这里我们使用 docker
编译我们的 u-boot
和 kernel
编译 u-boot
wget <https://source.denx.de/u-boot/u-boot/-/archive/v2025.04/u-boot-v2025.04.tar.gz>
tar xf u-boot-v2025.04.tar.gz
cd u-boot-v2025.04
make qemu_arm64_defconfig
... # just build it
cp u-boot.bin ../images # 复制到统一目录
wget <https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.14.6.tar.xz>
tar xf linux-6.14.6.tar.xz
cd linux-6.14.6
make ARCH=arm64 defconfig # kernel 会根据 ARCH 寻找 configs
make LLVM=1 ARCH=arm64 -j$(nproc) # 支持 LLVM 就不用 GCC 了
cp arch/arm64/boot/Image ../images
我们使用 alpine
作为 rootfs
首先制作一个 init
脚本用于初始化基本 rootfs
, 这个脚本仅仅进入 shell
给我们测试, 后面会更新跳转实际 rootfs
的 init
脚本. 注意使用 chmod +x init
为脚本添加执行权限.
#!/bin/sh
echo "Loading, please wait..."
[ -d /dev ] || mkdir -m 0755 /dev
[ -d /root ] || mkdir --mode=0700 /root
[ -d /sys ] || mkdir /sys
[ -d /proc ] || mkdir /proc
[ -d /tmp ] || mkdir /tmp
[ -d /mnt ] || mkdir /mnt
# Mount /proc and /sys:
mount -n proc /proc -t proc
mount -n sysfs /sys -t sysfs
# Note that this only becomes /dev on the real filesystem if udev's scripts
# are used; which they will be, but it's worth pointing out
#mount -t tmpfs -o mode=0755 udev /dev
[ -e /dev/console ] || mknod /dev/console c 5 1
[ -e /dev/null ] || mknod /dev/null c 1 3
# this will scan device update /dev list
mdev -s
/bin/sh -i
mkdir rootfs
wget <https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/aarch64/alpine-minirootfs-3.21.3-aarch64.tar.gz>
tar xf alpine-minirootfs-3.21.3-aarch64.tar.gz -C rootfs
cd rootfs
cp ../init . # copy init script to rootfs
find . | cpio -o -H newc | gzip > ../images/rootfs.cpio.gz
我们将qemu模拟设备的机器设备树dump出来, 这里我们的模拟机器是 virt
, 相关的其他 arm
机器查询https://www.qemu.org/docs/master/system/target-arm.html
qemu-system-aarch64 -machine virt,dumpdtb=virt.dtb -cpu cortex-a72 -smp 4 -m 2G -nographic