UniXNU 构建指南:从克隆仓库到生成 boot.img 的 8 个关键步骤
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 个动作:
- 将 patches/xnu/ 与
kits/NativePrelink/patches补丁应用到固定版本的 XNU 源码; - 运行 scripts/prepare-xnu-source.py 恢复缺失的 DriverKit 头文件;
- 首轮编译生成编译记录(
startup.o.json); - 按
[kernel] archives顺序构建静态库; - 以
ARM64/BCM2837/DEVELOPMENT/ iOS 17 构建 XNU 并链接; - 用 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
内部流程非常严谨:
- 按固件基址与大小编译 BootShim;
- 追加固件卷并用 gzip 压缩;
- 应用
[[bootimg.dtb_node]]后追加设备树; - 用 Mu-Silicium 配置中的镜像参数调用
mkbootimg.py打包; - 解包镜像并逐部分与输入比对,确保无误。
完成后你会得到:
- 📦
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 的锁屏!