3、获取内核源码:从kernel.org下载、使用Git管理内核源码、打补丁与版本切换
好,咱们正式开始动手。做嵌入式Linux,第一件事就是拿到内核源码。这事儿听起来简单,但里面的门道不少。我见过不少新手,直接去网上下个zip包就开始改,结果后面版本一乱,补丁打不上,哭都来不及。
今天咱们就把「获取源码」这件事聊透。从哪下、怎么管、怎么打补丁、怎么切版本,一条龙讲清楚。
3.1 从 kernel.org 下载:官方渠道与签名验证
最正统的获取方式,就是去 kernel.org。这是Linux内核的官方发布站点,所有主线版本、稳定版、长期支持版(LTS)都在这里。
我个人习惯,只从 kernel.org 下载。为什么?因为安全。你想想看,内核是整个系统的核心,如果源码被人动过手脚,后果不堪设想。kernel.org 提供 GPG 签名,下载完可以验证完整性。
下载步骤:
- 打开浏览器,访问
https://www.kernel.org/ - 找到你需要的版本,比如
linux-5.10.210.tar.xz - 同时下载对应的签名文件
linux-5.10.210.tar.sign - 用 GPG 验证签名
验证签名的命令长这样:
# 导入内核维护者的公钥
gpg --locate-keys torvalds@kernel.org gregkh@kernel.org
# 验证签名
xz -cd linux-5.10.210.tar.xz | gpg --verify linux-5.10.210.tar.sign -
# 如果输出 "Good signature",说明文件没问题
我曾经在一个项目里,图省事从第三方镜像站下载了内核。编译到一半报错,查了半天发现是源码被篡改过,某个驱动文件里被插了挖矿代码。从那以后,我再也不敢跳过签名验证这一步。
注意:不要用 root 用户解压和编译内核。创建一个普通用户,专门做内核开发。这是基本的安全习惯。
3.2 使用 Git 管理内核源码:克隆、分支与标签
下载压缩包只是临时方案。真正做项目,我强烈建议你用 Git 管理内核源码。为什么?因为你要打补丁、要切版本、要回溯问题,Git 是唯一靠谱的工具。
Linux 内核的官方 Git 仓库在 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git。克隆整个仓库大概需要 3-5GB 空间,网速好的话十几分钟能搞定。
# 克隆主线仓库
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
# 进入目录
cd linux
# 查看所有标签(版本号)
git tag -l 'v5.10.*'
# 切换到特定版本
git checkout v5.10.210
这里有个关键点:标签(tag)。每个正式发布的内核版本都有一个对应的 tag,比如 v5.10.210。你切到 tag 之后,仓库就处于「分离头指针」状态。别慌,这是正常的。你可以在上面创建自己的分支:
# 基于某个 tag 创建自己的开发分支
git checkout -b my-board-v5.10 v5.10.210
这样做的好处是,你的所有修改都在 my-board-v5.10 分支上,跟主线完全隔离。以后主线更新了,你可以把新版本合并进来,或者 rebase 上去。
我的经验:嵌入式项目通常基于某个 LTS 版本(比如 5.10、5.15、6.1)。选好 LTS 版本后,fork 出来,永远不要直接在 master 上改。这样出了问题,你能清楚地知道哪些代码是自己改的,哪些是上游的。
3.3 打补丁:patch 与 git am 的正确用法
做嵌入式开发,打补丁是家常便饭。芯片厂商会给你 BSP 补丁,社区会给你修复补丁,你自己也要写补丁。怎么打?两种主流方式:patch 命令和 git am。
3.3.1 传统 patch 命令
这种方式适合一次性补丁,或者你还没用 Git 管理源码的情况。
# 打补丁
cd linux-5.10.210
patch -p1 < ../my-fix.patch
# 验证补丁是否成功
patch -p1 --dry-run < ../my-fix.patch
-p1 是什么意思?说白了,就是去掉补丁文件路径中的第一级目录。内核补丁的路径通常以 a/ 和 b/ 开头,-p1 就是去掉这个前缀。
3.3.2 Git 方式:git am 和 git apply
如果你用 Git 管理源码,我推荐用 git am。它能保留补丁的提交信息、作者、时间戳,方便以后追溯。
# 应用补丁并保留提交信息
git am ../my-fix.patch
# 如果补丁冲突,解决后继续
git am --continue
# 或者放弃这次应用
git am --abort
还有一种情况,你只有 .patch 文件,但不想保留提交信息,只想把改动合进来:
# 只应用改动,不生成提交
git apply ../my-fix.patch
避坑指南:我曾经在一个项目里,连续打了 20 多个补丁,结果编译报错。排查了半天,发现是补丁顺序错了。内核补丁之间有依赖关系,顺序不能乱。建议你每次打补丁前,先看补丁文件的描述,或者用 quilt 工具管理补丁栈。
3.4 版本切换:在 LTS 与主线之间游走
嵌入式项目生命周期长,你可能需要在不同版本之间切换。比如,产品量产时用 5.10 LTS,但为了支持新硬件,想试试 6.1 LTS。怎么切?
如果你用 Git,切换版本就是一条命令的事:
# 查看当前分支
git branch
# 切换到另一个 LTS 版本
git checkout v6.1.100
# 或者创建新分支
git checkout -b my-board-v6.1 v6.1.100
但这里有个坑:配置不兼容。不同版本的内核,Kconfig 选项可能变了。你从 5.10 切到 6.1,原来的 .config 文件可能没法直接用。我建议的做法是:
- 切到新版本后,先
make olddefconfig,让内核自动适配新配置 - 然后
make menuconfig,手动检查新增的选项 - 最后保存配置,开始编译
版本切换检查清单:
| 检查项 | 说明 |
|---|---|
| 配置兼容性 | 运行 make olddefconfig 自动适配 |
| 设备树语法 | 新版本可能弃用了某些属性,检查 dts 文件 |
| 驱动 API 变化 | 检查你修改过的驱动,API 是否变了 |
| 补丁兼容性 | 旧补丁可能在新版本上打不上,需要 rebase |
| 工具链版本 | 新内核可能需要更新的交叉编译工具链 |
3.5 本章知识结构图
下面这张图,把获取内核源码的完整流程串起来了。从下载到管理,再到打补丁和切换版本,一目了然。
3.6 小结
获取内核源码,看似简单,实则是整个嵌入式Linux开发的基础。我见过太多人在这上面栽跟头——补丁顺序搞错、版本切不回去、源码被篡改还不知道。
记住三条铁律:
- 只用官方渠道,下载完必须验证签名
- 用 Git 管理,永远在分支上工作
- 打补丁前先检查,顺序错了就全白干
把这些基本功练扎实了,后面的内核配置和编译才能顺风顺水。