第4章:Linux内核配置与裁剪
内核配置与裁剪,说白了就是给A133的Linux内核做「瘦身」。
我刚开始做BSP时,总觉得内核越大越好,驱动越多越安全。结果呢?编译一次半小时,启动要十几秒,还动不动就OOM。后来被老大骂了一顿,才老老实实去研究Kconfig机制。
这一章,我就带你走一遍完整的裁剪流程。从Kconfig原理到menuconfig实战,再到驱动添加,一步不落。
4.1 Kconfig机制:内核配置的「骨架」
Kconfig是什么?它是内核的配置描述语言。每个驱动、每个功能模块,都有一个Kconfig文件来描述它。
举个例子,你想知道某个驱动能不能被编译进内核,就看它的Kconfig怎么写。
# drivers/i2c/busses/Kconfig 中的一段
config I2C_SUNXI
tristate "Allwinner I2C controller"
depends on ARCH_SUNXI
help
Say Y here to include support for Allwinner I2C controller.
This driver can also be built as a module.
这里有几个关键点:
- tristate:三态选择——Y(编译进内核)、M(编译为模块)、N(不编译)
- depends on:依赖关系,只有ARCH_SUNXI被选中,这个选项才会出现
- help:帮助信息,告诉你这个驱动是干嘛的
4.2 menuconfig实战:动手裁剪A133内核
好,理论说完了,咱们直接上手。
进入内核源码目录,执行:
cd kernel/
make ARCH=arm64 menuconfig
你会看到一个蓝底白字的界面。别慌,我带你一步步来。
4.2.1 裁剪CPU子系统
A133用的是Cortex-A53,但内核默认支持很多CPU架构。我们只保留ARM64相关的。
General setup --->
[*] Support for 64-bit ARM systems
[ ] Support for 32-bit ARM systems # 关掉,A133是64位
嗯,这里要注意:如果你关掉了32位支持,有些老驱动可能编译不过。我遇到过这种情况,后来发现是某个传感器驱动用了32位汇编。解决办法是把它也裁剪掉。
4.2.2 裁剪文件系统支持
A133主要用ext4和FAT32。其他文件系统,比如XFS、Btrfs、NTFS,统统关掉。
File systems --->
<*> The Extended 4 (ext4) filesystem
< > The Extended 3 (ext3) filesystem # 不需要
< > Btrfs filesystem # 不需要
< > XFS filesystem # 不需要
DOS/FAT/NT Filesystems --->
<*> VFAT (Windows-95) fs support
< > NTFS file system support # 不需要
4.2.3 裁剪网络协议栈
A133是嵌入式设备,不需要完整的TCP/IP协议栈。IPv6、IPsec、多播路由,这些都可以关掉。
Networking support --->
Networking options --->
[ ] IPv6 support # 关掉
[ ] IP: IPsec transport mode # 关掉
[ ] IP: multicast routing # 关掉
我做过一个项目,客户要求设备只做数据采集,不需要IPv6。关掉后,内核小了800KB,内存占用也降了。
4.3 添加必要的驱动支持
裁剪不是一味地删。有些驱动必须加,否则板子跑不起来。
4.3.1 必须保留的驱动
| 驱动类别 | 具体选项 | 说明 |
|---|---|---|
| 串口驱动 | CONFIG_SERIAL_SUNXI | 调试输出全靠它 |
| MMC/SD卡驱动 | CONFIG_MMC_SUNXI | 启动系统用 |
| USB驱动 | CONFIG_USB_SUNXI | 外接设备用 |
| 显示驱动 | CONFIG_DRM_SUNXI | 屏幕显示用 |
4.3.2 按需添加的驱动
比如你的产品需要Wi-Fi模块,那就加上:
Device Drivers --->
Network device support --->
Wireless LAN --->
[*] Realtek 8723ds support
我曾经踩过一个坑:加了Wi-Fi驱动,但忘了加固件文件。结果系统启动后,Wi-Fi设备能识别,但连不上网。折腾了两天才发现是固件没放对位置。
4.4 裁剪后的验证与优化
裁剪完,别急着烧录。先做两件事:
- 编译验证:make -j8,确保没有编译错误
- 启动测试:烧录到板子上,看启动日志,确认没有驱动加载失败
我习惯用这个命令查看内核大小:
ls -lh arch/arm64/boot/Image
# 裁剪前:约 12MB
# 裁剪后:约 6.5MB
启动速度呢?用dmesg看时间戳:
dmesg | grep "Kernel"
# 裁剪前:3.2秒
# 裁剪后:1.8秒
4.5 避坑指南
最后,分享几个我踩过的坑:
- 别删掉initramfs:有一次我为了省空间,把initramfs支持关了。结果系统启动到一半就卡住了。因为根文件系统挂载需要它。
- 注意驱动依赖链:你关掉一个驱动,可能连带关掉它依赖的驱动。比如关掉I2C,所有I2C设备(触摸屏、传感器)都会失效。
- 保留调试选项:产品发布前,建议保留CONFIG_DEBUG_KERNEL。出问题时,它能帮你快速定位。
嗯,这一章的内容就到这里。内核裁剪是个细活,急不来。你按我说的步骤走,多试几次,就能找到最适合你产品的配置。
下一章,我们会聊设备树配置。到时候见。