基于 Kali Linux ARM64 2026.3 与 Arch Linux ARM Generic AArch64 的完整实验报告
/root/arch-arm64-iso
本报告记录了在 Kali Linux ARM64 2026.3 环境中,从零构建一个基于 Arch Linux ARM Generic AArch64 的可启动、可进入 KDE Plasma Live 桌面、可选择安装到虚拟硬盘、支持 ARM64 UEFI、中文系统环境与 Fcitx5 中文输入法的自定义操作系统镜像 WuKongOS 1.0 的完整过程。
额,我打包进去的是简体输入法,各位林北有需要可以打包进去仓颉输入法.我设置操作系统名字是 悟空OS.各位林北可以设置自己喜欢的女神名字~
项目最终采用“Live Installer ISO”架构:ISO 启动阶段使用定制的 mkinitcpio hook 查找 ISO9660 光盘、挂载 SquashFS,并通过 OverlayFS 构造临时可写根文件系统;进入 systemd 后,根据 GRUB 传入的 wukong_install=1 参数决定是进入安装模式,还是进入 KDE Live 模式。安装模式中,wukong-install 自动对目标硬盘进行 GPT 分区、EFI System Partition 与 ext4 根分区创建、基础系统复制、目标系统 chroot、KDE Plasma / NetworkManager / SDDM / Fcitx5 安装、中文 locale 配置、硬盘版 initramfs 生成以及 ARM64 UEFI GRUB 安装。
本项目中最关键的工程问题包括:Arch 官方 archiso 工具主要面向 x86_64,故采用手工构建 ARM64 ISO;SquashFS 必须使用 gzip 而不是 zstd;VMware Fusion ARM64 对 EFI 启动镜像的要求;Live initramfs 与硬盘 initramfs 的职责分离;以及 efibootmgr 在 Live/chroot 环境中无法写入 UEFI NVRAM 时,使用 grub-install --removable --no-nvram 将引导器写入标准 ARM64 fallback 路径 EFI/BOOT/BOOTAA64.EFI。
最终 ISO 启动后,GRUB 提供三个入口:
1. Install WuKongOS 1.0
2. Try WuKongOS 1.0 Live
3. WuKongOS 1.0 Live Debug
三种模式的目标如下:
wukong_install=1 后自动执行 wukong-install;安装器完成硬盘分区、系统复制、KDE Plasma、Fcitx5、中文环境、GRUB 安装,最终提示断开 ISO 后重启。premount 阶段进入调试 shell,用于排查 ISO、SquashFS、OverlayFS、设备识别等问题。最终从硬盘启动后的正确状态应满足:
/ -> ext4 硬盘分区,例如 /dev/nvme0n1p2
/boot/efi -> FAT32 EFI 分区,例如 /dev/nvme0n1p1
根文件系统不是 overlay
/etc/mkinitcpio.conf 中不再包含 archlive
硬盘 initramfs 中不再包含 archlive hook
EFI fallback loader 存在:/boot/efi/EFI/BOOT/BOOTAA64.EFI
mkdir -p /root/arch-arm64-iso/{work,iso,out,grub}
cd /root/arch-arm64-iso
建议工程结构最终保持为:
/root/arch-arm64-iso/
├── work/
│ └── rootfs/
├── iso/
│ ├── boot/
│ ├── arch/aarch64/
│ ├── EFI/BOOT/
│ └── efiboot.img
├── grub/
│ └── grub.cfg
└── out/
apt update
apt install -y \
wget curl ca-certificates \
xorriso squashfs-tools \
grub-efi-arm64-bin grub-common \
dosfstools mtools \
rsync parted gdisk \
util-linux
说明:本工程没有直接依赖 Arch 官方
archiso完成 ARM64 ISO,因为标准 archiso 工作流以 x86_64 为核心。本实验采用“Arch Linux ARM rootfs + 自定义 initramfs hook + 手工 EFI/ISO 结构”的方式。
cd /root/arch-arm64-iso
mkdir -p work/rootfs
wget -O /tmp/ArchLinuxARM-aarch64-latest.tar.gz \
http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz
解压 rootfs:
tar -xpf /tmp/ArchLinuxARM-aarch64-latest.tar.gz \
-C /root/arch-arm64-iso/work/rootfs
检查:
ls -lah /root/arch-arm64-iso/work/rootfs
cat /root/arch-arm64-iso/work/rootfs/etc/os-release
cd /root/arch-arm64-iso
ROOT=/root/arch-arm64-iso/work/rootfs
mountpoint -q "$ROOT/dev" || mount --bind /dev "$ROOT/dev"
mountpoint -q "$ROOT/dev/pts" || mount --bind /dev/pts "$ROOT/dev/pts"
mountpoint -q "$ROOT/proc" || mount -t proc proc "$ROOT/proc"
mountpoint -q "$ROOT/sys" || mount -t sysfs sys "$ROOT/sys"
mountpoint -q "$ROOT/run" || mount --bind /run "$ROOT/run"
cp -L /etc/resolv.conf "$ROOT/etc/resolv.conf"
chroot "$ROOT" /bin/bash
即使 chroot 后提示符仍显示 root@kali,也不能仅凭 hostname 判断环境。应检查:
cat /etc/os-release
findmnt /
pwd
pacman-key --init
pacman-key --populate archlinuxarm
pacman -Sy
安装核心内核与安装器依赖:
pacman -S --needed \
linux-aarch64 \
mkinitcpio \
grub \
efibootmgr \
dosfstools \
e2fsprogs \
util-linux \
rsync \
parted \
gptfdisk \
networkmanager
确认 ARM64 GRUB 模块:
ls /usr/lib/grub/arm64-efi
确认内核:
ls -lh /boot/Image
pacman -Q linux-aarch64
本次实验中内核曾为 7.2.3-2-aarch64-ARCH;Arch Linux ARM 为 rolling release,实际版本可能变化。
Live 模式需要提前具备 KDE,以确保 Try WuKongOS 1.0 Live 可直接进入桌面。
pacman -S --needed \
plasma-desktop \
plasma-workspace \
konsole \
dolphin \
sddm \
networkmanager
systemctl enable NetworkManager
systemctl enable sddm
systemctl set-default graphical.target
本项目采用 root-only KDE 作为实验环境,因此配置 SDDM 允许 UID 0 显示。
mkdir -p /etc/sddm.conf.d
cat > /etc/sddm.conf.d/10-root.conf <<'EOF_SDDM'
[Users]
HideUsers=
HideShells=/sbin/nologin,/usr/bin/nologin,/bin/false
MinimumUid=0
MaximumUid=60000
EOF_SDDM
grep -q '^zh_CN.UTF-8 UTF-8' /etc/locale.gen || \
echo 'zh_CN.UTF-8 UTF-8' >> /etc/locale.gen
grep -q '^en_US.UTF-8 UTF-8' /etc/locale.gen || \
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen
locale-gen
cat > /etc/locale.conf <<'EOF_LOCALE'
LANG=zh_CN.UTF-8
EOF_LOCALE
pacman -S --needed \
fcitx5 \
fcitx5-configtool \
fcitx5-chinese-addons \
fcitx5-qt \
fcitx5-gtk
可选扩展:
pacman -S --needed \
fcitx5-breeze \
fcitx5-pinyin-zhwiki \
fcitx5-lua
配置环境变量:
mkdir -p /etc/environment.d
cat > /etc/environment.d/90-fcitx5.conf <<'EOF_FCITX'
XMODIFIERS=@im=fcitx
GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
SDL_IM_MODULE=fcitx
EOF_FCITX
cat > /etc/profile.d/fcitx5.sh <<'EOF_FCITX_PROFILE'
export XMODIFIERS=@im=fcitx
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export SDL_IM_MODULE=fcitx
EOF_FCITX_PROFILE
chmod 644 /etc/profile.d/fcitx5.sh
为 root KDE 会话设置自动启动:
mkdir -p /root/.config/autostart
cat > /root/.config/autostart/fcitx5.desktop <<'EOF_AUTOSTART'
[Desktop Entry]
Type=Application
Name=Fcitx 5
Exec=fcitx5 -d
Terminal=false
X-KDE-autostart-after=panel
EOF_AUTOSTART
cat > /etc/os-release <<'EOF_OS'
NAME="WuKongOS"
PRETTY_NAME="WuKongOS 1.0"
ID=wukongos
ID_LIKE=arch
VERSION="1.0"
VERSION_ID="1.0"
BUILD_ID=rolling
ANSI_COLOR="38;2;23;147;209"
LOGO=archlinux-logo
EOF_OS
echo 'wukongos' > /etc/hostname
假设背景图片位于 Kali:/root/arch-arm64-iso/assets/wallpaper.jpg。
mkdir -p \
/root/arch-arm64-iso/work/rootfs/usr/share/wallpapers/WuKongOS/contents/images
cp /root/arch-arm64-iso/assets/wallpaper.jpg \
/root/arch-arm64-iso/work/rootfs/usr/share/wallpapers/WuKongOS/contents/images/1920x1080.jpg
cat > /root/arch-arm64-iso/work/rootfs/usr/share/wallpapers/WuKongOS/metadata.json <<'EOF_META'
{
"KPlugin": {
"Id": "WuKongOS",
"Name": "WuKongOS",
"Description": "WuKongOS default wallpaper"
}
}
EOF_META
项目中可同时建立 Plasma 主题目录:
mkdir -p /usr/share/plasma/desktoptheme/wukongos
cat > /etc/xdg/plasmarc <<'EOF_PLASMA'
[Theme]
name=wukongos
EOF_PLASMA
KDE Plasma 的桌面配置会随版本变化,最稳妥的验收方式是在 Live KDE 中实际选择 WuKongOS 壁纸,确认显示正确;若需要固定 root 用户的桌面状态,可保留 /root/.config/ 中由当前 Plasma 版本实际生成的配置。
archlive hook 的职责Live ISO 需要完成:
识别 ISO 光驱
-> 按卷标找到 ARCH_ARM64
-> 挂载 ISO9660
-> 找到 arch/aarch64/airootfs.sfs
-> loop 挂载 SquashFS
-> 创建 tmpfs upper/work
-> 创建 OverlayFS
-> 将 OverlayFS 挂载到 /sysroot
-> switch_root 进入 systemd
mkdir -p /etc/initcpio/install /etc/initcpio/hooks
cat > /etc/initcpio/install/archlive <<'EOF_ARCHLIVE_INSTALL'
#!/usr/bin/env bash
build() {
add_module "loop"
add_module "squashfs"
add_module "overlay"
add_module "iso9660"
add_module "sr_mod"
add_runscript
}
help() {
cat <<HELPEOF
Mount the Arch ARM Live ISO, locate airootfs.sfs,
mount it as SquashFS and create an OverlayFS root filesystem.
HELPEOF
}
EOF_ARCHLIVE_INSTALL
chmod 755 /etc/initcpio/install/archlive
cat > /etc/initcpio/hooks/archlive <<'EOF_ARCHLIVE_RUNTIME'
#!/usr/bin/ash
run_hook() {
mount_handler="archlive_mount_handler"
root="archlive"
}
archlive_mount_handler() {
local newroot="$1"
mkdir -p \
/run/archlive/iso \
/run/archlive/squash \
/run/archlive/cow
local iso_mount="/run/archlive/iso"
local squash_mount="/run/archlive/squash"
local cow_mount="/run/archlive/cow"
local iso_label
iso_label="$(getarg archlive_label=)"
if [ -z "$iso_label" ]; then
iso_label="ARCH_ARM64"
fi
echo "archlive: searching for ISO label: $iso_label"
udevadm settle
local iso_device=""
iso_device="$(blkid -L "$iso_label" 2>/dev/null)"
if [ -z "$iso_device" ]; then
for dev in /dev/sr0 /dev/sr1 /dev/cdrom; do
if [ -b "$dev" ]; then
iso_device="$dev"
break
fi
done
fi
if [ -z "$iso_device" ]; then
echo "archlive: ERROR: Live ISO device not found"
return 1
fi
echo "archlive: ISO device: $iso_device"
mount -t iso9660 -o ro "$iso_device" "$iso_mount"
local sfs="$iso_mount/arch/aarch64/airootfs.sfs"
if [ ! -f "$sfs" ]; then
echo "archlive: ERROR: $sfs not found"
return 1
fi
echo "archlive: mounting SquashFS"
mount -t squashfs -o loop,ro \
"$sfs" \
"$squash_mount"
echo "archlive: creating writable overlay"
mount -t tmpfs tmpfs "$cow_mount"
mkdir -p \
"$cow_mount/upper" \
"$cow_mount/work"
mount -t overlay overlay \
-o lowerdir="$squash_mount",upperdir="$cow_mount/upper",workdir="$cow_mount/work" \
"$newroot"
if [ ! -x "$newroot/sbin/init" ]; then
echo "archlive: ERROR: $newroot/sbin/init not found"
return 1
fi
echo "archlive: Live root mounted successfully"
return 0
}
EOF_ARCHLIVE_RUNTIME
chmod 755 /etc/initcpio/hooks/archlive
Live ISO 使用:
HOOKS=(base udev modconf block archlive filesystems keyboard)
sed -i 's/^HOOKS=.*/HOOKS=(base udev modconf block archlive filesystems keyboard)/' \
/etc/mkinitcpio.conf
mkinitcpio -P
ls -lh /boot/Image /boot/initramfs-linux.img
lsinitcpio /boot/initramfs-linux.img | grep archlive
lsinitcpio是 Arch/mkinitcpio 工具。Kali 宿主机检查时应调用 rootfs 中的二进制:
chroot /root/arch-arm64-iso/work/rootfs \
/usr/bin/lsinitcpio /boot/initramfs-linux.img \
| grep archlive
exit
ROOT=/root/arch-arm64-iso/work/rootfs
while mountpoint -q "$ROOT/dev/pts"; do umount "$ROOT/dev/pts" || break; done
while mountpoint -q "$ROOT/dev"; do umount "$ROOT/dev" || break; done
while mountpoint -q "$ROOT/proc"; do umount "$ROOT/proc" || break; done
while mountpoint -q "$ROOT/sys"; do umount "$ROOT/sys" || break; done
while mountpoint -q "$ROOT/run"; do umount "$ROOT/run" || break; done
grep "$ROOT" /proc/self/mountinfo
正确结果:无输出。
cd /root/arch-arm64-iso
mkdir -p \
iso/boot \
iso/arch/aarch64 \
iso/EFI/BOOT
cp -v work/rootfs/boot/Image iso/boot/Image
cp -v work/rootfs/boot/initramfs-linux.img iso/boot/initramfs-linux.img
airootfs.sfsrm -f iso/arch/aarch64/airootfs.sfs
mksquashfs \
work/rootfs \
iso/arch/aarch64/airootfs.sfs \
-comp gzip \
-wildcards \
-e 'proc/*' 'sys/*' 'dev/*' 'run/*'
必须使用 -comp gzip。
早期测试中,使用 zstd 后发生:
mount: /tmp/squash: fsconfig() failed: filesystem uses "zstd" compression. This is not supported.
验证:
unsquashfs -s iso/arch/aarch64/airootfs.sfs
必须看到 Compression gzip。
cd /root/arch-arm64-iso
cat > grub/grub.cfg <<'EOF_GRUB'
set timeout=8
set default=0
insmod part_gpt
insmod part_msdos
insmod iso9660
insmod search
insmod search_label
search --no-floppy --label ARCH_ARM64 --set=root
menuentry "Install WuKongOS 1.0" {
linux /boot/Image archlive_label=ARCH_ARM64 wukong_install=1 rw console=tty0
initrd /boot/initramfs-linux.img
}
menuentry "Try WuKongOS 1.0 Live" {
linux /boot/Image archlive_label=ARCH_ARM64 rw console=tty0
initrd /boot/initramfs-linux.img
}
menuentry "WuKongOS 1.0 Live Debug" {
linux /boot/Image archlive_label=ARCH_ARM64 rw console=tty0 break=premount
initrd /boot/initramfs-linux.img
}
EOF_GRUB
cat grub/grub.cfg
ARCH_ARM64 不能随意改名,因为 GRUB 和 archlive hook 都使用该卷标定位 ISO。
BOOTAA64.EFIgrub-mkstandalone \
-O arm64-efi \
-o iso/EFI/BOOT/BOOTAA64.EFI \
"boot/grub/grub.cfg=grub/grub.cfg"
file iso/EFI/BOOT/BOOTAA64.EFI
应为 ARM64 EFI application。
最终验证通过的是 24 MiB FAT16 efiboot.img。
umount /mnt/wukong-efi 2>/dev/null || true
rm -f iso/efiboot.img
dd if=/dev/zero of=iso/efiboot.img bs=1M count=24
mkfs.vfat -F 16 iso/efiboot.img
mkdir -p /mnt/wukong-efi
mount -o loop iso/efiboot.img /mnt/wukong-efi
mkdir -p /mnt/wukong-efi/EFI/BOOT
cp -v \
iso/EFI/BOOT/BOOTAA64.EFI \
/mnt/wukong-efi/EFI/BOOT/BOOTAA64.EFI
sync
find /mnt/wukong-efi -maxdepth 4 -type f -print
file /mnt/wukong-efi/EFI/BOOT/BOOTAA64.EFI
sha256sum \
iso/EFI/BOOT/BOOTAA64.EFI \
/mnt/wukong-efi/EFI/BOOT/BOOTAA64.EFI
umount /mnt/wukong-efi
早期 64 MiB EFI 镜像曾出现内容未正确写入,VMware 报 No compatible bootloader found;因此后续固定保留已验证的 24 MiB FAT16 镜像。
wukong-installer.servicecd /root/arch-arm64-iso
mkdir -p work/rootfs/etc/systemd/system
cat > work/rootfs/etc/systemd/system/wukong-installer.service <<'EOF_SERVICE'
[Unit]
Description=WuKongOS 1.0 Installer
Wants=systemd-udev-settle.service NetworkManager.service
After=local-fs.target systemd-udev-settle.service NetworkManager.service
Conflicts=display-manager.service getty@tty1.service
[Service]
Type=idle
ExecStart=/usr/local/bin/wukong-install
StandardInput=tty
StandardOutput=tty
StandardError=tty
TTYPath=/dev/tty1
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=no
Restart=no
TimeoutStartSec=infinity
[Install]
WantedBy=multi-user.target
EOF_SERVICE
chmod 644 work/rootfs/etc/systemd/system/wukong-installer.service
wukong-installer-generatormkdir -p work/rootfs/usr/lib/systemd/system-generators
cat > work/rootfs/usr/lib/systemd/system-generators/wukong-installer-generator <<'EOF_GENERATOR'
#!/bin/sh
GENERATOR_DIR="$1"
if grep -qw 'wukong_install=1' /proc/cmdline; then
echo "WuKongOS: installer mode detected" > /dev/kmsg 2>/dev/null || true
mkdir -p "$GENERATOR_DIR/multi-user.target.wants"
ln -sf \
/etc/systemd/system/wukong-installer.service \
"$GENERATOR_DIR/multi-user.target.wants/wukong-installer.service"
ln -sf \
/usr/lib/systemd/system/multi-user.target \
"$GENERATOR_DIR/default.target"
fi
exit 0
EOF_GENERATOR
chmod 755 \
work/rootfs/usr/lib/systemd/system-generators/wukong-installer-generator
sh -n work/rootfs/usr/lib/systemd/system-generators/wukong-installer-generator
用户只需要在 Live Installer 模式运行(实际由 systemd 自动运行):
/usr/local/bin/wukong-install
脚本先在 Live WuKongOS 中运行,挂载目标硬盘后再自动:
chroot "$TARGET" /bin/bash <<'CHROOT'
...
CHROOT
因此 pacman 安装 KDE、Fcitx5、中文 locale、GRUB 等命令是在目标硬盘 WuKongOS chroot 中由脚本自动执行,不需要用户手工进入 chroot。
安装器所有交互提示使用英文,以避免安装 tty 阶段中文字体/locale 未完整加载导致乱码;安装后的系统仍设置为中文。
wukong-install这个脚本,我测试了,有一个bug,进入安装器的时候,选择硬盘设备,需要手动输入完整的设备路径,例如:/dev/nvme0n1,如果输入错误,就会卡死,需要重启虚拟机,然后再次选择“WuKongOS 1.0 Installer”,从新输入dev设备.....我熬了7个小时调试通.懒得改了,各位林北自己改吧.
cd /root/arch-arm64-iso
cat > work/rootfs/usr/local/bin/wukong-install <<'EOF_INSTALLER'
#!/usr/bin/env bash
set -Eeuo pipefail
TARGET="/mnt/wukong-target"
SOURCE="/run/archlive/squash/"
cleanup() {
sync 2>/dev/null || true
umount "$TARGET/run" 2>/dev/null || true
umount "$TARGET/sys" 2>/dev/null || true
umount "$TARGET/proc" 2>/dev/null || true
umount "$TARGET/dev/pts" 2>/dev/null || true
umount "$TARGET/dev" 2>/dev/null || true
umount "$TARGET/boot/efi" 2>/dev/null || true
umount "$TARGET" 2>/dev/null || true
}
fail() {
echo
echo "========================================"
echo "WuKongOS installation failed"
echo "========================================"
echo
echo "$1"
echo
exit 1
}
trap cleanup EXIT
clear
echo "========================================"
echo " WuKongOS 1.0 Installer"
echo "========================================"
echo
echo "The installer will perform the following:"
echo
echo " 1. Create a GPT partition table"
echo " 2. Create an EFI System Partition"
echo " 3. Create an ext4 root partition"
echo " 4. Install the WuKongOS base system"
echo " 5. Install KDE Plasma"
echo " 6. Install the Fcitx5 Chinese input method"
echo " 7. Configure the Chinese system locale"
echo " 8. Install ARM64 UEFI GRUB"
echo " 9. Enable SDDM and NetworkManager"
echo
echo "WARNING: All data on the target disk will be erased."
echo
if [ "$(id -u)" -ne 0 ]; then
fail "The installer must be run as root."
fi
if ! mountpoint -q /run/archlive/squash; then
fail "/run/archlive/squash was not found. Boot from the WuKongOS Installer ISO."
fi
echo
echo "[Preparation] Starting NetworkManager..."
systemctl start NetworkManager 2>/dev/null || true
sleep 2
echo
echo "Current network interfaces:"
ip -br addr || true
echo
echo "Checking network connectivity..."
NETWORK_OK=0
for i in $(seq 1 20); do
if getent hosts mirror.archlinuxarm.org >/dev/null 2>&1; then
NETWORK_OK=1
break
fi
sleep 1
done
if [ "$NETWORK_OK" -ne 1 ]; then
echo
echo "WARNING: No working network connection was detected."
echo
echo "KDE and the Chinese input method are installed using pacman,"
echo "so this installation mode requires a network connection."
echo
read -rp "Continue installing the base system anyway? Type YES to continue: " NET_CONFIRM
if [ "$NET_CONFIRM" != "YES" ]; then
exit 1
fi
fi
echo
echo "========================================"
echo "Available disks"
echo "========================================"
echo
lsblk -d -o NAME,SIZE,MODEL,TRAN,TYPE
echo
read -rp "Enter the target disk, for example /dev/nvme0n1: " DISK
if [ ! -b "$DISK" ]; then
fail "Target disk $DISK does not exist."
fi
DISK_TYPE="$(lsblk -dn -o TYPE "$DISK")"
if [ "$DISK_TYPE" != "disk" ]; then
fail "$DISK is not a disk device."
fi
case "$DISK" in
/dev/sr*|/dev/loop*)
fail "Installation to a CD-ROM or loop device is not allowed."
;;
esac
echo
echo "Selected target disk:"
echo
lsblk -o NAME,SIZE,FSTYPE,LABEL,MOUNTPOINTS "$DISK"
echo
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "Target disk: $DISK"
echo "ALL DATA ON THIS DISK WILL BE ERASED."
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo
read -rp "Type YES to erase the entire disk and continue: " CONFIRM
if [ "$CONFIRM" != "YES" ]; then
echo
echo "Installation cancelled."
exit 0
fi
echo
echo "[1/15] Unmounting existing target disk partitions..."
while read -r PART; do
[ "$PART" = "$DISK" ] && continue
umount "$PART" 2>/dev/null || true
done < <(lsblk -lnpo NAME "$DISK")
echo
echo "[2/15] Removing old filesystems and partition table..."
wipefs -a "$DISK"
echo
echo "[3/15] Creating GPT partition table..."
parted -s "$DISK" mklabel gpt
parted -s "$DISK" mkpart ESP fat32 1MiB 513MiB
parted -s "$DISK" set 1 esp on
parted -s "$DISK" mkpart ROOT ext4 513MiB 100%
partprobe "$DISK"
udevadm settle
if [[ "$DISK" == *nvme* || "$DISK" == *mmcblk* ]]; then
EFI_PART="${DISK}p1"
ROOT_PART="${DISK}p2"
else
EFI_PART="${DISK}1"
ROOT_PART="${DISK}2"
fi
if [ ! -b "$EFI_PART" ]; then
fail "Failed to create EFI partition $EFI_PART."
fi
if [ ! -b "$ROOT_PART" ]; then
fail "Failed to create ROOT partition $ROOT_PART."
fi
echo
echo "EFI partition : $EFI_PART"
echo "ROOT partition: $ROOT_PART"
echo
echo "[4/15] Formatting EFI partition..."
mkfs.fat -F32 -n WUKONG_EFI "$EFI_PART"
echo
echo "[5/15] Formatting ROOT partition..."
mkfs.ext4 -F -L WUKONG_ROOT "$ROOT_PART"
echo
echo "[6/15] Mounting target system..."
mkdir -p "$TARGET"
mount "$ROOT_PART" "$TARGET"
mkdir -p "$TARGET/boot/efi"
mount "$EFI_PART" "$TARGET/boot/efi"
echo
echo "ROOT:"
findmnt "$TARGET"
echo
echo "EFI:"
findmnt "$TARGET/boot/efi"
echo
echo "[7/15] Installing WuKongOS base system..."
rsync \
-aHAX \
--numeric-ids \
--info=progress2 \
--exclude='/dev/*' \
--exclude='/proc/*' \
--exclude='/sys/*' \
--exclude='/run/*' \
--exclude='/tmp/*' \
--exclude='/mnt/*' \
--exclude='/media/*' \
--exclude='/lost+found' \
"$SOURCE" \
"$TARGET/"
echo
echo "[8/15] Creating system directories..."
mkdir -p \
"$TARGET/dev/pts" \
"$TARGET/proc" \
"$TARGET/sys" \
"$TARGET/run" \
"$TARGET/tmp" \
"$TARGET/boot/efi"
chmod 1777 "$TARGET/tmp"
echo
echo "[9/15] Creating /etc/fstab..."
ROOT_UUID="$(blkid -s UUID -o value "$ROOT_PART")"
EFI_UUID="$(blkid -s UUID -o value "$EFI_PART")"
cat > "$TARGET/etc/fstab" <<FSTAB
# /etc/fstab
# Generated by WuKongOS Installer
UUID=$ROOT_UUID / ext4 defaults,noatime 0 1
UUID=$EFI_UUID /boot/efi vfat umask=0077 0 2
FSTAB
cat "$TARGET/etc/fstab"
echo
echo "[10/15] Preparing target system chroot..."
mount --bind /dev "$TARGET/dev"
mount --bind /dev/pts "$TARGET/dev/pts"
mount -t proc proc "$TARGET/proc"
mount -t sysfs sysfs "$TARGET/sys"
mount --bind /run "$TARGET/run"
rm -f "$TARGET/etc/resolv.conf"
cp -L /etc/resolv.conf "$TARGET/etc/resolv.conf"
echo
echo "[11/15] Configuring installed WuKongOS..."
echo
echo "The following operations will run inside the target disk system."
chroot "$TARGET" /bin/bash <<'CHROOT'
set -Eeuo pipefail
echo
echo "========================================"
echo "Configuring installed WuKongOS"
echo "========================================"
echo
echo "[A] Checking target system network..."
if ! getent hosts mirror.archlinuxarm.org >/dev/null 2>&1; then
echo
echo "ERROR: The target system cannot resolve the Arch Linux ARM mirror."
echo
echo "Check the network connection and run the installation again."
exit 1
fi
echo
echo "[B] Refreshing Arch Linux ARM package database..."
pacman -Sy --noconfirm
echo
echo "[C] Installing KDE Plasma..."
pacman -S --needed --noconfirm \
plasma-desktop \
plasma-workspace \
konsole \
dolphin \
sddm
echo
echo "[D] Installing NetworkManager..."
pacman -S --needed --noconfirm networkmanager
echo
echo "[E] Installing Fcitx5 Chinese input method..."
pacman -S --needed --noconfirm \
fcitx5 \
fcitx5-configtool \
fcitx5-chinese-addons \
fcitx5-qt \
fcitx5-gtk
echo
echo "[F] Configuring Chinese system locale..."
if grep -q '^#zh_CN.UTF-8 UTF-8' /etc/locale.gen; then
sed -i 's/^#zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen
fi
if grep -q '^#en_US.UTF-8 UTF-8' /etc/locale.gen; then
sed -i 's/^#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
fi
grep -q '^zh_CN.UTF-8 UTF-8' /etc/locale.gen || \
echo 'zh_CN.UTF-8 UTF-8' >> /etc/locale.gen
grep -q '^en_US.UTF-8 UTF-8' /etc/locale.gen || \
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen
locale-gen
cat > /etc/locale.conf <<'EOF_LOCALE'
LANG=zh_CN.UTF-8
EOF_LOCALE
echo
echo "[G] Configuring Fcitx5..."
mkdir -p /etc/environment.d
cat > /etc/environment.d/90-fcitx5.conf <<'EOF_FCITX'
XMODIFIERS=@im=fcitx
GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
SDL_IM_MODULE=fcitx
EOF_FCITX
cat > /etc/profile.d/fcitx5.sh <<'EOF_PROFILE'
export XMODIFIERS=@im=fcitx
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export SDL_IM_MODULE=fcitx
EOF_PROFILE
chmod 644 /etc/profile.d/fcitx5.sh
mkdir -p /root/.config/autostart
cat > /root/.config/autostart/fcitx5.desktop <<'EOF_AUTOSTART'
[Desktop Entry]
Type=Application
Name=Fcitx 5
Exec=fcitx5 -d
Terminal=false
X-KDE-autostart-after=panel
EOF_AUTOSTART
echo
echo "[H] Setting hostname..."
echo "wukongos" > /etc/hostname
echo
echo "[I] Removing Live-only archlive..."
if grep -q archlive /etc/mkinitcpio.conf; then
sed -i 's/[[:space:]]archlive[[:space:]]/ /g' /etc/mkinitcpio.conf
fi
rm -f /etc/initcpio/install/archlive /etc/initcpio/hooks/archlive
echo
echo "Installed system mkinitcpio HOOKS:"
grep '^HOOKS=' /etc/mkinitcpio.conf
echo
echo "[J] Generating installed-system initramfs..."
mkinitcpio -P
echo
echo "[K] Installing ARM64 UEFI GRUB..."
mkdir -p /boot/grub
findmnt /boot/efi
grub-install \
--target=arm64-efi \
--efi-directory=/boot/efi \
--bootloader-id=WuKongOS \
--removable \
--no-nvram \
--recheck
echo
echo "[L] Generating grub.cfg..."
grub-mkconfig -o /boot/grub/grub.cfg
echo
echo "[M] Enabling KDE / NetworkManager..."
systemctl enable NetworkManager
systemctl enable sddm
systemctl set-default graphical.target
echo
echo "[N] Checking installation result..."
if grep -q archlive /etc/mkinitcpio.conf; then
echo "ERROR: mkinitcpio.conf still contains archlive."
exit 1
fi
if [ ! -f /boot/Image ]; then
echo "ERROR: /boot/Image does not exist."
exit 1
fi
if [ ! -f /boot/initramfs-linux.img ]; then
echo "ERROR: initramfs does not exist."
exit 1
fi
if [ ! -f /boot/efi/EFI/BOOT/BOOTAA64.EFI ]; then
echo "ERROR: EFI/BOOT/BOOTAA64.EFI does not exist."
exit 1
fi
if [ ! -f /boot/grub/grub.cfg ]; then
echo "ERROR: grub.cfg does not exist."
exit 1
fi
echo
echo "Installed system configuration completed."
CHROOT
echo
echo "[12/15] Verifying installed system..."
echo
echo "EFI Bootloader:"
ls -lh "$TARGET/boot/efi/EFI/BOOT/BOOTAA64.EFI"
echo
echo "Kernel:"
ls -lh "$TARGET/boot/Image"
echo
echo "Initramfs:"
ls -lh "$TARGET/boot/initramfs-linux.img"
echo
echo "GRUB:"
ls -lh "$TARGET/boot/grub/grub.cfg"
echo
echo "fstab:"
cat "$TARGET/etc/fstab"
echo
echo "locale:"
cat "$TARGET/etc/locale.conf"
echo
echo "Checking for archlive..."
if grep -q archlive "$TARGET/etc/mkinitcpio.conf"; then
fail "The installed system still contains archlive."
fi
echo
echo "[13/15] Checking KDE and Fcitx5..."
if ! chroot "$TARGET" pacman -Q plasma-desktop >/dev/null 2>&1; then
fail "KDE plasma-desktop was not installed correctly."
fi
if ! chroot "$TARGET" pacman -Q sddm >/dev/null 2>&1; then
fail "SDDM was not installed correctly."
fi
if ! chroot "$TARGET" pacman -Q fcitx5 >/dev/null 2>&1; then
fail "Fcitx5 was not installed correctly."
fi
if ! chroot "$TARGET" pacman -Q fcitx5-chinese-addons >/dev/null 2>&1; then
fail "Fcitx5 Chinese components were not installed correctly."
fi
echo
echo "KDE / Fcitx5 checks passed."
echo
echo "[14/15] Writing data to disk..."
sync
echo
echo "[15/15] Unmounting installation target..."
trap - EXIT
cleanup
echo
echo "========================================"
echo " WuKongOS 1.0 Installation Complete"
echo "========================================"
echo
echo "Installed components:"
echo
echo " WuKongOS base system"
echo " KDE Plasma"
echo " SDDM"
echo " NetworkManager"
echo " Fcitx5"
echo " Fcitx5 Chinese input method"
echo " zh_CN.UTF-8 Chinese locale"
echo " ARM64 UEFI GRUB"
echo
echo "The target system has been written to disk."
echo
echo "Now disconnect the installation ISO in VMware Fusion:"
echo
echo " CD/DVD -> Disconnect"
echo
read -rp "After disconnecting the CD-ROM, press Enter to reboot..."
sync
systemctl reboot
EOF_INSTALLER
chmod 755 work/rootfs/usr/local/bin/wukong-install
bash -n work/rootfs/usr/local/bin/wukong-install
检查安装器汉字残留:
LC_ALL=C.UTF-8 \
grep -nP '[\x{4e00}-\x{9fff}]' \
work/rootfs/usr/local/bin/wukong-install
正确结果:无输出。
cd /root/arch-arm64-iso
ls -lh \
work/rootfs/usr/local/bin/wukong-install \
work/rootfs/etc/systemd/system/wukong-installer.service \
work/rootfs/usr/lib/systemd/system-generators/wukong-installer-generator
应看到安装脚本与 generator 为可执行权限,service 为普通只读配置文件。
archlivegrep '^HOOKS=' work/rootfs/etc/mkinitcpio.conf
ls -lh \
work/rootfs/etc/initcpio/install/archlive \
work/rootfs/etc/initcpio/hooks/archlive
构建 rootfs 中必须保留 archlive。仅安装到硬盘后的目标副本删除它。
chroot /root/arch-arm64-iso/work/rootfs \
/usr/bin/lsinitcpio /boot/initramfs-linux.img \
| grep archlive
必须有输出。
ROOT=/root/arch-arm64-iso/work/rootfs
while mountpoint -q "$ROOT/dev/pts"; do umount "$ROOT/dev/pts" || break; done
while mountpoint -q "$ROOT/dev"; do umount "$ROOT/dev" || break; done
while mountpoint -q "$ROOT/proc"; do umount "$ROOT/proc" || break; done
while mountpoint -q "$ROOT/sys"; do umount "$ROOT/sys" || break; done
while mountpoint -q "$ROOT/run"; do umount "$ROOT/run" || break; done
grep "$ROOT" /proc/self/mountinfo
目标:无输出。
cd /root/arch-arm64-iso
rm -f iso/arch/aarch64/airootfs.sfs
mksquashfs \
work/rootfs \
iso/arch/aarch64/airootfs.sfs \
-comp gzip \
-wildcards \
-e 'proc/*' 'sys/*' 'dev/*' 'run/*'
验证:
unsquashfs -s iso/arch/aarch64/airootfs.sfs
unsquashfs -ll \
iso/arch/aarch64/airootfs.sfs \
| grep -E \
'wukong-install|wukong-installer.service|wukong-installer-generator'
如果 grub/grub.cfg 有任何变化,必须重新生成。
cd /root/arch-arm64-iso
grub-mkstandalone \
-O arm64-efi \
-o iso/EFI/BOOT/BOOTAA64.EFI \
"boot/grub/grub.cfg=grub/grub.cfg"
file iso/EFI/BOOT/BOOTAA64.EFI
更新 EFI image:
mkdir -p /mnt/wukong-efi
mount -o loop iso/efiboot.img /mnt/wukong-efi
cp -v \
iso/EFI/BOOT/BOOTAA64.EFI \
/mnt/wukong-efi/EFI/BOOT/BOOTAA64.EFI
sync
sha256sum \
iso/EFI/BOOT/BOOTAA64.EFI \
/mnt/wukong-efi/EFI/BOOT/BOOTAA64.EFI
umount /mnt/wukong-efi
cd /root/arch-arm64-iso
mkdir -p out
rm -f out/WuKongOS-1.0-arm64-Installer.iso
xorriso \
-as mkisofs \
-iso-level 3 \
-full-iso9660-filenames \
-volid ARCH_ARM64 \
-eltorito-alt-boot \
-e efiboot.img \
-no-emul-boot \
-output out/WuKongOS-1.0-arm64-Installer.iso \
iso/
ls -lh out/WuKongOS-1.0-arm64-Installer.iso
xorriso \
-indev out/WuKongOS-1.0-arm64-Installer.iso \
-toc
Volume ID 必须是 ARCH_ARM64。
mkdir -p /mnt/wukong-iso
mount -o loop,ro \
out/WuKongOS-1.0-arm64-Installer.iso \
/mnt/wukong-iso
find /mnt/wukong-iso -maxdepth 4 -type f -print
应至少包含:
/boot/Image
/boot/initramfs-linux.img
/arch/aarch64/airootfs.sfs
/EFI/BOOT/BOOTAA64.EFI
/efiboot.img
检查 Installer 文件:
unsquashfs -ll \
/mnt/wukong-iso/arch/aarch64/airootfs.sfs \
| grep -E \
'wukong-install|wukong-installer.service|wukong-installer-generator'
检查英文安装器:
unsquashfs -cat \
/mnt/wukong-iso/arch/aarch64/airootfs.sfs \
usr/local/bin/wukong-install \
| LC_ALL=C.UTF-8 grep -nP '[\x{4e00}-\x{9fff}]'
最后:
umount /mnt/wukong-iso
建议:
CPU:4 核
RAM:8 GiB
Firmware:ARM64 UEFI
磁盘:64 GiB 空白虚拟磁盘
CD/DVD:WuKongOS-1.0-arm64-Installer.iso
严禁在 Kali 构建系统自己的 /dev/nvme0n1 上测试安装器。本项目的 Kali 宿主磁盘曾为:
nvme0n1
├─nvme0n1p1
├─nvme0n1p2 vfat /boot/efi
├─nvme0n1p3 ext4 /
└─nvme0n1p4 swap
因此破坏性安装测试必须在新建 VM 的空白虚拟磁盘中完成。
启动后应出现:
Install WuKongOS 1.0
Try WuKongOS 1.0 Live
WuKongOS 1.0 Live Debug
选择 Try WuKongOS 1.0 Live。
预期链路:
UEFI
-> GRUB
-> Kernel
-> initramfs
-> archlive
-> ISO9660
-> airootfs.sfs
-> SquashFS
-> OverlayFS
-> switch_root
-> systemd
-> SDDM
-> KDE
findmnt /
findmnt /run/archlive/squash
cat /etc/locale.conf
pacman -Q fcitx5 fcitx5-chinese-addons fcitx5-qt fcitx5-gtk
Live 根文件系统应为 overlay。
选择 WuKongOS 1.0 Live Debug。
在 premount shell 中可检查:
cat /proc/cmdline
blkid
ls -l /dev/sr*
lsmod | grep -E 'squashfs|overlay|iso9660|sr_mod|loop'
选择:
Install WuKongOS 1.0
GRUB 传入:
wukong_install=1
systemd generator 应自动启动 wukong-install,不进入 KDE。
若虚拟硬盘是 /dev/nvme0n1,输入:
/dev/nvme0n1
随后确认:
YES
安装器自动完成:
GPT
-> 512 MiB FAT32 ESP
-> ext4 ROOT
-> rsync 基础系统
-> fstab
-> chroot 硬盘系统
-> pacman 安装 KDE
-> pacman 安装 NetworkManager
-> pacman 安装 Fcitx5
-> 设置 zh_CN.UTF-8
-> 删除 archlive
-> mkinitcpio -P
-> grub-install --removable --no-nvram
-> grub-mkconfig
-> enable SDDM / NetworkManager
efibootmgr 故障与最终 GRUB 方案早期安装失败信息:
grub-install: efibootmgr 无法注册启动项: 没有那个文件或目录
原因是普通 grub-install 尝试通过 efibootmgr 写 UEFI NVRAM,但 VMware Live/chroot 环境中 EFI variables 可能不可用或不可写。
最终采用:
grub-install \
--target=arm64-efi \
--efi-directory=/boot/efi \
--bootloader-id=WuKongOS \
--removable \
--no-nvram \
--recheck
grub-mkconfig -o /boot/grub/grub.cfg
生成:
/boot/efi/EFI/BOOT/BOOTAA64.EFI
该方式使用 UEFI 标准 fallback 路径,不需要 NVRAM 注册。
安装器最后提示断开 CD/DVD。
CD/DVD -> Disconnect
按 Enter,安装器执行:
systemctl reboot
findmnt /
应为硬盘 ext4,例如 /dev/nvme0n1p2,不能是 overlay。
findmnt /boot/efi
ls -lh /boot/efi/EFI/BOOT/BOOTAA64.EFI
lsblk -f
预期:
nvme0n1
├─nvme0n1p1 vfat FAT32 WUKONG_EFI /boot/efi
└─nvme0n1p2 ext4 WUKONG_ROOT /
archlivegrep '^HOOKS=' /etc/mkinitcpio.conf
lsinitcpio /boot/initramfs-linux.img | grep archlive
第二条正确结果为无输出。
pacman -Q \
plasma-desktop \
plasma-workspace \
sddm \
networkmanager
systemctl get-default
systemctl is-enabled sddm
systemctl is-enabled NetworkManager
应为 graphical.target、enabled、enabled。
cat /etc/locale.conf
locale
应看到:
LANG=zh_CN.UTF-8
pacman -Q \
fcitx5 \
fcitx5-configtool \
fcitx5-chinese-addons \
fcitx5-qt \
fcitx5-gtk
cat /etc/environment.d/90-fcitx5.conf
cat /etc/profile.d/fcitx5.sh
cat /root/.config/autostart/fcitx5.desktop
pgrep -a fcitx5
解决架构:
ArchLinuxARM-aarch64 rootfs
+ linux-aarch64
+ 自定义 archlive hook
+ SquashFS
+ grub-mkstandalone -O arm64-efi
+ FAT EFI El Torito image
+ xorriso
错误:
filesystem uses "zstd" compression. This is not supported.
解决:始终 -comp gzip。
No compatible bootloader found原因:EFI image 内没有正确的 EFI/BOOT/BOOTAA64.EFI。
解决:使用已验证 24 MiB FAT16 efiboot.img,挂载后复制文件并用 SHA256 校验。
efibootmgr 无法注册启动项解决:硬盘安装阶段使用:
--removable --no-nvram
写入标准 fallback loader。
构建 ISO 的 work/rootfs:
必须保留 archlive
安装到硬盘后的目标系统:
必须删除 archlive
必须重新 mkinitcpio -P
lsinitcpio正确检查方法:
chroot /root/arch-arm64-iso/work/rootfs \
/usr/bin/lsinitcpio /boot/initramfs-linux.img
重复 chroot 未清理可能影响 SquashFS。每次构建前使用循环卸载并确认 /proc/self/mountinfo 中无 rootfs 子挂载。
例如修改:
wukong-install
systemd service
generator
KDE 配置
背景
Fcitx5 配置
需要:
重新 mksquashfs
-> 重新 xorriso
若 GRUB 未变,EFI 可以不变;为避免版本混淆,发布版本可统一完整重建 EFI。
必须:
mksquashfs(若 rootfs 也有变化)
-> grub-mkstandalone
-> 更新 efiboot.img 内 BOOTAA64.EFI
-> xorriso
mkinitcpio -P
cp -v work/rootfs/boot/Image iso/boot/Image
cp -v work/rootfs/boot/initramfs-linux.img iso/boot/initramfs-linux.img
之后重新 SquashFS 与 ISO。
cd /root/arch-arm64-iso
ROOT=/root/arch-arm64-iso/work/rootfs
while mountpoint -q "$ROOT/dev/pts"; do umount "$ROOT/dev/pts" || break; done
while mountpoint -q "$ROOT/dev"; do umount "$ROOT/dev" || break; done
while mountpoint -q "$ROOT/proc"; do umount "$ROOT/proc" || break; done
while mountpoint -q "$ROOT/sys"; do umount "$ROOT/sys" || break; done
while mountpoint -q "$ROOT/run"; do umount "$ROOT/run" || break; done
rm -f iso/arch/aarch64/airootfs.sfs
mksquashfs \
work/rootfs \
iso/arch/aarch64/airootfs.sfs \
-comp gzip \
-wildcards \
-e 'proc/*' 'sys/*' 'dev/*' 'run/*'
grub-mkstandalone \
-O arm64-efi \
-o iso/EFI/BOOT/BOOTAA64.EFI \
"boot/grub/grub.cfg=grub/grub.cfg"
mkdir -p /mnt/wukong-efi
mount -o loop iso/efiboot.img /mnt/wukong-efi
cp -v iso/EFI/BOOT/BOOTAA64.EFI \
/mnt/wukong-efi/EFI/BOOT/BOOTAA64.EFI
sync
umount /mnt/wukong-efi
mkdir -p out
rm -f out/WuKongOS-1.0-arm64-Installer.iso
xorriso \
-as mkisofs \
-iso-level 3 \
-full-iso9660-filenames \
-volid ARCH_ARM64 \
-eltorito-alt-boot \
-e efiboot.img \
-no-emul-boot \
-output out/WuKongOS-1.0-arm64-Installer.iso \
iso/