UniXNU 构建指南:从克隆仓库到生成 boot.img 的 8 个关键步骤

原创2026-10-25 23:25:13833 阅读

UniXNU 构建指南:从克隆仓库到生成 boot.img 的 8 个关键步骤

这是一份面向新手的 UniXNU 构建指南,通过 8 个关键步骤带你从克隆仓库开始,一步步构建出可在非 Apple ARM64 设备上运行的 boot.img 启动镜像,最终让 iOS / macOS 跑在小米平板 6S Pro 这类国产 ARM64 硬件上。整个流程由仓库内置的构建驱动 unixnu 自动完成,你只需要按顺序执行命令。

🧰 开始之前:了解构建流程

UniXNU 的构建围绕三个仓库展开,最终产物是一个 Android 格式的启动镜像:

仓库 作用
UniXNU(主仓库) 构建驱动、UEFI 启动管理器、驱动模块与 XNU 补丁
UniXNU-sheng(设备仓库) 板级描述、defconfig、内核静态库脚本
uefi-sheng(UEFI 移植) 设备的 Mu-Silicium 固件工程

构建时 unixnu 会读取设备仓库、解析模块、组装构建树,并逐步执行 fetch → 内核 → 固件 → 打包。所有输出统一放在 out/ 目录,布局详见 docs/zh/reference/output-layout.md。

💡 建议先把三个仓库克隆到同一级目录下,后续命令会用到相对路径 ../UniXNU-sheng 和 ../uefi-sheng。

步骤 1:克隆 UniXNU 仓库

打开终端,执行以下命令克隆主仓库(带 --recurse-submodules 可同时拉取驱动与 kit 子模块):

git clone --recurse-submodules https://gitcode.com/gh_mirrors/un/UniXNU
cd UniXNU

再克隆设备仓库 UniXNU-sheng 与 UEFI 移植 uefi-sheng(从与主仓库相同的镜像源获取),放在 UniXNU 同级目录。

如果你已经克隆过仓库,只需补齐子模块:

git submodule update --init --recursive

步骤 2:准备构建环境与外部输入

构建驱动在 macOS 上运行(内核步骤会调用 Xcode),其余步骤可在任意系统执行。环境要求速查:

工具 用途 安装方式
macOS + Xcode 内核、Data 种子步骤 App Store
Python ≥ 3.11 所有步骤 Homebrew
cmake、ninja 内核参考源码 brew install cmake ninja
unifdef libdispatch 头文件 brew install unifdef
LLVM 与 lld 内核、固件、启动镜像 brew install llvm
mtools、dtc 负载卷、设备树 brew install mtools dtc

完整清单见 docs/zh/guide/requirements.md。

此外还有几类外部输入,构建时需要提供:

输入 使用步骤 对应选项
目标 IPSW(恢复镜像) 内核预链接、userdata --ipsw
编译后的设备树 .dtb 启动镜像 --dtb
解压后的 kernelcache 内核预链接 --kernelcache
UEFI 移植仓库 固件、启动镜像 --uefi

🔑 小技巧:所有选项都有同名环境变量(如 UNIXNU_IPSW、UNIXNU_UEFI),写进 shell 配置可省去每次输入。

步骤 3:选择 defconfig 板级配置

defconfig 负责把设备仓库中的板级配置复制到构建输出区,并在构建前校验文件格式:

./unixnu defconfig sheng_defconfig -D ../UniXNU-sheng
  • 不带名称执行 ./unixnu defconfig 可以列出设备仓库 configs/ 下所有可用配置;
  • -D 指定设备仓库,首次使用后会记住在 out/state.json,之后可省略;
  • 选中后配置写入 out/<board>/.config,构建全程以此为准。

板级描述文件的完整结构可参考 examples/device/board.toml 与示例配置 examples/device/configs/example_defconfig。

步骤 4:fetch 拉取并锁定源码

./unixnu fetch

这一步会解析所有模块并拉取 git 源码。它采用浅克隆 + blobless + sparse checkout,每个仓库与 ref 只保留一份克隆,既省空间又快速。拉取完成后,每个源码的 commit 会写入设备仓库的 unixnu.lock 锁文件,保证后续构建可复现;需要强制更新时加 --update。

步骤 5:ipsw fetch 提取目标恢复镜像

./unixnu ipsw fetch

IPSW 是 Apple 的完整恢复镜像,体积庞大。UniXNU 通过 HTTP range 请求按成员读取,绝不整体下载,解压出的组件缓存在 out/ipsw/<build>/ 并按 board.toml 中的 [ipsw.sha256] 哈希校验。

执行前可先用 ./unixnu ipsw info 查看镜像的产品、build 和全部组件。镜像必须匹配 [ipsw] 段声明的产品、版本、chip ID 与 board ID,否则构建会被拒绝。

步骤 6:build kernel 编译并预链接内核

./unixnu build kernel

这是耗时最长的一步,内部完成 6 个动作:

  1. 将 patches/xnu/ 与 kits/NativePrelink/patches 补丁应用到固定版本的 XNU 源码;
  2. 运行 scripts/prepare-xnu-source.py 恢复缺失的 DriverKit 头文件;
  3. 首轮编译生成编译记录(startup.o.json);
  4. 按 [kernel] archives 顺序构建静态库;
  5. 以 ARM64 / BCM2837 / DEVELOPMENT / iOS 17 构建 XNU 并链接;
  6. 用 kits/NativePrelink/ 将原生内核与原始 kernelcache 预链接。

kernelcache 默认从 IPSW 提取(LZFSE 解码、选 arm64 切片、按 kernelcache_sha256 校验)。最终产物为 out/<board>/kernel/kernel.macho。

步骤 7:build package 与 firmware

先构建 UEFI 包组件:

./unixnu build package

这一步用 EDK II 编译 package/UniXNUPkg/,输出到 out/<board>/package/Build/Out,包含启动管理器 UniXNU.efi、驱动 UniXNUDxe.efi 及测试用的 HelloPayload.efi、SampleDriver.efi、XnuTest.efi。

再构建设备固件(依赖步骤 1 克隆的 UEFI 移植仓库):

./unixnu build firmware --uefi ../uefi-sheng

固件步骤会依次运行板级预检脚本、临时应用板级补丁到共享 edk2 树(构建后自动还原)、执行 EDK II build。固件卷大小必须与 Mu-Silicium 设备配置的 [uefi_fd] size 一致。

步骤 8:bootimg 打包生成 boot.img

最后一步把 BootShim、固件卷、设备树和负载卷打包成 Android 启动镜像:

./unixnu bootimg --uefi ../uefi-sheng --dtb /path/to/device.dtb

内部流程非常严谨:

  1. 按固件基址与大小编译 BootShim;
  2. 追加固件卷并用 gzip 压缩;
  3. 应用 [[bootimg.dtb_node]] 后追加设备树;
  4. 用 Mu-Silicium 配置中的镜像参数调用 mkbootimg.py 打包;
  5. 解包镜像并逐部分与输入比对,确保无误。

完成后你会得到:

  • 📦 out/<board>/boot/boot.img —— 最终启动镜像
  • 📄 out/<board>/boot/boot.json —— 构建报告

如需携带完整负载(含预链接内核与配置文件),可先执行 ./unixnu build payload 生成 payload.img,再运行 bootimg,它会优先使用负载输出作为 ramdisk。

✅ 验证成果与刷入设备

./unixnu status   # 查看设备、配置与每个模块的来源
fastboot boot out/<board>/boot/boot.img

fastboot boot 只把镜像加载到内存启动一次,不会修改设备原有的 boot 分区,可以放心冒烟测试。完整的刷写与启动菜单操作见 docs/zh/guide/boot.md。

⚡ 常用选项速查

选项 含义
-D DIR 设备仓库,首次使用后会记住
-j N 并行任务数,默认取 CPU 数量
--target DEBUG|RELEASE EDK II 构建目标,默认 DEBUG
--ipsw PATH_OR_URL 指定目标 IPSW,本地或远程
--kernel-arg NAME=VALUE 追加/替换内核命令行参数,可重复
--ramdisk FILE 指定 ramdisk,--ramdisk none 使用空 ramdisk
clean 子命令:删除板级输出,保留已拉取源码

📚 小结

回顾这 8 个关键步骤:克隆仓库 → 准备环境 → defconfig → fetch → ipsw fetch → build kernel → build package/firmware → bootimg。掌握这条主线后,你随时可以回到 docs/zh/building.md 查阅完整命令表,或参考 scripts/unixnu/ 下的驱动源码理解每一步的实现细节。祝构建顺利,早日在国产平板上看到 iOS 的锁屏!

登录后查看全文
UniXNU