3、Linux内核源码结构:从目录到版本,再到获取方法

说实话,刚接触Linux内核源码时,我也被那庞大的目录结构吓到过。几万个文件,上千万行代码,从哪看起?

别慌。内核源码虽然大,但它的目录组织是有规律的。搞懂这个规律,你就能像逛自家后院一样熟悉它。

3.1 内核版本号:一眼看懂你的内核

先说说版本号。这东西看着简单,但很多人搞混过。

Linux内核版本号格式很固定:A.B.C-D。比如 5.10.168-1。

部分 含义 举例
A(主版本号) 重大架构变更,不常见 4 → 5
B(次版本号) 功能更新,稳定版/开发版标识 5.10、5.15
C(补丁级别) Bug修复、安全更新 5.10.168
D(发布号) 发行版打包编号 -1、-2
我的习惯:选内核时,我一般看次版本号。偶数(如5.10、5.15)是稳定版,奇数(如5.11、5.16)是开发版。做产品,老老实实用稳定版。

还有个细节——LTS(长期支持)版本。这类内核会维护5-10年。我在工业项目里,基本只选LTS内核。为什么?你不想产品卖出去两年后,内核没人管了吧?

3.2 内核源码目录:核心骨架

好,版本号搞明白了。现在咱们看看源码里到底有什么。

下载一份内核源码,解压后第一眼看到的就是这些顶层目录。我挑几个最重要的说。

arch/ —— 架构相关代码

这是硬件相关的核心目录。每种CPU架构一个子目录:

  • arch/arm/ —— ARM架构,嵌入式最常用
  • arch/arm64/ —— 64位ARM
  • arch/x86/ —— x86架构
  • arch/riscv/ —— RISC-V,新贵

每个架构目录下,又有 boot/(启动代码)、mm/(内存管理)、kernel/(核心调度)等子目录。

我曾经踩过的坑:移植内核时,以为改通用代码就行。结果发现启动流程卡死在arch层。记住:arch/是硬件和内核的接口,这里出问题,上层代码再对也没用。

drivers/ —— 驱动大本营

这是内核里最大的目录,没有之一。我数过,光子目录就上百个。

  • drivers/net/ —— 网络设备驱动
  • drivers/i2c/ —— I2C总线驱动
  • drivers/spi/ —— SPI总线驱动
  • drivers/gpio/ —— GPIO驱动
  • drivers/mmc/ —— SD卡/eMMC驱动
  • drivers/usb/ —— USB驱动

你想想看,嵌入式设备上那些外设,驱动基本都在这里。写驱动时,先看看有没有现成的,别自己从头造轮子。

fs/ —— 文件系统

内核支持的所有文件系统都在这里:

  • fs/ext4/ —— 最常用的Linux文件系统
  • fs/fat/ —— FAT系列,U盘常用
  • fs/jffs2/ —— 老牌闪存文件系统
  • fs/squashfs/ —— 只读压缩文件系统,嵌入式神器
  • fs/proc/ —— proc虚拟文件系统
  • fs/sysfs/ —— sysfs,设备模型接口

include/ —— 头文件仓库

内核编程离不开头文件。这个目录分两部分:

  • include/linux/ —— 通用内核头文件,驱动开发最常用
  • include/asm-*/ —— 架构相关的汇编头文件

写驱动时,#include <linux/module.h>、#include <linux/fs.h> 这些,都来自这里。

其他重要目录

目录 作用
kernel/ 核心调度、进程管理、信号处理
mm/ 内存管理:页分配、slab、虚拟内存
net/ 网络协议栈:TCP/IP、socket、路由
init/ 内核初始化入口,main.c在这里
scripts/ 编译脚本、配置工具、DTB编译工具
Documentation/ 内核文档,别忽略它
我的建议:刚开始学内核,别想着全看懂。先盯住三个目录:arch/(你的硬件平台)、drivers/(你的外设)、include/(接口定义)。这三个搞明白,基本就能上手了。

3.3 内核源码结构总览

说了这么多,咱们用一张图把关系理清楚。

Linux内核源码顶层结构 Linux Kernel Source arch/ drivers/ fs/ include/ kernel/ mm/ net/ 架构相关 arm/ arm64/ x86/ riscv/ mips/ powerpc/ 设备驱动 net/ i2c/ spi/ gpio/ mmc/ usb/ pci/ 文件系统 ext4/ fat/ jffs2/ squashfs/ proc/ sysfs/ 头文件 linux/ asm-generic/ uapi/ 核心子系统 进程调度 内存管理 网络协议栈 提示:嵌入式开发重点关注 arch/ + drivers/ + include/ 这三个目录覆盖了90%的移植和驱动开发工作 内核源码获取流程 kernel.org 下载 git clone 发行版源码包 解压

3.4 获取内核源码:三种方式

源码结构搞清楚了,接下来就是拿到它。我常用的方法有三种。

方式一:从 kernel.org 下载

最正统的方式。直接去 https://www.kernel.org,找到你想要的版本,下载 .tar.xz 或 .tar.gz 包。

# 下载内核源码
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.168.tar.xz

# 解压
tar -xf linux-5.10.168.tar.xz
cd linux-5.10.168/

方式二:git clone

如果你需要跟踪最新开发,或者想方便地切换版本,用git。

# 克隆主线仓库(很大,建议加 --depth)
git clone --depth=1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

# 或者克隆稳定版仓库
git clone --depth=1 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

# 查看所有标签(版本)
git tag | grep v5.10
我的习惯:做产品时,我用方式一,下载稳定版压缩包。做开发调试时,我用git clone,方便切分支。记住加 --depth=1,不然下载量会让你怀疑人生。

方式三:发行版源码包

Ubuntu、Debian等发行版会提供自己的内核源码包。好处是已经打了发行版的补丁。

# Ubuntu/Debian
apt-get install linux-source-5.10.0

# 源码通常在 /usr/src/
ls /usr/src/
注意:发行版源码包可能不是最新版本,而且补丁较多。如果你要学习纯净的内核,建议用方式一或方式二。

3.5 验证源码完整性

下载完源码,我建议你做个校验。别嫌麻烦,我在项目里遇到过下载损坏的情况,编译到一半报错,排查了半天才发现是源码包坏了。

# 下载签名文件
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.168.tar.sign

# 导入内核维护者的公钥
gpg --locate-keys torvalds@kernel.org gregkh@kernel.org

# 验证签名
xz -cd linux-5.10.168.tar.xz | gpg --verify linux-5.10.168.tar.sign -

签名验证通过,说明源码包是官方发布的,没有被篡改过。

3.6 小结

这一章咱们把内核源码的骨架摸了一遍。记住几个关键点:

  • 版本号:A.B.C-D,偶数稳定,奇数开发,LTS是首选
  • 核心目录:arch/、drivers/、fs/、include/ 是嵌入式开发的主战场
  • 获取方式:kernel.org下载、git clone、发行版源码包,按需选择
  • 验证完整性:签名校验不能省