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 宏内核的核心分层与子系统关系:

Linux 宏内核架构分层 用户空间(User Space) 应用程序 · C 库 · Shell · 守护进程 系统调用接口(System Call Interface) 内核核心(Kernel Core) 进程调度 CFS · RT · Deadline 内存管理 VMA · Slab · 页回收 VFS 虚拟文件系统 ext4 · btrfs · tmpfs 网络协议栈 TCP/IP · netfilter IPC 进程间通信 信号 · 管道 · 共享内存 安全模块 SELinux · AppArmor 设备驱动框架(字符 · 块 · 网络 · 平台) 硬件层(CPU · 内存 · 外设 · 总线)
架构要点:所有核心子系统(调度、内存、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 裁剪视角下的关键目录

下图从裁剪开发角度,标注了最常操作的目录及其依赖关系:

裁剪视角:内核源码关键目录与依赖 init/ kernel/ mm/ arch/(板级支持) drivers/(裁剪重灾区) fs/ net/ sound/ Kconfig(配置入口) arch/*/boot/dts/ Makefile · Kbuild
实战建议:首次接触内核源码时,先进入 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. make ARCH=arm imx_v7_defconfig — 加载默认配置
2. make ARCH=arm menuconfig — 交互式裁剪
3. make ARCH=arm savedefconfig — 生成精简 defconfig
4. make ARCH=arm -j$(nproc) — 编译验证