3. Linux内核编译与烧录:内核配置、设备树编译、分区表理解、烧录工具使用(RKDevTool)
这一章,我们聊聊嵌入式Linux开发中最基础、也最绕不开的一环——内核编译与烧录。很多刚入行的朋友觉得这步就是敲几个命令,等进度条跑完就完事了。其实不然。我在Rockchip平台上栽过不少跟头,后来才明白,内核配置、设备树、分区表、烧录工具这四块,每一块都有它的脾气。
说白了,你写的驱动再漂亮,如果内核没编对、设备树没配好、分区表搞错了、烧录工具不会用,板子就是跑不起来。嗯,咱们一个一个说。
3.1 内核配置:别用默认配置直接开干
拿到一个Rockchip的开发板,第一件事是什么?很多人会直接 make rockchip_linux_defconfig,然后就开始编译。我个人习惯是先看看这个defconfig到底开了什么。
make menuconfig 进去扫一遍,重点关注三个地方:- Device Drivers → 你的外设驱动有没有被选中
- File systems → 根文件系统类型是否匹配
- General setup → Local version,加个自定义后缀方便区分
我在项目中遇到过一个问题:板子的以太网死活不通,查了两天硬件,最后发现是内核配置里把 CONFIG_REALTEK_PHY 给漏了。你说冤不冤?所以我的建议是:每次拿到新板子,先把 make savedefconfig 生成的 defconfig 和官方对比一下,差异一目了然。
另外,Rockchip 的 SDK 里通常有多个 defconfig,比如针对不同 DDR 容量、不同显示接口的变种。选错了,轻则某些功能用不了,重则起不来。我建议你直接看 arch/arm64/configs/ 下的文件名,一般命名规则是 芯片型号_板卡型号_defconfig。
3.2 设备树编译:DTS 改完别忘编译
设备树(Device Tree)是 Rockchip 平台硬件适配的核心。你改了一个 GPIO 的复用、加了一个 I2C 设备、调整了显示时序,都得动 DTS 文件。
编译设备树的命令很简单:
make dtbs
或者针对单板:
make rk3588-evb1-lp4.dtb
但这里有个坑——我见过不止一个同事,改了 DTS 文件后只编译了内核,没单独编译设备树,结果烧进去发现硬件没生效。为什么?因为内核编译流程里,make 默认会重新生成 dtb,但如果你用了 make modules 或者只编了部分代码,dtb 可能没更新。
make dtbs,确保万无一失。
还有一点:Rockchip 的设备树是分层的。一个完整的 DTS 文件会 include 芯片级 .dtsi、SoC 级 .dtsi,最后才是板级 .dts。你改的时候要搞清楚改的是哪一层。我习惯在板级 .dts 里用 &pinctrl 这种引用方式覆写,而不是直接改 .dtsi,这样升级 SDK 时不容易冲突。
3.3 分区表理解:烧错分区等于白干
分区表,说白了就是告诉烧录工具:你的固件该往 Flash 的哪个位置写。Rockchip 平台用的是 parameter.txt 文件来定义分区。
一个典型的 parameter.txt 长这样:
FIRMWARE_VER: 1.0
MACHINE_MODEL: RK3588
MACHINE_ID: 007
MANUFACTURER: Rockchip
CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(misc),0x00020000@0x00008000(boot),0x00040000@0x00028000(recovery),0x00080000@0x00068000(rootfs),-@0x000e8000(userdata)
每个分区的格式是 大小@偏移(名称)。单位是 sector,一个 sector 通常是 512 字节。你想想看,如果大小算错了,或者偏移重叠了,烧进去的固件就会互相覆盖。
| 分区名 | 大小(sector) | 偏移(sector) | 用途 |
|---|---|---|---|
| uboot | 0x2000 (4MB) | 0x4000 | 引导加载程序 |
| misc | 0x2000 (4MB) | 0x6000 | 系统模式信息 |
| boot | 0x20000 (64MB) | 0x8000 | 内核 + dtb |
| rootfs | 0x80000 (256MB) | 0x68000 | 根文件系统 |
| userdata | 剩余空间 | 0xE8000 | 用户数据 |
我在项目中遇到过最典型的问题:rootfs 分区大小设小了,导致文件系统解压到一半就报错。后来我学乖了,每次改分区表都会先算一下根文件系统镜像的实际大小,再留出 20% 的余量。
3.4 烧录工具使用:RKDevTool 的正确打开方式
RKDevTool 是 Rockchip 官方的烧录工具,支持 USB 和 SD 卡两种模式。我个人更常用 USB 模式,因为速度快、操作简单。
基本流程是这样的:
- 板子进入 MaskROM 模式(按住 Recovery 键上电,或者短接 EMMC 的 CLK 和 GND)
- 打开 RKDevTool,点击「切换」按钮,确保设备已识别
- 在「下载镜像」页面,按分区表配置好每个镜像的路径和地址
- 点击「执行」开始烧录
这里有个细节:RKDevTool 的地址是十六进制的,而且单位是 sector。你从 parameter.txt 里看到的偏移,直接填进去就行。但要注意,有些版本的 RKDevTool 地址单位是字节,需要乘以 512。我建议你烧录前先看一眼工具界面上的提示,确认单位。
另外,如果你用的是 SD 卡启动,需要用 SD_Firmware_Tool 制作启动卡。这个工具会把整个固件包(包括分区表)写到 SD 卡上。我个人觉得 SD 卡模式适合调试阶段,因为换固件方便,不用每次都插拔 USB。
3.5 本章知识体系
下面这张图把内核编译与烧录的完整流程串起来了,你可以对照着看:
从图上你能看到,内核配置、设备树、分区表是三个并行的输入,最终汇聚到编译环节,生成镜像后再烧录到板子上。任何一个环节出问题,都会导致最终结果不对。
嗯,这一章的内容就这些。内核编译与烧录看似基础,但细节很多。你只要把配置、设备树、分区表、烧录工具这四个点吃透,后面写驱动、调硬件的时候就会顺畅很多。