第1章:内核编译环境搭建
说实话,做嵌入式Linux开发这么多年,我见过太多人在环境搭建这一步就卡住了。不是工具链版本不对,就是内核配置选项找不到。今天咱们就把这块硬骨头啃下来。
1.1 交叉编译工具链配置
先说说交叉编译工具链。这东西说白了,就是让你在x86的电脑上,编译出能在ARM、MIPS等其他架构上运行的代码。
工具链的选择
我个人习惯用Linaro提供的工具链,稳定且社区活跃。当然,你也可以用芯片厂商提供的,比如NXP、TI的官方工具链。
常用工具链下载地址:
- Linaro GCC:
https://releases.linaro.org/components/toolchain/binaries/ - ARM官方:
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain
安装步骤
其实就三步:下载、解压、加环境变量。
# 以ARM64为例
wget https://releases.linaro.org/components/toolchain/binaries/latest/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
# 加到环境变量
export PATH=$PATH:/path/to/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin
小提示:我建议把工具链路径写到 ~/.bashrc 里,这样每次打开终端就不用重新设置了。
验证工具链
装好了怎么知道对不对?跑一下这个命令:
aarch64-linux-gnu-gcc --version
能看到版本信息,说明工具链装好了。我在项目中遇到过有人装了半天,结果发现是x86的gcc,编译出来的东西在ARM板上跑不了——嗯,这种低级错误我也犯过。
1.2 内核源码获取与解压
内核源码怎么拿?两种方式:
- 从kernel.org下载:稳定版,适合产品开发
- 从芯片厂商获取:比如NXP的Linux内核,里面带了BSP支持
下载和解压
# 下载内核源码
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.100.tar.xz
# 解压
tar -xvf linux-5.10.100.tar.xz
# 进入目录
cd linux-5.10.100
注意:解压后的内核源码大概有1GB左右,确保你的磁盘空间够用。我曾经在虚拟机里编译,结果磁盘爆了,编译到一半报错——那叫一个崩溃。
1.3 内核配置(menuconfig)
配置内核,最常用的就是 menuconfig。它是个图形化的配置界面,用起来很方便。
基本操作
# 先清理一下
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- distclean
# 加载默认配置
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
# 进入配置界面
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
进入界面后,你会看到各种选项。按 / 可以搜索,按 空格 选中或取消,按 ESC 退出。
常用配置项
| 配置项 | 说明 | 建议 |
|---|---|---|
| General setup | 内核通用设置 | 默认即可 |
| Enable loadable module support | 模块支持 | 必须开启 |
| Device Drivers | 设备驱动 | 按需配置 |
| File systems | 文件系统支持 | ext4、proc、sysfs必选 |
避坑指南:我曾经在配置时漏掉了 CONFIG_EXT4_FS,结果根文件系统挂载不上,系统启动到一半就卡住了。排查了半天才发现是文件系统没编译进去。
1.4 编译常见错误
编译内核,说白了就是跑 make。但跑起来之后,各种错误就来了。我整理了几个最常见的:
错误1:找不到交叉编译器
make: aarch64-linux-gnu-gcc: Command not found
原因:环境变量没配好。检查一下 PATH 里有没有工具链路径。
错误2:头文件缺失
fatal error: linux/compiler-gcc.h: No such file or directory
原因:工具链版本和内核版本不匹配。我建议用Linaro 7.x系列,兼容性最好。
错误3:模块编译失败
make[1]: *** No rule to make target 'modules'
原因:没先配置内核。先跑 make defconfig 再编译。
我的经验:编译时加 -j4 参数可以加速,但别加太多,不然内存容易爆。4核CPU用 -j4,8核用 -j8,以此类推。
完整的编译命令
# 配置
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
# 编译内核
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j4
# 编译模块
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules -j4
# 安装模块到指定目录
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules_install INSTALL_MOD_PATH=/path/to/rootfs
最后提醒一句:编译内核时,确保你的系统有足够的swap空间。我见过有人用2GB内存的虚拟机编译内核,结果直接OOM(内存溢出)了。建议至少4GB内存,8GB更稳妥。
这张图把整个流程串起来了。从工具链配置到最终生成内核镜像,每一步都有坑,但按这个流程走,基本不会出大问题。
好了,环境搭建这块就讲这么多。记住一句话:工具链要对,配置要全,编译要耐心。下一章咱们聊聊内核启动流程,看看vmlinux是怎么跑起来的。