4. Linux内核源码获取与编译环境搭建:下载主线内核、配置交叉编译工具链、构建最小文件系统镜像
文件系统移植工作的起点,是建立一个可重复、可验证的内核编译环境。本章将引导你完成从源码获取到最小文件系统镜像构建的完整流程,为后续的 ext4 到 F2FS 适配实验打下坚实的工程基础。
4.1 主线内核源码获取策略
移植工作建议基于 Linux 主线内核(Mainline) 而非发行版内核,因为主线内核包含最新的文件系统特性与修复。获取方式主要有两种:
| 方式 | 命令/操作 | 适用场景 |
|---|---|---|
| Git 克隆(完整仓库) | git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git |
长期开发、需要追踪历史提交 |
| 下载稳定版 tarball | wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.tar.xz |
快速搭建、固定版本实验 |
| LTS 长期支持版 | 从 https://www.kernel.org/ 选择 LTS 标签版本 |
产品级移植、长期维护 |
推荐做法: 使用
git clone --depth=1 浅克隆仅获取最新版本,可大幅减少下载时间与磁盘占用。例如:git clone --depth=1 -b v6.6 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
4.2 交叉编译工具链配置
嵌入式目标平台(如 ARM64、RISC-V)通常无法直接运行 x86 编译出的内核,必须使用交叉编译工具链。以下是标准配置流程:
4.2.1 工具链安装
以 ARM64(aarch64)目标为例,推荐使用 Linaro 或 ARM 官方提供的预编译工具链:
# 下载并解压 ARM64 工具链
wget https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
tar -xf arm-gnu-toolchain-13.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
sudo mv arm-gnu-toolchain-13.2.rel1-x86_64-aarch64-none-linux-gnu /opt/toolchains/
# 将工具链加入 PATH
export PATH=/opt/toolchains/arm-gnu-toolchain-13.2.rel1-x86_64-aarch64-none-linux-gnu/bin:$PATH
4.2.2 环境变量与 Make 参数
编译内核时,需要向 make 传递架构和工具链前缀:
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-
# 验证工具链是否生效
aarch64-none-linux-gnu-gcc --version
关键参数说明:
ARCH:指定目标 CPU 架构,如 arm64、riscv、armCROSS_COMPILE:交叉编译工具链前缀,内核 Makefile 会自动追加 gcc、ld、objcopy 等后缀- 建议将上述 export 命令写入
~/.bashrc或项目根目录的setenv.sh脚本中
4.3 内核配置与编译
获取源码并配置好工具链后,进入内核源码目录执行配置与编译:
cd linux-6.6
# 第一步:生成默认配置(基于目标架构)
make defconfig
# 第二步:手动调整配置,启用 F2FS 支持
make menuconfig
# 在 menuconfig 界面中导航至:
# File systems --->
# [*] F2FS filesystem support
# [*] F2FS Status Information
# [*] F2FS extended attributes
# [*] F2FS Access Control Lists
# 第三步:编译内核镜像与设备树
make -j$(nproc) Image.gz
make -j$(nproc) dtbs
# 第四步:编译内核模块(可选)
make -j$(nproc) modules
编译产物位于 arch/arm64/boot/ 目录下:
Image.gz— 压缩后的内核镜像Image— 未压缩的内核镜像(QEMU 直接引导用)dts/与dtbs/— 设备树源文件与编译后的二进制
常见编译错误排查:
- “No rule to make target ‘defconfig’” — 检查 ARCH 环境变量是否设置正确
- “Cannot use CONFIG_CC_OPTIMIZE_FOR_SIZE” — 工具链版本过旧,建议升级到 GCC 12+
- “fatal error: linux/compiler.h” — 未执行
make defconfig直接编译
4.4 最小文件系统镜像构建
内核启动后需要根文件系统(rootfs)才能完成初始化。最小文件系统通常包含 init 程序、必要的设备节点和 BusyBox 工具集。
4.4.1 使用 BusyBox 构建最小 rootfs
# 下载并编译 BusyBox
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar -xf busybox-1.36.1.tar.bz2
cd busybox-1.36.1
# 配置为静态编译(避免依赖动态库)
make defconfig
make menuconfig
# 在 Settings 中启用:
# [*] Build static binary (no shared libs)
# 编译并安装到临时目录
make -j$(nproc)
make CONFIG_PREFIX=../rootfs install
cd ../rootfs
# 创建必要目录结构
mkdir -p proc sys dev etc/init.d
# 创建 init 脚本
cat > init << 'EOF'
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs none /tmp
echo "Welcome to Minimal Rootfs for F2FS Porting"
exec /bin/sh
EOF
chmod +x init
4.4.2 制作文件系统镜像
将 rootfs 目录打包为 ext4 或 F2FS 镜像,用于 QEMU 或实际硬件引导:
# 创建一个 512MB 的空白镜像
dd if=/dev/zero of=rootfs.img bs=1M count=512
# 格式化为 ext4(后续章节将替换为 F2FS)
mkfs.ext4 rootfs.img
# 挂载并复制 rootfs 内容
mkdir -p /mnt/rootfs
sudo mount -o loop rootfs.img /mnt/rootfs
sudo cp -a ../rootfs/* /mnt/rootfs/
sudo umount /mnt/rootfs
# 验证镜像完整性
fsck.ext4 -f rootfs.img
快速验证: 使用 QEMU 启动编译好的内核与 rootfs 镜像:
qemu-system-aarch64 -M virt -cpu cortex-a57 -kernel arch/arm64/boot/Image -drive file=rootfs.img,format=raw -append "root=/dev/vda console=ttyAMA0" -nographic
4.5 环境搭建流程总览
下图展示了从源码获取到可启动镜像的完整工作流:
4.6 环境验证清单
完成上述步骤后,建议逐项核对以下清单,确保环境无误:
| 检查项 | 验证命令 | 预期结果 |
|---|---|---|
| 工具链可用 | aarch64-none-linux-gnu-gcc --version |
显示版本号,无“command not found” |
| 内核配置正确 | grep CONFIG_F2FS_FS .config |
输出 CONFIG_F2FS_FS=y |
| 内核镜像生成 | ls -lh arch/arm64/boot/Image |
文件存在且大小合理(通常 > 10MB) |
| rootfs 镜像挂载 | sudo mount -o loop rootfs.img /mnt/test && ls /mnt/test |
看到 bin/、sbin/、etc/ 等目录 |
| QEMU 启动 | 执行 QEMU 命令后观察串口输出 | 内核启动日志后进入 shell 提示符 |
环境就绪标志: 当你在 QEMU 串口终端看到
Welcome to Minimal Rootfs for F2FS Porting 并出现 # 提示符时,说明内核源码获取、交叉编译工具链配置、内核编译与最小文件系统镜像构建全部成功。下一阶段将基于此环境进行 F2FS 文件系统的移植与调试。