嵌入式Linux内核裁剪:从5.4到最小系统,砍了哪些模块?

FPGA_工老王 发表于 2026-10-15 15:13 · 12 次浏览 · 1 条回复
F
最近在做一个电力终端项目,要求固件体积尽量小,启动尽量快。从主线5.4内核开始裁剪,最后把zImage从12MB砍到了3MB以内,启动时间从8秒压到2秒。分享一下裁剪思路。

第一步:先搞清楚你的硬件

裁剪的前提是你知道板子上有什么芯片。我们的板子是:
- CPU:i.MX6ULL(Cortex-A7,单核,512MB DDR3)
- Flash:256MB NAND
- 外设:ETH、UART、SPI Flash、I2C RTC、USB Host

不需要的硬件驱动全部关掉,这是最大的一块。

第二步:关掉不相关的体系结构和特性

Processor type and features:
- 只选你的CPU型号,其他全部关掉
- SMP、NUMA、大内核锁这些不需要的都关

Power management:
- 只留必要的CPU idle,其他省电策略如果不需要就关

第三步:文件系统和驱动

File systems:
- 只留ext4和squashfs(我们用squashfs做根文件系统,只读压缩)
- NFS、FAT、NTFS、ISO9660全部关掉

Device Drivers:
- 网络设备:只留FEC以太网驱动
- USB:只留EHCI和USB Host, gadget、OTG都关
- I2C/SPI:只留你实际用的控制器
- 字符设备:tty、串口、rtc、watchdog,其他全关
- 块设备:NAND/MLC驱动留着,其他SATA、SD全部关

第四步:内核调试和开发选项

Kernel hacking里面的东西,发布版基本全关:
- printk如果不需要可以调低级别(或者直接关)
- dynamic debug、ftrace、kprobes全部关
- KGDB、kdump这些调试功能都关

裁剪前后对比

| 项目 | 裁剪前 | 裁剪后 |
|---|---|---|
| zImage大小 | 12.3 MB | 2.8 MB |
| 内核配置项 | ~15000 | ~3500 |
| 启动到shell | ~8s | ~2.1s |
| 运行内存占用 | ~80MB | ~35MB |

一个容易忽略的点:模块 vs 内建

很多人图方便把驱动都编成模块(.ko),但如果你的根文件系统在NAND上,加载模块的时间开销其实不小。对于必须的驱动,直接编进内核(y)比模块(m)启动更快。

我们最终把根文件系统相关的驱动(NAND、UBI、ext4)全部编进内核,其他外设驱动编成模块,按需加载。

大家做嵌入式Linux裁剪的时候,最小做到过多小?有没有什么独门技巧?
广告位 A8广告位招商帖子页首楼下方通栏 · 728×90 · 查看报价 · 联系 ads@oeforum.com
论 论坛助手
裁剪很实用!再补几个常见手段:用 initcall_debug 和 bootgraph 找启动耗时大户,关掉 printk 时间戳和串口打印(quiet),使用 XZ/LZ4 压缩权衡解压速度,以及把驱动改成模块按需加载。你们 2 秒的启动时间里,内核和用户空间各占多少,用户空间是用 systemd 还是 busybox init?
登录 后参与回复,还没有账号?立即注册
行业企业展示索尔思光电 Source Photonics SFP 光模块产品图光模块与光芯片厂商访问官网 →行业企业展示,基于公开资料,如需撤下请联系 ads@oeforum.com