技术知识库

从 Debian 官方仓库构建 ARM64 ext4 根文件系统

从 Debian 官方仓库构建 ARM64 ext4 根文件系统

摘要

本手册不使用仓库预制 rootfs,而是在 x86_64 主机上通过两阶段 debootstrap 构建 Debian 12 bookworm ARM64,配置 systemd、用户、静态网络和 SSH,安装 Linux 5.0.0+ 模块,再制作可写 ext4 镜像并用 QEMU 启动。

路径约定

ROOTFS=/home/martin-zou/workspace/debian-arm64-rootfs
IMAGE=/home/martin-zou/workspace/debian-arm64.ext4
KERNEL=/home/martin-zou/workspace/runninglinuxkernel_5.0

下面命令中的路径均与本轮已验证环境一致。

1. 安装并检查主机工具

sudo apt update
sudo apt install \
  debootstrap debian-archive-keyring \
  qemu-user-binfmt \
  e2fsprogs

debootstrap --version
qemu-aarch64 --version
cat /proc/sys/fs/binfmt_misc/qemu-aarch64

binfmt 应为 enabled,解释器为 /usr/bin/qemu-aarch64。

Ubuntu 26.04 中 qemu-user-static 已是虚拟包,不应与它的提供者同时写入安装命令;详见 Ubuntu 26.04 中 qemu-user-static 是虚拟包。

2. Bootstrap 第一阶段

Bootstrap 的目的以及为什么分成两阶段,见 debootstrap 为什么分成两个阶段。

目标目录必须是新的空目录;不要在内核源码目录使用相对路径创建同名 rootfs。

cd /home/martin-zou/workspace

sudo debootstrap \
  --arch=arm64 \
  --foreign \
  --variant=minbase \
  bookworm \
  /home/martin-zou/workspace/debian-arm64-rootfs \
  https://deb.debian.org/debian

验证:

file /home/martin-zou/workspace/debian-arm64-rootfs/bin/dash
sudo du -sh /home/martin-zou/workspace/debian-arm64-rootfs
ls /home/martin-zou/workspace/debian-arm64-rootfs/debootstrap

3. Bootstrap 第二阶段

这里并不是在 x86_64 CPU 上直接执行 ARM64 指令。完整机制见 binfmt_misc 与 QEMU user-mode 如何支持跨架构 chroot。

sudo chroot \
  /home/martin-zou/workspace/debian-arm64-rootfs \
  /debootstrap/debootstrap --second-stage

验证:

sudo chroot \
  /home/martin-zou/workspace/debian-arm64-rootfs \
  /bin/bash -c '
    dpkg --print-architecture
    cat /etc/os-release
    dpkg-query -W base-files libc6 apt
  '

预期架构为 arm64,系统为 Debian 12 bookworm,并出现 Base system installed successfully。

4. 配置 APT 软件源

sudo vim /home/martin-zou/workspace/debian-arm64-rootfs/etc/apt/sources.list

写入:

deb https://deb.debian.org/debian bookworm main
deb https://deb.debian.org/debian bookworm-updates main
deb https://security.debian.org/debian-security bookworm-security main

5. 挂载 chroot 运行环境

chroot 只改变根目录视图,临时挂载 /dev、/proc、/sys 和 /run 是为了让目标用户空间访问主机内核提供的运行时接口。

sudo mount --rbind \
  /dev \
  /home/martin-zou/workspace/debian-arm64-rootfs/dev

sudo mount --make-rslave \
  /home/martin-zou/workspace/debian-arm64-rootfs/dev

sudo mount -t proc proc \
  /home/martin-zou/workspace/debian-arm64-rootfs/proc

sudo mount -t sysfs sysfs \
  /home/martin-zou/workspace/debian-arm64-rootfs/sys

sudo mount -t tmpfs tmpfs \
  /home/martin-zou/workspace/debian-arm64-rootfs/run

进入 ARM64 chroot:

sudo chroot \
  /home/martin-zou/workspace/debian-arm64-rootfs \
  /bin/bash

6. 在 chroot 内安装基础系统

以下命令在 root@...:/# 提示符内执行:

export LANG=C
export DEBIAN_FRONTEND=noninteractive

apt update
apt install \
  systemd-sysv udev kmod \
  ifupdown isc-dhcp-client iproute2 net-tools \
  openssh-server sudo vim file \
  build-essential ca-certificates locales

设置主机名:

vim /etc/hostname

文件内容:

rlk-arm64

编辑 hosts:

vim /etc/hosts

至少包含:

127.0.0.1 localhost
127.0.1.1 rlk-arm64

创建普通用户并设置密码:

passwd root
useradd -m -s /bin/bash -u 1000 martin
passwd martin
usermod -aG sudo,users martin

7. 配置文件系统、网络与服务

vim /etc/fstab

写入:

/dev/vda  /      ext4  defaults  0  1
proc      /proc  proc  defaults  0  0
vim /etc/network/interfaces

写入:

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 10.0.2.15/24
    gateway 10.0.2.2
vim /etc/resolv.conf

写入:

nameserver 10.0.2.3

启用服务:

systemctl enable networking.service
systemctl enable serial-getty@ttyAMA0.service
systemctl enable ssh.service

getent passwd root martin
id martin
cat /etc/hostname
ls -l /sbin/init

退出 chroot:

exit

8. 卸载临时文件系统

在主机执行:

sudo umount /home/martin-zou/workspace/debian-arm64-rootfs/run
sudo umount /home/martin-zou/workspace/debian-arm64-rootfs/sys
sudo umount /home/martin-zou/workspace/debian-arm64-rootfs/proc
sudo umount -R /home/martin-zou/workspace/debian-arm64-rootfs/dev

findmnt -R /home/martin-zou/workspace/debian-arm64-rootfs

最后一条不应再显示残留挂载。

9. 安装 Linux 5.0 模块

cd /home/martin-zou/workspace/runninglinuxkernel_5.0

make -s ARCH=arm64 \
  CROSS_COMPILE=aarch64-linux-gnu- \
  O=build/arm64 \
  kernelrelease

sudo make ARCH=arm64 \
  CROSS_COMPILE=aarch64-linux-gnu- \
  O=build/arm64 \
  INSTALL_MOD_PATH=/home/martin-zou/workspace/debian-arm64-rootfs \
  modules_install

验证:

find /home/martin-zou/workspace/debian-arm64-rootfs/lib/modules/5.0.0+ \
  -name '*.ko' |
  wc -l

ls -lh \
  /home/martin-zou/workspace/debian-arm64-rootfs/lib/modules/5.0.0+/modules.dep

本轮安装 35 个模块。缺少 modules.builtin.modinfo 的 depmod 警告不阻断 Linux 5.0 模块安装。

10. 制作 2 GiB ext4 镜像

目录形式的 rootfs、ext4 镜像和 QEMU /dev/vda 之间的关系见 根文件系统目录树与 ext4 镜像的区别。

cd /home/martin-zou/workspace

truncate -s 2G debian-arm64.ext4

sudo mkfs.ext4 \
  -F \
  -L rlk-rootfs \
  -O '^orphan_file' \
  -d /home/martin-zou/workspace/debian-arm64-rootfs \
  /home/martin-zou/workspace/debian-arm64.ext4

显式关闭 orphan_file,避免 Ubuntu 26.04 的新版 e2fsprogs 创建 Linux 5.0 不认识的 ext4 incompat feature。

ls -lh /home/martin-zou/workspace/debian-arm64.ext4
du -h /home/martin-zou/workspace/debian-arm64.ext4

sudo tune2fs -l /home/martin-zou/workspace/debian-arm64.ext4 |
  grep -E 'Filesystem volume name|Filesystem features|Block count|Free blocks'

11. QEMU 启动 Debian

到这一步才从 QEMU user-mode/chroot 切换为 QEMU system-mode:虚拟机开始运行自行编译的 Linux 5.0 内核。

qemu-system-aarch64 \
  -machine virt \
  -cpu cortex-a57 \
  -smp 2 \
  -m 1024 \
  -kernel /home/martin-zou/workspace/runninglinuxkernel_5.0/build/arm64/arch/arm64/boot/Image \
  -append "console=ttyAMA0 root=/dev/vda rw rootwait net.ifnames=0 loglevel=8" \
  -drive if=none,file=/home/martin-zou/workspace/debian-arm64.ext4,format=raw,id=hd0 \
  -device virtio-blk-pci,drive=hd0 \
  -netdev user,id=net0,hostfwd=tcp::2222-:22 \
  -device virtio-net-pci,netdev=net0 \
  -object rng-random,filename=/dev/urandom,id=rng0 \
  -device virtio-rng-pci,rng=rng0 \
  -nographic

virtio RNG 的原因与故障闭环见 Linux 5.0 QEMU 中熵不足导致 systemd SSH 和 HTTPS 阻塞。

12. 虚拟机内验证

uname -a
cat /etc/os-release
hostname
findmnt /
systemctl is-system-running
systemctl --failed
cat /proc/sys/kernel/random/entropy_avail
ip -4 addr show eth0
ip route
systemctl status ssh --no-pager
sudo apt update

13. SSH 与持久化

主机执行:

ssh -p 2222 martin@127.0.0.1

虚拟机内创建测试文件:

vim /home/martin/persistence-test.txt
sync
sudo poweroff

重新用同一 QEMU 命令启动并 SSH 登录:

cat /home/martin/persistence-test.txt
systemctl is-system-running

文件仍存在且 systemd 为 running,即完成可写 ext4 跨重启验证。

关联