# x-kernel-image **Repository Path**: openkylin/x-kernel-image ## Basic Information - **Project Name**: x-kernel-image - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-02 - **Last Updated**: 2026-07-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # x-kernel-image 为 X-Kernel 构建根文件系统镜像,供内核仓库 `make rootfs` 使用。 提供 Alpine 和 Debian 两类 rootfs,命名格式:`x-kernel-{distro}-{init}-{arch}[-{variant}].img.xz` | 类型 | C 库 | 包管理器 | Init | 产出文件 | |------|------|----------|------|----------| | Alpine | musl | apk | busybox | `x-kernel-alpine-busybox-.img.xz` | | Alpine CI | musl | apk | busybox | `x-kernel-alpine-busybox--ci.img.xz` | | Alpine OpenRC | musl | apk | openrc | `x-kernel-alpine-openrc-.img.xz` | | Debian | glibc | apt/dpkg | busybox | `x-kernel-debian-busybox-.img.xz` | | Debian | glibc | apt/dpkg | systemd | `x-kernel-debian-systemd-.img.xz` | ## Alpine rootfs (musl) 依赖:`curl`、`xz`、`fallocate`、`mkfs.ext4`、`fsck.ext4`;需 root 权限。 安装 profile 包时优先使用 host `apk-tools`;如果 host `apk` 不存在或不可用, 会从配置的 Alpine 镜像源下载 `apk-tools-static` 作为 fallback;如果下载失败, 再尝试使用 Docker 中的 Alpine `apk`。 ```sh sudo make all # 默认 aarch64,生成 x-kernel-alpine-busybox-aarch64.img.xz sudo make all ARCH=riscv64 # 指定架构 sudo make all ARCH=x86_64 PROFILE=ci # 生成 x-kernel-alpine-busybox-x86_64-ci.img.xz sudo make all4 # 构建四个架构(aarch64 / riscv64 / x86_64 / loongarch64) make clean # 清理产物 ``` 变量在 `config.mk`(`ARCH`、`PROFILE`、`IMG_SIZE`、`BASE`、`REL`),可命令行覆盖。 ### Alpine profiles `PROFILE=base` 是默认值,使用 Alpine minirootfs、仓库内的 `etc/` overlay,并安装 基础磁盘查看/维护工具。包列表维护在 `profiles/base.packages`,当前包含: - `util-linux`:提供 `lsblk`、`blkid`、`fdisk`、`findmnt`、`blockdev` 等块设备工具。 - `e2fsprogs`、`e2fsprogs-extra`:提供 `e2fsck`、`dumpe2fs`、`debugfs`、`tune2fs`、`resize2fs` 等 ext 文件系统工具。 - `parted`:分区表查看和维护工具。 - `smartmontools`:磁盘 SMART 状态查看工具。 - `nvme-cli`:NVMe 设备状态查看工具。 `PROFILE=ci` 生成 CI 镜像,用于 pjdfstest、LTP 子集等测试运行时。包列表维护在 `profiles/ci.packages`,当前包含: - `perl`、`perl-utils`、`perl-test-harness`:运行 pjdfstest 原版 Perl/TAP 测试。 - `bash`、`coreutils`、`findutils`、`grep`、`sed`:复杂 shell 测试的基础工具。 - `openssl`:pjdfstest 原版 `misc.sh` 使用 `openssl md5` 生成随机文件名。 - `e2fsprogs`:ext4 镜像检查工具。 - `strace`:调试 syscall 行为。 新增 profile 时只需要增加 `profiles/.packages`,并使用 `sudo make all PROFILE= ARCH=` 构建。 CI profile 构建完成后可检查镜像内容: ```sh sudo mount x-kernel-alpine-busybox-aarch64-ci.img mnt ls mnt/usr/bin/perl mnt/usr/bin/prove mnt/usr/bin/openssl mnt/sbin/e2fsck sudo umount mnt ``` 如果 host 与目标架构一致,也可以进一步用 `chroot` 检查版本;跨架构时交给 QEMU guest 验证。 ## Alpine OpenRC rootfs (musl) 走独立的构建路径:不依赖 Alpine minirootfs 也不走 Makefile 流程,而是用 `apk-tools-static` 在 host 上从零组装 `alpine-base + openrc` 的 rootfs, 再通过 `mkfs.ext4 -d` 打成 ext4 镜像。**不需要 chroot、binfmt_misc**, 也不需要预下载 minirootfs。 脚本本身要 root 跑(`apk-tools-static` 不肯用非 root 身份初始化数据库,且 staging 目录必须是 root 属主,否则最终镜像里文件 uid 不对——`fakeroot` 在这里 帮不上忙,因为 `apk.static` 是静态链接,`LD_PRELOAD` 拦不到)。下面给两种入口。 ### 方式 A:用 Docker(host 上不需要 sudo) 推荐。容器内是 root,apk.static 和 `mkfs.ext4 -d` 都能正常跑;构建完成后 把产物 chown 回 host 用户,避免之后还要 sudo 才能删文件。 ```sh # 一次性构建 aarch64 镜像(产出 target/x-kernel-alpine-openrc-aarch64.img) HOST_UID=$(id -u) HOST_GID=$(id -g) docker run --rm \ -e HOST_UID -e HOST_GID \ -v "$PWD:/work" -w /work alpine:3.23 sh -c ' apk add --no-cache bash curl tar e2fsprogs qemu-aarch64 >/dev/null ./scripts/make_openrc_rootfs.sh -o /work/target/x-kernel-alpine-openrc-aarch64.img chown -R "$HOST_UID:$HOST_GID" /work/target/openrc-rootfs \ /work/target/x-kernel-alpine-openrc-aarch64.img ' ``` 换架构时把 `qemu-aarch64` 换成对应的 `qemu-`(例如 `qemu-riscv64`)。 ### 方式 B:直接 sudo(host 上已有 root 权限) ```sh sudo ./scripts/make_openrc_rootfs.sh # aarch64 -> x-kernel-alpine-openrc-aarch64.img sudo ./scripts/make_openrc_rootfs.sh -a riscv64 # 换架构 sudo ./scripts/make_openrc_rootfs.sh -a x86_64 -s 2048 # 自定义大小 sudo ./scripts/make_openrc_rootfs.sh -o /tmp/x.img # 自定义输出路径 ``` 依赖:`curl`、`tar`、`dd`、`mkfs.ext4`(来自 `e2fsprogs`);**跨架构**时还需要 `qemu-`(仅用于枚举 busybox applets,因为 `--no-scripts` 跳过了 busybox post-install 创建符号链接的步骤)。Docker 方式里这些都装在容器内。 ### 可选参数(`-h` 查看全部) | 参数 | 默认值 | 说明 | |------|--------|------| | `-a, --arch` | `aarch64` | apk 目标架构 | | `-b, --branch` | `v3.23` | Alpine 分支 | | `-m, --mirror` | `https://mirrors.cernet.edu.cn/alpine` | Alpine 镜像源 | | `-s, --size` | `1024` | 镜像大小(MiB) | | `-o, --output` | `x-kernel-alpine-openrc-.img` | 输出路径 | | `-w, --workdir` | `target/openrc-rootfs` | 中间产物目录 | ### 构建后压缩 ```sh xz --threads=0 -k target/x-kernel-alpine-openrc-aarch64.img ``` ### ⚠️ 让 OpenRC 真正起来 x-kernel 默认通过内置的 `entry/src/init.sh` 引导用户态,**不是** `/sbin/init`, 所以脚本写入的 `/etc/inittab` 本身是惰性的,需要把 `entry/src/init.sh` 改成 显式调用 `openrc`,或 `exec /sbin/init`。最小改法: ```sh if [ -x /sbin/openrc ]; then /sbin/openrc sysinit /sbin/openrc boot /sbin/openrc default fi ``` 详见脚本末尾打印的提示。此外,脚本刻意**没有**启用 `devfs`/`procfs`/`sysfs`/`mtab` 服务(x-kernel 在 `entry/src/bootstrap.rs` 里已经预挂好这些,重新挂载有覆盖 `/dev/console` 的风险),也没有启用 `hostname` 服务(x-kernel 未实现 `sethostname(2)`)。`/etc/inittab` 用 `console::respawn:getty -L 0 console vt100` 在 QEMU `-serial mon:stdio` 的 PL011 上放一个登录会话。 ## Debian rootfs (glibc) 依赖:Docker(支持多架构,通过 QEMU binfmt 模拟);**不需要** root 权限。 ```sh # busybox init bash scripts/build-debian-rootfs.sh --arch aarch64 --init busybox bash scripts/build-debian-rootfs.sh --arch x86_64 --init busybox bash scripts/build-debian-rootfs.sh --arch riscv64 --init busybox # systemd bash scripts/build-debian-rootfs.sh --arch aarch64 --init systemd bash scripts/build-debian-rootfs.sh --arch x86_64 --init systemd bash scripts/build-debian-rootfs.sh --arch riscv64 --init systemd # 使用 -o 指定自定义输出路径(匹配新命名格式) bash scripts/build-debian-rootfs.sh --arch aarch64 --init busybox \ -o x-kernel-debian-busybox-aarch64.img # 可选参数 bash scripts/build-debian-rootfs.sh --arch aarch64 --init systemd \ --size 4G --debian bookworm -o x-kernel-debian-systemd-aarch64.img ``` 构建后压缩: ```sh xz x-kernel-debian-busybox-aarch64.img ``` 首次构建跨架构镜像时需注册 QEMU binfmt: ```sh docker run --rm --privileged tonistiigi/binfmt --install all ``` ## 已有镜像 当前目录下已构建好的镜像: | 文件 | 说明 | |------|------| | `x-kernel-alpine-busybox-aarch64.img` / `.img.xz` | Alpine aarch64 base | | `x-kernel-alpine-busybox-x86_64.img` / `.img.xz` | Alpine x86_64 base | | `x-kernel-alpine-busybox-aarch64-ci.img` / `.img.xz` | Alpine aarch64 CI | | `x-kernel-alpine-busybox-x86_64-ci.img` / `.img.xz` | Alpine x86_64 CI | | `x-kernel-alpine-openrc-aarch64.img` / `.img.xz` | Alpine aarch64 OpenRC | | `x-kernel-alpine-openrc-riscv64.img` / `.img.xz` | Alpine riscv64 OpenRC | | `x-kernel-alpine-openrc-x86_64.img` / `.img.xz` | Alpine x86_64 OpenRC | | `x-kernel-alpine-openrc-loongarch64.img` / `.img.xz` | Alpine loongarch64 OpenRC | | `x-kernel-debian-busybox-aarch64.img` / `.img.xz` | Debian trixie aarch64 busybox | | `x-kernel-debian-busybox-x86_64.img` / `.img.xz` | Debian trixie x86_64 busybox | | `x-kernel-debian-systemd-aarch64.img` / `.img.xz` | Debian trixie aarch64 systemd | | `x-kernel-debian-systemd-x86_64.img` / `.img.xz` | Debian trixie x86_64 systemd |