内核源码获取与配置环境搭建
做嵌入式Linux开发,第一步就是搞定内核源码和编译环境。这事儿看着简单,但坑不少。我见过太多新手卡在源码版本不对、工具链不匹配这些地方,一卡就是好几天。
今天咱们就把这关过了。从源码获取到交叉编译环境搭建,再到第一次用menuconfig裁剪内核,一条龙走通。
选择LTS内核版本
内核版本怎么选?我的建议很明确:用LTS(Long Term Support)版本。LTS版本维护周期长,社区持续修bug,稳定性有保障。
| 版本类型 | 维护周期 | 适用场景 | 我的建议 |
|---|---|---|---|
| LTS(长期支持) | 6年+ | 产品量产、工业设备 | 首选 |
| Stable(稳定版) | 3-6个月 | 开发板验证 | 不推荐用于产品 |
| Mainline(主线) | 无固定周期 | 尝鲜、学习 | 别用在项目里 |
我个人习惯用linux-6.1.y这个LTS分支。为什么?它支持周期到2027年,而且对ARM64和ARM32的支持都很成熟。我在一个工业网关项目里就用它,跑了两年没出过问题。
当前推荐的LTS版本(截至2025年)
- linux-6.1.y — 维护到2027年,ARM生态最完善
- linux-6.6.y — 较新,支持RISC-V更好
- linux-5.15.y — 老项目还在用,但建议迁移
获取内核源码
源码从哪拿?官方渠道就一个:kernel.org。别去GitHub上随便clone,那些镜像可能不是官方的。
我常用的方式有两种:
- 直接下载tar包 — 适合第一次搭建环境
- git clone — 适合后续要跟踪补丁
先看tar包方式:
# 下载6.1.100版本
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.100.tar.xz
# 解压
tar -xf linux-6.1.100.tar.xz
cd linux-6.1.100
git方式更适合长期维护:
# 克隆LTS分支
git clone --depth 1 --branch linux-6.1.y \
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
小技巧:用--depth 1只拉最新提交,省流量也省时间。完整历史有几十万个commit,没必要全拉下来。
配置交叉编译工具链
交叉编译,说白了就是在PC上编译出能在ARM板子上跑的代码。工具链必须跟目标架构匹配。
我遇到过最坑的事:用x86的工具链编译ARM内核,编译了一小时,最后发现全是错的。嗯,这种低级错误犯一次就够了。
工具链选择
| 目标架构 | 推荐工具链 | 安装方式 |
|---|---|---|
| ARM 32位 (armv7) | arm-linux-gnueabihf- | apt install gcc-arm-linux-gnueabihf |
| ARM 64位 (aarch64) | aarch64-linux-gnu- | apt install gcc-aarch64-linux-gnu |
| RISC-V 64位 | riscv64-linux-gnu- | apt install gcc-riscv64-linux-gnu |
安装完成后,验证一下:
# 以ARM64为例
aarch64-linux-gnu-gcc --version
# 输出类似:
# aarch64-linux-gnu-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
看到版本号就说明装好了。如果提示找不到命令,检查一下PATH环境变量。
设置环境变量
我习惯把交叉编译的配置写到一个脚本里,每次编译前source一下:
# 文件: setenv.sh
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export PATH=$PATH:/usr/local/arm-gcc/bin
用的时候:
source setenv.sh
make menuconfig
注意:ARCH和CROSS_COMPILE这两个变量必须同时设置。少一个,make就会用本机gcc编译,出来的内核跑不到板子上。我曾经帮一个同事排查了两天,最后发现他忘了设ARCH=arm64。
使用menuconfig进行基础内核裁剪
内核裁剪是嵌入式优化的第一步。默认的内核配置包含大量你不需要的驱动和功能,编译出来几十兆,放不到Flash里。
menuconfig是内核提供的图形化配置工具,基于ncurses。用起来很简单:
make menuconfig
界面长这样(文字描述):
Linux/arm64 6.1.100 Kernel Configuration
─────────────────────────────────────────────
General setup --->
Platform selection --->
Kernel Features --->
Boot options --->
Power management options --->
[ ] CPU Power Management --->
[*] Networking support --->
Device Drivers --->
File systems --->
...
操作键:
- 方向键 — 上下移动
- Enter — 进入子菜单
- Y — 编译进内核
- M — 编译为模块
- N — 不编译
- ? — 查看帮助
- / — 搜索配置项
基础裁剪策略
裁剪不是乱删。我总结了一个“三步走”策略:
- 关掉不需要的架构 — 你只跑ARM64,就把x86、ARM32全关了
- 关掉不需要的驱动 — 板子上没有WiFi,就把无线网卡驱动全删了
- 关掉调试功能 — 产品发布前关掉
DEBUG_KERNEL、DYNAMIC_DEBUG
具体操作:
# 搜索某个配置项
/DEBUG_KERNEL
# 搜索结果:
# Symbol: DEBUG_KERNEL [=y]
# Prompt: Kernel debugging
# Location:
# -> Kernel hacking
# -> 按数字键1跳转到该位置
我的裁剪清单(ARM64通用)
- 关闭:
CONFIG_X86、CONFIG_ARM— 只保留ARM64 - 关闭:
CONFIG_DEBUG_KERNEL— 产品版必须关 - 关闭:
CONFIG_PRINTK(可选) — 关掉后内核不打印日志,省内存 - 关闭:
CONFIG_FTRACE— 调试用,产品版不需要 - 按需选择文件系统:只保留
ext4、squashfs,其他全关
保存配置
配置完成后,按Tab键选择Save,默认保存为.config。也可以另存为其他名字:
# 保存配置
cp .config my_defconfig
# 下次直接加载
make my_defconfig
知识体系总览
下面这张图把本章的核心流程串起来了。你跟着走一遍,环境就搭好了。
常见问题与避坑
最后分享几个我踩过的坑:
坑1:工具链版本太新
我曾经用gcc 13编译linux-5.10,结果报了一堆语法错误。后来发现是gcc太新,内核代码里有些语法在新版gcc下不兼容。解决办法:用gcc 11或12,或者升级内核版本。
坑2:.config不干净
如果你从别的项目拷了.config过来,直接make menuconfig修改,可能会残留一些依赖问题。我建议每次都用make defconfig生成一个干净的基准配置,再在此基础上裁剪。
小技巧:第一次编译别追求极致裁剪。先保证能跑起来,再慢慢优化。我一般第一次只关掉明显不需要的架构和驱动,编译通过后再迭代裁剪。