3. Rockchip启动流程与驱动加载机制

这一章,我们聊聊怎么把 Rockchip 的内核源码变成能在开发板上跑起来的镜像。说白了,就是「源码 → 配置 → 编译 → 烧录」这条流水线。我刚开始接触 RK 平台时,光烧录就折腾了一整天,后来才发现是分区表没对齐。嗯,咱们一步步来。

3.1 获取内核源码:Rockchip BSP kernel

Rockchip 官方维护的 BSP 内核,一般托管在 GitHub 或 Gitee 上。你拿到开发板时,厂商通常会提供一个 SDK 压缩包,里面就包含了完整的内核源码。

我个人习惯直接从 Rockchip 的官方仓库拉取,这样能保证是最新稳定分支:

git clone -b linux-5.10.y https://github.com/rockchip-linux/kernel.git
cd kernel

这里有个坑:不同芯片型号(RK3568、RK3588、RK3399)对应的内核分支可能不同。我建议你拿到板子后,先确认芯片型号,再选分支。

小提示: 如果你用的是 Firefly、友善之臂这类第三方板子,它们会在自己的 SDK 里打上补丁。直接用厂商提供的源码最省心。

3.2 配置内核:defconfig 与 menuconfig

内核配置是编译前的关键一步。Rockchip 平台通常提供现成的 defconfig 文件,你直接加载就行。

3.2.1 加载默认配置

make ARCH=arm64 rockchip_linux_defconfig

这条命令会读取 arch/arm64/configs/rockchip_linux_defconfig,生成 .config 文件。说白了,这就是 Rockchip 官方给你配好的「标准答案」。

3.2.2 微调配置

默认配置不一定完全满足你的需求。比如你要加一个 SPI 驱动,或者去掉一些不用的模块,就需要手动调整:

make ARCH=arm64 menuconfig

menuconfig 是图形化的配置界面,用方向键和空格操作。我一般会在这里做三件事:

  • 开启调试选项:Kernel hacking → KGDB、DEBUG_FS
  • 添加外设驱动:Device Drivers → SPI、I2C、PWM
  • 关闭无用模块:比如不用的网卡驱动、文件系统
注意: 不要随意修改 defconfig 里与芯片底层相关的选项(如 ARM PMU、GIC、定时器)。我曾经改过一次,结果内核起不来,查了两天才发现是中断控制器配置被误关了。

3.3 编译内核与 DTB

配置搞定后,就是编译。Rockchip 平台一般用 Device Tree 来描述硬件,所以我们要同时编译内核镜像和 DTB 文件。

3.3.1 编译命令

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) dtbs

这里解释一下:

  • Image:生成的内核镜像,放在 arch/arm64/boot/Image
  • dtbs:编译所有设备树,生成 .dtb 文件,放在 arch/arm64/boot/dts/rockchip/

你想想看,如果你的板子是 RK3568,那对应的 DTB 文件就是 rk3568-evb.dtb 或厂商自定义的 rk3568-firefly.dtb。

3.3.2 编译产物清单

产物 路径 说明
内核镜像 arch/arm64/boot/Image 压缩后的内核,烧录到 boot 分区
设备树 arch/arm64/boot/dts/rockchip/*.dtb 硬件描述文件,烧录到 dtb 分区
内核模块 drivers/ 下各目录 需要单独安装到根文件系统
避坑指南: 我曾经编译完直接烧录,结果板子起不来。后来发现是 DTB 和内核版本不匹配——我改了内核配置,但忘了重新编译 DTB。记住:每次改配置后,Image 和 dtbs 都要重新编译。

3.4 烧录到开发板

Rockchip 平台有两种主流烧录工具:RKDevTool(Windows 下用)和 upgrade_tool(Linux 下用)。我平时在 Linux 下开发,所以更常用 upgrade_tool。

3.4.1 烧录前的准备

先把开发板切换到 Loader 模式(也叫 Maskrom 模式):

  • 按住板子上的 RECOVERY 键(或 MASKROM 键)
  • 上电或按 RESET 键
  • 用 USB 线连接电脑

在 Linux 下,用 lsusb 检查是否识别到 Rockchip 设备:

lsusb | grep Rockchip
# 输出类似:Bus 001 Device 003: ID 2207:350a Rockchip

3.4.2 使用 upgrade_tool 烧录

upgrade_tool 是 Rockchip 官方提供的命令行工具。烧录命令如下:

sudo upgrade_tool ul bootloader.bin
sudo upgrade_tool di -b boot.img
sudo upgrade_tool di -dtb rk3568-evb.dtb
sudo upgrade_tool rd

解释一下每条命令:

  • ul:烧录 bootloader(通常由 Rockchip 提供,不需要自己编译)
  • di -b:烧录 boot 分区(包含内核镜像)
  • di -dtb:烧录设备树
  • rd:复位开发板
小技巧: 如果你经常烧录,可以写一个脚本。我一般把烧录命令放在 flash.sh 里,每次改完内核直接 ./flash.sh,省得敲一堆命令。

3.4.3 分区表对齐

这里有个容易忽略的点:分区表。Rockchip 的烧录工具依赖 parameter.txt 文件来定义分区大小和偏移。如果你自己编译的内核镜像太大,超过了 boot 分区的大小,烧录会失败。

我遇到过这种情况:加了几个驱动后,内核从 8MB 涨到了 12MB,结果 boot 分区只有 10MB。解决办法是修改 parameter.txt,把 boot 分区调大。

3.5 本章知识体系

下面这张图总结了从源码到烧录的完整流程,你可以对照着梳理自己的操作步骤:

内核编译与烧录流程 内核编译与烧录流程 获取 BSP 内核源码 配置内核 (defconfig + menuconfig) 编译 Image + dtbs Image (内核镜像) *.dtb (设备树) 烧录到开发板 验证启动 (串口日志) 提示:每次修改配置后,必须重新编译 Image 和 dtbs,否则可能启动失败

3.6 验证启动

烧录完成后,用串口工具(如 minicom、putty)连接开发板,上电看启动日志。如果看到内核版本号和你编译的一致,说明烧录成功。

U-Boot 2021.10 (Jan 10 2024 - 15:30:00)
...
Starting kernel ...
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x412fd050]
[    0.000000] Linux version 5.10.160 (user@host) (aarch64-linux-gnu-gcc 10.3.0)
...

看到 Linux version 5.10.160 了吗?那就是你编译的内核。如果卡在某个地方,别慌,先检查 DTB 是否匹配,再确认分区表是否正确。

常见问题: 如果串口没有任何输出,先检查 USB 线是否插好,再确认开发板是否进入了 Loader 模式。我遇到过好几次,都是因为线接触不良。