第3章:SDK源码结构解析

拿到一块新的开发板,第一件事是什么?我个人习惯是先把它自带的SDK目录结构摸清楚。说白了,你得知道什么东西放在哪里,不然编译都找不到头文件,那可就尴尬了。

RV1126的SDK,我刚开始接触时也觉得挺复杂。但拆开来看,其实就几个核心模块。今天我就带你走一遍,把每个目录的职责讲明白。

3.1 SDK顶层目录一览

先看看SDK解压后的顶层长什么样。你执行 ls -l 会看到类似这样的结构:

rv1126_sdk/
├── kernel/          # Linux内核源码
├── u-boot/          # U-Boot引导程序
├── buildroot/       # 根文件系统构建工具
├── app/             # 应用层代码
├── docs/            # 文档
├── tools/           # 工具链和脚本
├── output/          # 编译输出目录
└── Makefile         # 顶层编译入口

嗯,这里要注意:不同厂商的SDK可能会有细微差别,但核心模块基本一致。我在项目中遇到过一家厂商把 app 改名叫 customer,但内容大同小异。

3.2 kernel目录:驱动开发的主战场

作为驱动开发者,kernel 目录是你打交道最多的地方。它的结构遵循标准Linux内核布局:

kernel/
├── arch/            # 架构相关代码
│   └── arm/         # ARM架构
│       └── mach-rockchip/  # Rockchip平台代码
├── drivers/         # 设备驱动
│   ├── media/       # 多媒体驱动(摄像头、显示等)
│   ├── net/         # 网络驱动
│   ├── spi/         # SPI驱动
│   └── i2c/         # I2C驱动
├── include/         # 头文件
├── sound/           # 音频驱动
└── Makefile         # 内核编译规则

你想想看,我们写驱动时,大部分时间都在 drivers/ 下折腾。比如你要写一个摄像头驱动,就去 drivers/media/ 下面找。Rockchip平台相关的代码在 arch/arm/mach-rockchip/ 里,这里面定义了芯片的引脚复用、时钟管理等底层配置。

我的小技巧: 刚接手项目时,先看看 arch/arm/mach-rockchip/ 下的 board-*.c 文件。这里面有开发板的硬件初始化代码,能帮你快速了解外设是怎么挂载的。

3.3 u-boot目录:系统启动的第一棒

U-Boot负责初始化硬件并加载内核。它的目录结构相对简单:

u-boot/
├── board/           # 板级支持包
│   └── rockchip/    # Rockchip板级代码
├── common/          # 通用功能
├── drivers/         # 驱动(串口、网络、存储等)
├── include/         # 头文件
└── configs/         # 板级配置文件

我曾经在调试一个新板子时,发现U-Boot死活起不来。查了半天,原来是 configs/ 下的配置文件里DDR参数设错了。所以,如果你遇到启动问题,先检查这里。

注意: U-Boot的驱动和内核驱动是两套独立的代码。别想着在U-Boot里调用的驱动,内核里也能直接用。它们各自维护自己的驱动框架。

3.4 buildroot目录:构建你的文件系统

Buildroot是一个自动化构建工具,帮你生成根文件系统。它的结构如下:

buildroot/
├── board/           # 板级配置
├── configs/         # 默认配置
├── package/         # 软件包
│   ├── busybox/     # 基础命令
│   ├── alsa-utils/  # 音频工具
│   └── openssh/     # SSH服务
├── fs/              # 文件系统生成脚本
└── Makefile         # 构建规则

说白了,你想在板子上跑什么软件,就在 package/ 下找对应的包。比如你想加个网络调试工具,就找 package/iperf/。Buildroot会自动下载源码、交叉编译、打包进文件系统。

核心要点: Buildroot的配置在 configs/ 下,通常以 rockchip_rv1126_defconfig 命名。执行 make menuconfig 可以图形化选择你要的软件包。

3.5 app目录:用户态程序的家

app 目录存放用户态应用程序,比如多媒体测试程序、网络服务等。它的结构因项目而异,但通常包含:

app/
├── camera/          # 摄像头测试程序
├── display/         # 显示测试程序
├── network/         # 网络相关程序
└── common/          # 公共库

我建议你多看看这里的代码。很多时候,驱动写好了,怎么验证?就是靠这些app。比如你写完一个摄像头驱动,就可以用 app/camera/ 下的程序抓一帧图像看看。

3.6 编译流程概览

整个SDK的编译流程,我用一张图来展示:

RV1126 SDK编译流程 1. 配置环境 2. 编译U-Boot 3. 编译内核 4. 构建文件系统

编译流程其实就四步:

  1. 配置环境: 设置交叉编译工具链路径,执行 source envsetup.sh
  2. 编译U-Boot: 生成 uboot.img,负责引导系统
  3. 编译内核: 生成 boot.img,包含内核镜像和设备树
  4. 构建文件系统: 生成 rootfs.img,包含所有用户态程序

你可能会问:为什么是这个顺序?因为U-Boot要先跑起来,才能加载内核;内核跑起来后,才能挂载文件系统。一环扣一环,缺一不可。

实际编译命令:
# 一键编译所有
./build.sh all

# 或者分步编译
./build.sh uboot
./build.sh kernel
./build.sh rootfs

我记得第一次编译整个SDK时,等了将近半小时。后来发现,其实可以只编译你修改的部分。比如你只改了内核驱动,那就只执行 ./build.sh kernel,能省不少时间。

3.7 输出目录说明

编译完成后,所有生成的文件都在 output/ 目录下:

output/
├── images/          # 最终镜像文件
│   ├── uboot.img
│   ├── boot.img
│   └── rootfs.img
├── kernel/          # 内核编译中间文件
├── uboot/           # U-Boot编译中间文件
└── buildroot/       # 文件系统编译中间文件

你烧录板子时,只需要 images/ 下的三个镜像文件。其他中间文件,说白了就是编译过程的副产品,平时不用管。

避坑指南: 我曾经在 output/ 目录下找半天找不到镜像文件,后来发现是编译失败了。建议你每次编译完,先检查 output/images/ 下有没有生成文件,再开始烧录。

好了,SDK的目录结构和编译流程就讲到这里。你只要记住:kernel是驱动的主战场,u-boot是启动的第一棒,buildroot负责文件系统,app是验证工具。把这几个模块的关系理清楚,后面写驱动时就不会迷路了。


可可精品资料库