第二章:内核配置与编译——开启Device Tree Overlay支持,编译dtc工具
好,咱们接着往下走。上一章我们把Overlay的基本概念理清了,这一章就得动真格的了——把内核环境搭起来,把Overlay支持打开,再把dtc工具编译好。
说实话,这一步看着简单,但坑不少。我当年第一次搞的时候,内核配置漏了一项,结果折腾了两天才发现是某个宏没开。嗯,咱们今天就把这些细节都捋清楚。
2.1 内核配置:打开Overlay的开关
先说说内核配置。你要想让内核支持Device Tree Overlay,得把几个关键选项打开。它们藏在Device Drivers -> Device Tree and Open Firmware support这个路径下。
我个人习惯用make menuconfig,图形化界面不容易漏项。你执行一下:
$ cd <你的内核源码目录>
$ make menuconfig
然后找到下面这几个选项,确保它们被选中:
| 配置项 | 路径 | 说明 |
|---|---|---|
| CONFIG_OF | Device Tree and Open Firmware support | 设备树基础支持,必须开 |
| CONFIG_OF_OVERLAY | Device Tree and Open Firmware support -> Device Tree overlays | Overlay动态加载的核心开关 |
| CONFIG_OF_CONFIGFS | Device Tree and Open Firmware support -> Device Tree overlays -> Device Tree Overlay configfs interface | 通过configfs接口加载Overlay |
| CONFIG_OF_DYNAMIC | Device Tree and Open Firmware support -> Device Tree overlays -> Device Tree dynamic support | 动态修改设备树的能力 |
重点提醒:CONFIG_OF_OVERLAY和CONFIG_OF_CONFIGFS这两个最容易漏掉。我见过不少新手只开了CONFIG_OF,然后发现/sys/kernel/config/device-tree/overlays目录根本不存在,一脸懵。
配置完以后,记得保存退出。然后检查一下.config文件,确认这几个宏确实被置为y了:
$ grep -E "CONFIG_OF_OVERLAY|CONFIG_OF_CONFIGFS|CONFIG_OF_DYNAMIC" .config
CONFIG_OF_OVERLAY=y
CONFIG_OF_CONFIGFS=y
CONFIG_OF_DYNAMIC=y
看到这三个=y,心里就踏实了。
2.2 编译内核:让配置生效
配置改完了,接下来就是编译内核。这一步没什么花活,标准流程:
$ make -j$(nproc) # 编译内核
$ make modules # 编译模块(如果需要)
$ make modules_install # 安装模块
$ make install # 安装内核
这里有个小技巧——-j$(nproc)能充分利用你CPU的所有核心。我自己的机器是8核的,编译时间能缩短一大半。
编译完成后,重启系统,用新内核启动。进系统后先验证一下:
$ uname -r
5.10.100-custom # 确认是你刚编译的内核版本
然后检查Overlay相关的文件系统接口:
$ ls /sys/kernel/config/device-tree/
overlays
如果能看到overlays目录,说明内核配置生效了。如果看不到……嗯,回头检查一下CONFIG_OF_CONFIGFS有没有漏掉。
注意:有些嵌入式平台(比如树莓派)的内核配置可能默认就开了Overlay支持。但即便如此,我建议你还是手动确认一遍。我曾经遇到过某个BSP(板级支持包)声称支持Overlay,结果实际跑起来发现CONFIG_OF_DYNAMIC没开,动态加载直接报错。
2.3 编译dtc工具:你的Overlay编译器
内核搞定了,接下来是dtc。dtc是Device Tree Compiler的缩写,它负责把.dts源文件编译成.dtb二进制文件。Overlay的.dtbo文件也是它生成的。
dtc的源码就在内核源码树里,路径是scripts/dtc/。你不需要单独下载,直接编译就行:
$ cd <你的内核源码目录>/scripts/dtc
$ make
$ sudo make install # 安装到系统路径
安装完成后,验证一下:
$ dtc --version
Version 1.6.1
看到版本号就说明装好了。
这里有个细节——dtc默认只编译.dtb,要生成Overlay的.dtbo文件,你得用-@选项。这个选项会在.dtbo里加入符号信息,方便内核做动态解析。具体用法我们下一章会详细讲。
个人建议:如果你用的是Ubuntu或Debian,也可以直接apt install device-tree-compiler。但我不推荐这么做——系统自带的dtc版本往往比较老,可能不支持Overlay的一些新特性。自己编译内核源码里的dtc,版本跟内核完全匹配,最稳妥。
2.4 验证环境:跑一个最小测试
环境搭好了,咱们跑个最小测试,确保一切正常。写一个最简单的Overlay源文件:
// test-overlay.dts
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target-path = "/";
__overlay__ {
test-node {
compatible = "test,overlay";
status = "okay";
};
};
};
};
然后编译它:
$ dtc -@ -I dts -O dtb -o test-overlay.dtbo test-overlay.dts
如果没报错,会生成test-overlay.dtbo文件。你可以用dtc -I dtb -O dts test-overlay.dtbo反编译看看,确认内容正确。
这个测试虽然简单,但能验证两件事:
- dtc工具能正常编译Overlay格式
-@选项能正确添加符号信息
如果这一步卡住了,别急着往下走。先排查一下dtc版本,或者检查.dts文件语法。我见过有人把/plugin/;写成了/plugin;,少了个斜杠,编译直接报错。
2.5 本章小结
这一章我们做了三件事:
- 打开内核的Overlay相关配置项
- 编译并安装了支持Overlay的内核
- 编译了dtc工具,并验证了Overlay编译功能
说白了,就是搭好舞台。下一章我们就要真正上台表演了——写一个完整的Overlay,加载到内核里,看看效果。
嗯,今天就到这儿。环境搭好了,后面的事就顺了。