一、系统裁剪概述:为什么要做系统裁剪?

说实话,我做了十几年系统优化,见过太多「大炮打蚊子」的案例。

一个嵌入式设备,跑着完整的 Linux 发行版。开机两分钟,内存吃掉大半。你说它功能全吗?全。但真正用到的,可能不到 20%。

这就是我们要做系统裁剪的原因。

1.1 性能瓶颈到底在哪?

先别急着动手。你得先搞清楚,系统慢在哪。

我个人习惯,拿到一个系统,先看三个地方:

  • CPU 空转率 —— 是不是大量时间花在调度无关进程上?
  • 内存占用分布 —— 谁在吃内存?内核?驱动?还是用户态服务?
  • 磁盘 I/O 瓶颈 —— 是不是频繁读写日志、临时文件?

我在项目中遇到过一台工业网关,启动要 45 秒。查了半天,发现光 udev 规则加载就占了 12 秒。裁剪掉不需要的设备规则,启动时间直接降到 18 秒。

核心观点: 性能瓶颈往往不是硬件不够强,而是软件太臃肿。裁剪的本质,是「去掉你不需要的,让需要的跑得更快」。

1.2 裁剪能带来什么收益?

说白了,就三个字:快、小、稳。

维度 裁剪前 裁剪后 典型提升
启动时间 45s 12s 73%
内存占用 128MB 48MB 62%
存储空间 512MB 128MB 75%
系统响应 有卡顿 流畅 明显改善

你想想看,一个 128MB Flash 的设备,原来装完系统只剩 20MB。裁剪后,还能剩 100MB 给应用。这差距,不是一点点。

1.3 裁剪的核心原则

嗯,这里要注意。裁剪不是乱砍。我见过有人把 libc 都裁了,结果程序跑不起来。这就过头了。

我总结了四条原则,你可以记一下:

  1. 最小化原则 —— 只保留系统运行必需的最小集合。多一个进程都不要。
  2. 模块化原则 —— 功能按模块拆分,按需加载。用不到的模块,编译时就去掉。
  3. 可追溯原则 —— 每次裁剪都要记录。我曾经裁掉一个「看起来没用」的驱动,结果现场设备连不上网。查了两天才找到原因。
  4. 测试优先原则 —— 裁剪完必须做功能测试和压力测试。别让裁剪引入新 bug。

避坑指南: 我曾经在裁剪内核时,把 SCSI 支持整个去掉了。结果系统启动到一半就 panic。后来才发现,虽然设备用的是 SATA,但内核内部依赖 SCSI 层做磁盘管理。所以,裁剪前一定要搞清楚依赖关系。

1.4 裁剪的层次结构

系统裁剪不是一锤子买卖。它分几个层面,每个层面都有不同的侧重点。

下面这张图,是我自己画的一个裁剪层次结构。你可以对照着看:

系统裁剪层次结构 应用层裁剪 移除不需要的应用程序、服务、库文件 中间件层裁剪 精简图形栈、网络协议栈、数据库、运行时环境 内核层裁剪 配置内核选项、移除无用驱动、精简文件系统支持 引导层裁剪 优化 Bootloader、精简 initramfs、加速启动流程 裁剪顺序:从应用层开始,逐层向下,每层裁剪后都要做回归测试

从这张图你能看出来,裁剪是有顺序的。我个人建议,先从应用层下手。因为应用层改动风险最小,收益也最直观。

比如,一个设备只需要做数据采集,那 Web 服务器、SSH 服务、打印服务,统统可以去掉。这一刀下去,内存占用能降 30% 以上。

1.5 什么时候不该裁剪?

说了这么多裁剪的好处,我也得泼点冷水。

有些场景,真的不适合做裁剪:

  • 通用型产品 —— 你不知道用户会怎么用。裁剪过度,反而限制用户。
  • 快速原型阶段 —— 先跑起来再说。优化是后面的事。
  • 维护成本敏感 —— 裁剪后的系统,维护起来更麻烦。每次升级都要重新裁剪。

我的建议: 如果你做的是专用嵌入式设备,比如路由器、工控机、IoT 终端,那裁剪是必修课。但如果你做的是通用服务器,那还是保持完整系统更稳妥。

1.6 裁剪前的准备工作

动手之前,先把这几件事做了:

  1. 建立基线 —— 记录当前系统的 CPU、内存、磁盘、启动时间等指标。
  2. 分析依赖 —— 用 ldd、readelf、systemd-analyze 等工具,搞清楚谁依赖谁。
  3. 制定目标 —— 明确你要达到什么效果。比如「启动时间 < 10s」「内存占用 < 64MB」。
  4. 准备回退方案 —— 裁剪失败了,能快速恢复。我一般会保留一份完整的系统镜像。

好了,这一章的内容就这些。记住一句话:裁剪不是目的,让系统跑得更快才是。