步骤
1. 获取内核源码
1 | wget https://git.kernel.org/torvalds/t/linux-6.14-rc2.tar.gz |
2. 安装交叉编译工具链
1 | sudo apt install fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison |
3. 配置内核
1 | export ARCH=arm64 |
4. 制作根文件系统
获取Busybox
1 | wget https://busybox.net/downloads/busybox-1.32.1.tar.bz2 |
配置Busybox
1 | make defconfig |

编译Busybox
1 | make -j12 |
制作根文件系统(setup_rootfs.sh)
1 | $ cat setup_rootfs.sh |
自定义根文件系统(rootfs)
1 | $ cat rootfs/etc/inittab |
5. 启动内核
1 | qemu-system-aarch64 -machine virt,virtualization=true,gic-version=3 -nographic -m size=1024M -cpu cortex-a72 -smp 2 -kernel ../../linux-stable.git1/arch/arm64/boot/Image -drive format=raw,file=rootfs.img -append "root=/dev/vda rw" |
定制
1. 选择其他编译器
虽然Ubuntu官方仓库已经提供了aarch64-linux-gnu-gcc,但是“定制”肯定也包括选择其他编译器,所以决定记录一下。
这里以使用Bootlin提供的aarch64-linux-gcc为例。
1 | wget https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--musl--bleeding-edge-2024.05-1.tar.xz |
设置环境变量:
1 | export PATH="/toolchains/aarch64--musl--bleeding-edge-2024.05-1/bin/:$PATH" |
此外,由于某些编译器提供厂商无法覆盖所有的库,所以我们需要手动安装一些第三方库(zlib、libcurl…)。例如:
1 | # 下载所需类库(源代码) |
不同第三方库的安装方法可能略微不同,不过主要步骤差别不大,这里不再赘述。
2. 编译用户程序
Linux常用的运行时库包括glibc、musl、uclibc等,这里使用了musl。在交叉编译时,我们可能需要另外设置程序的linker的地址,通过:
1 | export LDFLAGS="-Wl,--dynamic-linker=/lib/musl/ld-musl-aarch64.so.1,-rpath=/lib/musl" |
3. 部署至操作系统
编译成功后,我们将生成的可执行的用户程序复制到rootfs某个目录即可。
在此之前,我们需要先配置好上述的musl运行时库(如果使用到了)。方法如下:
1 | sudo mkdir -p rootfs/lib/musl/ |
将上述逻辑封装至脚本setup_rootfs.sh的umount操作前即可。
4. 测试
这里我们使用一个hello程序测试交叉编译出的系统是否正常。
1 | $ cat hello.c |
启动Qemu,运行并查看结果:
