嵌入式设备通常资源有限,存储空间可能只有几十 MB,内存也不过 128 MB 甚至更少。在这样的硬件条件下,运行一个通用 Linux 发行版的内核显得过于臃肿。通过对 Linux 内核进行合理的编译与裁剪,我们可以将内核镜像从数 MB 缩减到几百 KB,同时保留设备所需的核心功能。本文将围绕内核编译流程、裁剪策略以及最小系统的构建展开,帮助你在嵌入式开发中打造一个精简而高效的内核。
一、准备工作:工具链与内核源码
在开始编译之前,需要确保以下条件就绪:
- 交叉编译工具链:根据目标板架构(如 ARM、AArch64、MIPS)选择对应的
gcc工具链。常见的有arm-linux-gnueabihf-、aarch64-linux-gnu-等。 - 内核源码:从 kernel.org 下载长期支持版本(如 6.6.x 或 6.12.x),或使用芯片厂商提供的 BSP 内核。
- 依赖工具:
make、bc、flex、bison、libssl-dev、libelf-dev等。
解压源码后,进入内核根目录,设置架构和交叉编译器:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
二、内核配置:从 defconfig 到精简配置
内核配置是裁剪的核心环节。通常先使用厂商提供的 defconfig 作为基线:
make <soc_defconfig>
然后通过 make menuconfig 进行交互式裁剪。对于嵌入式最小系统,重点关注以下几类选项:
1. 处理器与特性
- 只保留目标 SoC 对应的平台选项,去掉其他无关架构。
- 关闭不需要的 CPU 特性(如某些浮点扩展、虚拟化支持)。
2. 设备驱动
- 仅启用目标板上实际存在的驱动:串口、GPIO、I2C、SPI、MMC、网络等。
- 将非必需驱动编译为模块(
=m)而非内置(=y),甚至完全禁用。 - 去掉 USB 存储、声卡、摄像头等与产品无关的驱动。
3. 文件系统
- 嵌入式常用
squashfs(只读根文件系统)、ext4、jffs2、ubifs。 - 如果使用 initramfs,需要启用
CONFIG_BLK_DEV_INITRD和CONFIG_INITRAMFS_SOURCE。 - 关闭
NFS、CIFS等网络文件系统,除非确有需要。
4. 网络协议
- 只保留
TCP/IP基础协议栈,关闭IPV6、Netfilter、QoS、Bridge等高级功能。 - 如果设备无需网络,可直接关闭整个网络子系统。
5. 内核调试与日志
- 关闭
CONFIG_DEBUG_KERNEL、CONFIG_MAGIC_SYSRQ、CONFIG_KALLSYMS等调试选项。 - 将
CONFIG_PRINTK保留但降低日志级别,或使用CONFIG_LOG_BUF_SHIFT减小日志缓冲区。
6. 内核压缩方式
- 选择
CONFIG_KERNEL_GZIP、CONFIG_KERNEL_XZ或CONFIG_KERNEL_LZ4。XZ压缩率最高但解压慢,LZ4解压最快但体积稍大。根据启动时间和存储空间权衡。
三、编译与镜像生成
配置完成后,执行编译:
make -j$(nproc) zImage # 或 Image、uImage,取决于平台
编译产物位于 arch/arm/boot/ 下。对于 ARM 平台,通常使用 zImage 或 uImage(U-Boot 引导)。若使用设备树,还需编译 .dtb 文件:
make dtbs
最终得到的 zImage 大小通常在 1~3 MB,经过裁剪后可降至 500 KB 左右。设备树文件一般只有几十 KB。
四、构建最小根文件系统
内核启动后需要挂载根文件系统。对于最小系统,推荐使用 BusyBox + initramfs 方案:
- 编译 BusyBox,生成静态链接的
busybox二进制。 - 创建目录结构:
/bin、/sbin、/etc、/proc、/sys、/dev。 - 编写
init脚本,挂载proc、sysfs,并启动必要服务。 - 使用
gen_init_cpio或cpio打包为 initramfs,并指定内核配置CONFIG_INITRAMFS_SOURCE指向该目录。
这样内核启动后直接解压 initramfs 到内存,无需外部存储即可运行,非常适合资源紧张的设备。
五、裁剪效果验证与调优
裁剪后需要验证系统功能是否完整:
- 通过串口查看启动日志,确认无关键错误。
- 检查
dmesg中是否有驱动加载失败。 - 使用
size命令查看内核各段大小,定位可进一步裁剪的模块。 - 若启动失败,逐步回退配置项,定位被误删的依赖。
常见调优方向包括:关闭 CONFIG_MODULES(若无需动态加载)、使用 CONFIG_CC_OPTIMIZE_FOR_SIZE 优化体积、移除 CONFIG_IKCONFIG 等元数据。
六、总结
Linux 内核编译与裁剪是一个“按需取舍”的过程。没有通用的最小配置,只有最适合当前硬件的配置。掌握 menuconfig 的层级结构、理解各子系统之间的依赖关系,是高效裁剪的关键。通过合理的裁剪,我们不仅节省了存储和内存,还能缩短启动时间、减少攻击面,为嵌入式设备打造一个真正精简、可靠的最小系统。
未经允许不得转载:任鹏个人博客 » Linux 内核编译与裁剪:为嵌入式设备打造最小系统


朋友圈点赞图在线生成源码