3、获取内核源码:从kernel.org下载、使用Git管理内核源码、打补丁与版本切换

好,咱们正式开始动手。做嵌入式Linux,第一件事就是拿到内核源码。这事儿听起来简单,但里面的门道不少。我见过不少新手,直接去网上下个zip包就开始改,结果后面版本一乱,补丁打不上,哭都来不及。

今天咱们就把「获取源码」这件事聊透。从哪下、怎么管、怎么打补丁、怎么切版本,一条龙讲清楚。

3.1 从 kernel.org 下载:官方渠道与签名验证

最正统的获取方式,就是去 kernel.org。这是Linux内核的官方发布站点,所有主线版本、稳定版、长期支持版(LTS)都在这里。

我个人习惯,只从 kernel.org 下载。为什么?因为安全。你想想看,内核是整个系统的核心,如果源码被人动过手脚,后果不堪设想。kernel.org 提供 GPG 签名,下载完可以验证完整性。

下载步骤:

  1. 打开浏览器,访问 https://www.kernel.org/
  2. 找到你需要的版本,比如 linux-5.10.210.tar.xz
  3. 同时下载对应的签名文件 linux-5.10.210.tar.sign
  4. 用 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 文件可能没法直接用。我建议的做法是:

  1. 切到新版本后,先 make olddefconfig,让内核自动适配新配置
  2. 然后 make menuconfig,手动检查新增的选项
  3. 最后保存配置,开始编译

版本切换检查清单:

检查项 说明
配置兼容性 运行 make olddefconfig 自动适配
设备树语法 新版本可能弃用了某些属性,检查 dts 文件
驱动 API 变化 检查你修改过的驱动,API 是否变了
补丁兼容性 旧补丁可能在新版本上打不上,需要 rebase
工具链版本 新内核可能需要更新的交叉编译工具链

3.5 本章知识结构图

下面这张图,把获取内核源码的完整流程串起来了。从下载到管理,再到打补丁和切换版本,一目了然。

获取内核源码:完整流程 kernel.org 下载 Git 克隆仓库 第三方 BSP 包 GPG 签名验证 查看标签 & 切换版本 解压 / 导入仓库 创建开发分支:git checkout -b my-board-v5.10 打补丁:git am / patch -p1 版本切换:git checkout & make olddefconfig 核心原则:永远在分支上工作,永远验证签名,永远检查补丁顺序

3.6 小结

获取内核源码,看似简单,实则是整个嵌入式Linux开发的基础。我见过太多人在这上面栽跟头——补丁顺序搞错、版本切不回去、源码被篡改还不知道。

记住三条铁律:

  • 只用官方渠道,下载完必须验证签名
  • 用 Git 管理,永远在分支上工作
  • 打补丁前先检查,顺序错了就全白干

把这些基本功练扎实了,后面的内核配置和编译才能顺风顺水。