Linux内核配置编译与裁剪开发实战工程 - 第1节
1. 内核概述
Linux 内核自 1991 年由 Linus Torvalds 发布以来,经历了从个人项目到支撑全球 IT 基础设施的演进。理解版本号规则与演进脉络,是选择内核源码、评估功能特性与进行裁剪开发的基础。
1.1.1 版本号命名规则
Linux 内核采用三段式版本号:A.B.C。不同阶段的含义如下表所示:
| 字段 | 含义 | 示例 |
|---|---|---|
| A(主版本) | 重大架构变更或不兼容更新 | 2、3、4、5、6 |
| B(次版本) | 早期(2.6 前)偶数为稳定版,奇数为开发版;2.6 后此规则废止 | 2.6、4.19、5.10、6.1 |
| C(补丁版本) | 安全修复、Bug 修复、小特性向后移植 | .1、.128、.300 |
裁剪提示:嵌入式开发通常选择 LTS(长期支持) 版本,如 5.10.y、6.1.y。LTS 版本维护周期长达 6~10 年,社区持续提供安全补丁,适合产品化。
1.1.2 关键演进里程碑
- 1991 — v0.01:仅支持 i386,单进程,无网络。
- 1994 — v1.0:支持多架构、虚拟内存、模块加载。
- 1996 — v2.0:SMP 对称多处理、模块机制成熟。
- 2003 — v2.6:抢占式内核、udev、大量驱动合并,嵌入式支持起步。
- 2011 — v3.0:版本号跳转,引入 cgroups、命名空间,容器技术萌芽。
- 2015 — v4.0:live patching(热补丁)、内核锁定机制。
- 2019 — v5.0:BPF CO-RE、Rust 实验性支持。
- 2022 — v6.0:Rust 进入主线、Btrfs 性能优化、更多 ARM/RISC-V 支持。
演进趋势:从通用服务器内核向 云原生(eBPF、cgroup v2)与 嵌入式实时(PREEMPT_RT、tinyconfig)双方向分化。裁剪开发需关注内核配置中
CONFIG_EXPERT、CONFIG_EMBEDDED 等开关。
1.2 内核架构概览:宏内核与微内核
Linux 采用 宏内核(Monolithic Kernel) 架构,但吸收了微内核的模块化设计思想。理解架构差异有助于在裁剪时判断哪些子系统可以移除或模块化。
1.2.1 架构对比
| 特性 | 宏内核(Linux) | 微内核(如 Minix、QNX) |
|---|---|---|
| 内核空间 | 所有核心服务(调度、内存、文件系统、驱动)运行在特权级 | 仅最小核心(IPC、调度、地址空间)在特权级 |
| 模块化 | 支持动态加载模块(.ko),但模块仍运行在内核空间 | 驱动、文件系统作为用户态服务进程 |
| 性能 | 函数调用直接,上下文切换少,吞吐高 | IPC 频繁,性能开销较大 |
| 安全性/隔离 | 一个模块崩溃可能导致整个内核 panic | 服务进程独立,故障隔离性好 |
| 裁剪灵活性 | 通过 Kconfig 编译时裁剪,但核心仍较大 | 可只保留极小的微内核,适合高安全场景 |
裁剪注意:Linux 虽然是宏内核,但通过
make tinyconfig 或手动关闭 CONFIG_NET、CONFIG_BLOCK 等子系统,可以生成仅几百 KB 的内核镜像,适用于资源极度受限的 MCU 或 FPGA 软核场景。
1.2.2 Linux 内核架构分层
下图展示了 Linux 宏内核的核心分层与子系统关系:
架构要点:所有核心子系统(调度、内存、VFS、网络)运行在同一内核地址空间,通过函数调用直接交互。裁剪时,可通过
make menuconfig 将不需要的子系统整体关闭(如 CONFIG_NET=n),从而大幅减小内核体积。
1.3 内核源码目录结构解析
Linux 内核源码采用树形组织,顶层目录按功能领域划分。掌握目录结构是进行配置、编译与裁剪的第一步。
1.3.1 顶层目录总览
| 目录/文件 | 功能说明 | 裁剪关注点 |
|---|---|---|
arch/ |
体系结构相关代码(x86、arm、arm64、riscv、mips 等) | 嵌入式开发主要关注 arch/arm/、arch/arm64/、arch/riscv/ |
block/ |
块设备层(I/O 调度、bio、分区) | 无块设备时可整体关闭 CONFIG_BLOCK=n |
crypto/ |
加密 API 与算法实现 | 无加密需求可关闭 CONFIG_CRYPTO |
drivers/ |
设备驱动(最大目录,占源码 50%+) | 裁剪重点:只保留目标板所需驱动 |
fs/ |
文件系统实现(ext4、btrfs、tmpfs、squashfs 等) | 只保留需要的文件系统,如只读系统用 squashfs |
include/ |
内核头文件(linux/、asm-generic/、uapi/) |
编译依赖,一般不做裁剪 |
init/ |
内核初始化(main.c、Kconfig) | 可定制启动参数与默认配置 |
ipc/ |
进程间通信(信号量、消息队列、共享内存) | 单进程系统可关闭 CONFIG_SYSVIPC |
kernel/ |
核心调度、任务管理、模块加载、printk | 可关闭 CONFIG_MODULES 禁止动态加载 |
lib/ |
内核通用库函数(crc32、rbtree、lzo、zstd) | 依赖自动选择,一般不动 |
mm/ |
内存管理(页分配、slab、vmalloc、oom) | 可关闭 CONFIG_COMPACTION、CONFIG_MEMCG 等 |
net/ |
网络协议栈(TCP/IP、IPv6、netfilter、wireless) | 无网络需求可关闭 CONFIG_NET=n |
scripts/ |
编译工具、Kconfig 解析器、DT 编译脚本 | 开发主机工具,不进入目标镜像 |
sound/ |
音频子系统(ALSA、ASoC) | 无音频需求可关闭 CONFIG_SOUND |
usr/ |
initramfs 打包与嵌入 | 嵌入式常用 CONFIG_INITRAMFS_SOURCE |
1.3.2 裁剪视角下的关键目录
下图从裁剪开发角度,标注了最常操作的目录及其依赖关系:
实战建议:首次接触内核源码时,先进入
arch/ 找到目标板目录,再查看 arch/*/configs/ 下的默认配置文件(如 defconfig)。以此为起点进行裁剪,比从零配置高效得多。
1.3.3 配置系统文件
内核裁剪的核心操作围绕以下文件展开:
- Kconfig — 每个目录下的配置选项定义文件,
make menuconfig读取此文件生成配置界面。 - .config — 编译时使用的最终配置文件,位于源码根目录。
- defconfig — 默认配置模板,位于
arch/*/configs/,如arch/arm/configs/imx_v7_defconfig。 - Makefile — 控制编译哪些文件进入内核镜像,裁剪时需关注
obj-y(内置)与obj-m(模块)。
裁剪工作流:
1.
2.
3.
4.
1.
make ARCH=arm imx_v7_defconfig — 加载默认配置2.
make ARCH=arm menuconfig — 交互式裁剪3.
make ARCH=arm savedefconfig — 生成精简 defconfig4.
make ARCH=arm -j$(nproc) — 编译验证