内核源码获取与配置环境搭建

做嵌入式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,那些镜像可能不是官方的。

我常用的方式有两种:

  1. 直接下载tar包 — 适合第一次搭建环境
  2. 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 — 不编译
  • ? — 查看帮助
  • / — 搜索配置项

基础裁剪策略

裁剪不是乱删。我总结了一个“三步走”策略:

  1. 关掉不需要的架构 — 你只跑ARM64,就把x86、ARM32全关了
  2. 关掉不需要的驱动 — 板子上没有WiFi,就把无线网卡驱动全删了
  3. 关掉调试功能 — 产品发布前关掉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. 选择LTS版本 2. 获取源码 3. 解压/克隆 4. 安装交叉工具链 5. 设置环境变量 6. 验证工具链 7. make menuconfig 8. 基础裁剪 9. 保存.config 裁剪要点:关架构 → 关驱动 → 关调试 → 按需选文件系统 💡 避坑提醒 ARCH和CROSS_COMPILE必须同时设置;LTS版本优先;menuconfig用/搜索配置项

常见问题与避坑

最后分享几个我踩过的坑:

坑1:工具链版本太新

我曾经用gcc 13编译linux-5.10,结果报了一堆语法错误。后来发现是gcc太新,内核代码里有些语法在新版gcc下不兼容。解决办法:用gcc 11或12,或者升级内核版本。

坑2:.config不干净

如果你从别的项目拷了.config过来,直接make menuconfig修改,可能会残留一些依赖问题。我建议每次都用make defconfig生成一个干净的基准配置,再在此基础上裁剪。

小技巧:第一次编译别追求极致裁剪。先保证能跑起来,再慢慢优化。我一般第一次只关掉明显不需要的架构和驱动,编译通过后再迭代裁剪。