Linux内核编译与模块加载实战 - 第1节
一、Linux内核版本号命名规则
说到Linux内核版本号,很多新手第一眼看到「5.10.0-28-generic」这种字符串就头大。其实没那么复杂,我带你拆解一下就明白了。
1.1 主版本号.次版本号.修订号
这是最基础的命名方式,比如 5.10.0:
- 主版本号(5):重大架构变化,比如从2到3那次,整个内核重写了调度器
- 次版本号(10):功能更新,以前偶数表示稳定版,奇数表示开发版——不过从3.0开始这个规则就废了
- 修订号(0):小修小补,bug修复为主
我个人习惯:看次版本号就够了。比如5.10和5.15,后者多了不少新驱动支持。我去年给一块瑞芯微的板子移植内核,就发现5.15才支持那个NPU驱动,5.10死活编不过。
1.2 额外标记的含义
你还会看到类似 -rc7、-stable 这样的后缀:
| 标记 | 含义 | 我的建议 |
|---|---|---|
| -rc | Release Candidate,候选版本 | 别用在产品上,我吃过亏 |
| -stable | 稳定版,经过验证 | 嵌入式首选 |
| -git | 开发中的快照 | 除非你也在开发内核,否则别碰 |
| -longterm | 长期支持版 | 工业产品必选 |
注意:我曾经在生产环境用了-rc版内核,结果某个驱动在压力测试下直接panic。从那以后,我定了个规矩——产品线只用longterm版本。
二、内核源码目录结构
下载一份内核源码,解压后你会看到一堆目录。我第一次看的时候也懵了,但摸清楚规律后,其实很好找。
2.1 顶层目录一览
咱们挑几个核心的说:
- arch/:架构相关代码。x86、arm、riscv都在这里。你想想看,不同CPU的启动流程能一样吗?
- drivers/:驱动代码。这是最大的目录,占了源码一半以上。我经常在这里翻找网卡、I2C、SPI的驱动
- fs/:文件系统。ext4、btrfs、overlayfs都在这里
- kernel/:核心代码。调度器、进程管理、信号处理
- mm/:内存管理。页分配、slab分配器
- net/:网络协议栈。TCP/IP、socket
- Documentation/:文档。嗯,说实话质量参差不齐,但有些必看
小技巧:我习惯用 tree -L 1 先看顶层结构,然后 du -sh */ 看哪个目录最占空间。drivers目录通常最大,因为硬件厂商的驱动都塞这里。
2.2 核心目录详解
举个例子,你在做嵌入式开发,想给一块ARM板子编译内核:
- 启动相关代码在
arch/arm/boot/和arch/arm/kernel/ - 设备树文件在
arch/arm/boot/dts/ - 板级配置在
arch/arm/mach-xxx/
说白了,你只要记住:arch/ 是入口,drivers/ 是主力,kernel/ 是心脏。其他目录按需查找就行。
三、内核编译的硬件与软件环境准备
编译内核不是随便一台机器就能跑的。我见过有人用树莓派编译主线内核,结果等了一整天还没完。嗯,这里要注意硬件选型。
3.1 硬件要求
| 硬件 | 最低要求 | 推荐配置 | 我的经验 |
|---|---|---|---|
| CPU | 双核 | 4核以上 | 多核编译用 -j 参数,快很多 |
| 内存 | 2GB | 8GB以上 | 4GB以下编译大型内核会swap到死 |
| 磁盘 | 10GB | 40GB SSD | SSD比HDD快3倍以上 |
避坑指南:我曾经用一台2GB内存的笔记本编译全功能内核,结果编译到一半系统OOM,直接卡死。后来加了swap才勉强跑完,但花了整整6个小时。所以,内存不够千万别硬上。
3.2 软件环境准备
以Ubuntu/Debian为例,你需要安装这些工具:
# 基础编译工具
sudo apt install build-essential
sudo apt install gcc g++ make
# 内核编译专用工具
sudo apt install libncurses-dev # menuconfig界面
sudo apt install flex bison # 词法/语法分析器
sudo apt install libssl-dev # 签名支持
sudo apt install bc # 数学计算
# 可选但推荐
sudo apt install git # 拉取源码
sudo apt install ctags cscope # 代码浏览
为什么需要这些?我简单解释一下:
- build-essential:包含了gcc、make等基础工具,是编译的基石
- libncurses-dev:没有它,你就只能用命令行配置内核,那体验...嗯,你懂的
- flex/bison:内核的配置系统依赖它们解析Kconfig文件
- libssl-dev:如果你要开启模块签名,这个必须装
我的习惯:我会在虚拟机里准备一个干净的编译环境。这样就算搞砸了,恢复也快。另外,我建议用 apt build-dep linux 一键安装所有依赖,省心。
3.3 获取内核源码
两种方式:
# 方式一:从kernel.org下载稳定版
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.80.tar.xz
tar -xf linux-5.15.80.tar.xz
# 方式二:从git拉取主线(推荐)
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v5.15
我个人推荐用git方式。为什么?因为你可以随时切换版本,还能看commit历史。有一次我遇到一个驱动bug,就是通过git bisect找到的引入commit,省了三天排查时间。
四、知识体系总览
下面这张图,是我自己总结的内核编译知识体系。你把它存下来,后面学起来会清晰很多。
好了,这一章的内容就到这里。版本号、目录结构、环境准备,这三块是内核编译的基石。下一章我们会真正动手配置内核,到时候你会用到今天准备的环境。
一句话总结:内核编译没那么神秘,版本号会看、目录会找、环境会配,你就已经迈出了第一步。
可可精品资料库