当前位置:首页>Linux>[TinyLinux-002] 突破极限:3.4MB 的内核是怎样炼成的?

[TinyLinux-002] 突破极限:3.4MB 的内核是怎样炼成的?

  • 2026-09-30 00:35:52
[TinyLinux-002] 突破极限:3.4MB 的内核是怎样炼成的?

[TinyLinux-002] 突破极限:3.4MB 的内核是怎样炼成的?

系列简介:TinyLinux 是由 LabHub 发起的“大道至简” Linux 学习项目。我们通过对内核进行“剔骨”级的物理精简,旨在构建一个 100% 透明、可重现的极简实验室。

公众号:LabHub | 项目仓库:https://gitee.com/lynyujiang/tiny-linux.git


🛠 技术看板

  • 实验目标:确立“QEMU 专用”原则,通过物理源码剔除与激进配置,将内核体积从 11MB 压榨至 3.4MB。
  • 核心知识点:内核源码树结构 / Kconfig 依赖管理 / Stubbing 技术。
  • 涉及脚本:scripts/prune_kernel_source.sh
  • 难度等级:🌟🌟 (进阶)

1. 知识点详注 (Technical Glossary)

  • Kconfig:Linux 内核的配置系统脚本。它定义了内核的功能开关、依赖关系以及在 make menuconfig 中看到的菜单结构。
  • **Stubbing (打桩)**:一种软件工程技术。当一个模块被删除,但其他模块仍试图调用它时,我们提供一个同名的“空函数”或“空文件”来欺骗编译器,确保链接不报错。
  • Vmlinux:编译出来的原始、未压缩的静态内核二进制文件(通常很大,数百 MB)。
  • **XZ (LZMA2)**:一种现代高压缩率算法。相比传统的 GZIP,XZ 能够识别更长的数据重复序列,非常适合压缩具有大量重复指令的内核二进制文件。

2. 理论背景 (Deep Theory)

2.1 为什么 Linux 内核如此庞大?

打开 Linux 6.12 的源码目录,你会发现它占据了近 2GB 的空间。其臃肿源于两个“无奈”:

  1. **全能性 (Universal)**:它必须同时支持 x86, ARM, RISC-V, MIPS 等几十种 CPU 架构。
  2. **包容性 (Inclusive)**:它内置了数万种驱动,从 90 年代的声卡到最新的 AI 加速卡。

2.2 “外科手术”的逻辑:物理级精简

仅仅在 make menuconfig 中关闭开关(.config)是不够的。即便你关掉了某个驱动,Makefile 依然会扫描相关目录,Kconfig 依然会解析依赖。物理精简的精髓在于:直接删除不参与编译的代码目录。但这会带来灾难性的依赖报错。我们需要利用 Stubbing 技术:

  • 删除 drivers/gpu,但必须保留一个空的 Kconfig,否则内核根目录的 drivers/Kconfig 会因为找不到引用而罢工。

3. 源码与脚本深度走读 (Source Code Dive)

3.1 核心脚本:prune_kernel_source.sh

这是 TinyLinux 的“手术刀”。它的核心逻辑是按需剔除。

# 示例:物理剔除除了 x86 以外的所有架构代码
# 我们只保留 x86 核心逻辑,删除 arm, powerpc, s390 等
for arch in $(ls arch/); do
if [ "$arch" != "x86" ] && [ "$arch" != "Kconfig" ]; then
        rm -rf "arch/$arch"
# 关键:创建一个空 Makefile 和最小化 Kconfig 防止构建系统崩溃
echo"obj-y :=" > "arch/$arch/Makefile"
echo"config ARCH_$(echo $arch | tr 'a-z' 'A-Z')" > "arch/$arch/Kconfig"
fi
done

3.2 关键配置:CONFIG_EXPERT=y

这个开关是所有精简操作的“上帝模式”。

  • 作用:一旦开启,内核会暴露出许多被隐藏的底层组件开关。例如,你可以选择关闭 BUG() 宏支持、关掉内核符号表、甚至是选择不同的 RCU 实现。这是从“通用系统”迈向“嵌入式实验室”的必经之路。

4. 配置详解 (Config & Engineering)

在本阶段,我们执行了以下“切除手术”:

  • CONFIG_USB=n: 移除整个 USB 协议栈。虽然这让 QEMU 无法识别模拟优盘,但在串口开发模式下,这能节省约 400KB。
  • CONFIG_DRM=n: 彻底拔掉显卡驱动。我们不再需要显示器,一切交互通过 ttyS0 进行。
  • 内核压缩切换:
    # 将 bzImage 压缩算法改为 XZ
    CONFIG_KERNEL_XZ=y
    # 放弃 GZIP 
    # CONFIG_KERNEL_GZIP is not set

5. 工程实验步骤 (Lab Steps)

  1. 执行源码修剪: 运行项目自带的修剪脚本(注意:此操作不可逆,请确保有备份)。
    ./scripts/prune_kernel_source.sh
  2. 应用 Tiny 配置:
    cd kernel && make tinylinux_defconfig
  3. 编译并观察体积:
    make -j$(nproc) bzImage

5.1 观察点 (Observation Points)

重点关注编译输出的最后一行。bzImage 的大小应该从之前的 11MB 骤降至 3.4MB 左右。同时,尝试使用 du -sh kernel 查看源码树大小,你会发现它从 1.7GB 缩减到了 600MB 以内。

5.2 避坑指南

  • 现象: make 报错 No rule to make target 'samples/Makefile'。
  • 原因: 物理删除了 samples/ 目录,但顶层 Makefile 仍试图进入该目录。
  • 对策: 在 samples/ 目录下创建一个内容为空的 Makefile 文件,欺骗构建系统。

6. 验证与重现

  • 对应提交: 9b0ecf51e
  • 检出命令: git checkout 9b0ecf51e
  • 重现步骤:
    1. source env.sh
    2. scripts/make_all.sh
  • 预期输出:Success! Kernel: .../output/target/bzImagels -lh ...bzImage -> 3.4MB

7. 总结与延伸

通过本章,我们不仅实现了内核体积的飞跃,更掌握了 Linux 内核构建系统的底层逻辑。思考题: 既然我们可以物理删除源码,那我们能否把内核中所有的 printk 字符串也物理删除来进一步减小体积?这会对系统调试带来什么后果?


🌟 互动与支持

如果你觉得这个项目对理解 Linux 底层有帮助,请不要吝啬你的支持:

  1. 点赞 & 在看:点击右下角,让更多极客看到这个“活的代码教科书”。
  2. 关注 LabHub:第一时间获取 TinyLinux 的最新“手术”报告。
  3. Star 项目:点击 Gitee 仓库地址 给我们一个五星好评!

本文由 LabHub 团队原创,转载请注明出处。

最新文章

随机文章