Build the kernel
The kernel step builds Apple's XNU source with UniXNU patches, then prelinks the result against the original kernelcache.
Source and tree
| Path | Contents |
|---|---|
out/<board>/tree/refer/xnu | Pinned XNU source |
out/<board>/tree/.cache/xnu-work | Working clone with patches applied |
out/<board>/tree/build/xnu/ios-obj | Object files and compile command records |
out/<board>/tree/build/xnu/ios-sym | Symbols |
out/<board>/tree/build/xnu/ios-dst | Install headers |
out/<board>/tree/.cache/fakeroot | Kernel SDK root with restored headers |
out/<board>/kernel/kernel.macho | Prelinked kernel |
The source version comes from feeds.toml:
[[source]]
name = "xnu"
kind = "refer"
git = "https://github.com/apple-oss-distributions/xnu.git"
ref = "xnu-10063.141.1"
commit = "d8b80295118ef25ac3a784134bcf95cd8e88109f"
darwin = "23.6.0"
version = "10063.141.1"
driverkit_tag = "xnu-10063.121.3"
trustcache_tag = "xnu-8796.101.5"unixnu build kernel passes these values to scripts/build-xnu-4k-baseline.sh as UNIXNU_XNU_TAG, UNIXNU_XNU_COMMIT, UNIXNU_XNU_DARWIN, UNIXNU_XNU_VERSION, UNIXNU_DRIVERKIT_TAG and UNIXNU_TRUSTCACHE_TAG.
The build target is:
SDKROOT=iphoneos
ARCH_CONFIGS=ARM64
MACHINE_CONFIGS=BCM2837
KERNEL_CONFIGS=DEVELOPMENT
ARM64_LINK_ADDR=0xfffffff007004000
ARM64_PLKSEG_ADDR=0xfffffff004004000
DEPLOYMENT_TARGET_FLAGS="-miphoneos-version-min=17.0 -DXNU_TARGET_OS_IOS"BCM2837 is the XNU machine configuration that carries the 4 KiB page layout. The kernel still targets iOS 17 so the prelink ABI matches the iPadOS kernelcache.
Defconfig flags
Each CONFIG_XNU_<NAME> line becomes XNU_<NAME> in the kernel build environment. y becomes 1, n becomes 0, quoted strings are passed as text, and {tree} in a string is replaced by the build tree path.
| Flag | Effect | Archive |
|---|---|---|
XNU_SOURCE_CORECRYPTO14 | Builds and links the source corecrypto provider | build/corecrypto-2023/libcorecrypto_kernel_noasm-namespaced.a |
XNU_SOURCE_PTHREAD | Builds and registers the source pthread component | build/libpthread-kernel/libpthread_kernel.a |
XNU_ARM_DT_PLATFORM | Links the Apple-format device tree platform expert | build/armdt-platform/libArmDTPlatform.a |
XNU_ARMVIRT_PLATFORM | Links the QEMU virt platform expert | build/armvirt-platform/libArmVirtPlatform.a |
XNU_ARMCPU | Links the architectural CPU and interrupt provider | build/armcpu/libArmCpu.a |
XNU_NATIVE_UFS | Links the UFS storage driver | build/native-ufs/libNativeUfs.a |
XNU_NATIVE_AES | Links the AES accelerator driver | build/native-aes/libNativeAES.a |
XNU_NATIVE_VIRTIO_BLOCK | Links the VirtIO block driver | XNU_NATIVE_VIRTIO_BLOCK_ARCHIVE or build/native-virtio-block/libNativeVirtioBlock.a |
XNU_NATIVE_RAM_BLOCK | Links the RAM block driver | build/native-ram-block/libNativeRamBlock.a |
XNU_NATIVE_VIRTIO_CONSOLE | Links the VirtIO console byte transport | build/native-virtio-console/libNativeVirtioConsole.a |
XNU_NATIVE_MOBILE_DISPLAY | Links the mobile display provider | build/native-mobile-display/libNativeMobileDisplay.late.a |
XNU_NATIVE_LEGACY_DISPLAY | Links the legacy display provider | build/native-legacy-display/libNativeLegacyDisplay.late.a |
XNU_NATIVE_ADRENO | Links the Adreno GPU driver and kits | build/native-adreno/libNativeAdreno.a |
XNU_NATIVE_OFFLINE_GPU | Links the offline GPU broker | build/native-offline-gpu/libNativeOfflineGPU.late.a |
XNU_VERIFIED_ROOT_PROBE | Links the verified root provider | XNU_VERIFIED_ROOT_ARCHIVE or build/verified-root-xnu/libVerifiedRootProbe.a |
XNU_NATIVE_CS_HASH_CACHE | Derives 4 KiB code signature hashes from verified 16 KiB blocks | none |
XNU_NATIVE_ARCH_TIMER | Uses the architectural timer entry | none |
XNU_NATIVE_PAN | Enables ARMv8.1 PAN support | none |
XNU_DT_PANIC_REGION | Reads the panic region from the device tree | none |
XNU_TRUST_CACHE_RUNTIME | Initializes the trust cache runtime | none |
XNU_BOOT_PROGRESS | Adds the boot progress layer | build/boot-progress/libBootProgress.a |
XNU_SOURCE_MOCKFS | Adds the mockfs test file | build/mockfs-fixture/libmockfs_fixture.a |
The device repository owns the scripts that produce its archives. Run them after the first kernel build produces the compile command records, then run unixnu build kernel again.
Build sequence
unixnu fetchclones XNU and the Apple references.unixnu build kernelapplies patches and builds XNU. WhenXNU_BOOT_PROGRESS=1andstartup.o.jsonis absent, the step runs once with boot progress disabled, then again with it enabled.- Build the device archives. Each device script compiles against the actual XNU compile flags recorded in
build/xnu/ios-obj/.../*.cpo.json. unixnu build kernellinks the archives into the kernel.unixnu build prelinkproducesout/<board>/kernel/kernel.macho.
The prelink reads [kernel.prelink] from board.toml:
[kernel.prelink]
tool = "kits/NativePrelink/emit_prelink.py"
kernel = "build/xnu/ios-obj/DEVELOPMENT_ARM64_BCM2837/mach.development.bcm2837.unstripped.noctf"
kernelcache_sha256 = "..."
slide = "-0x1000000"
early_security_init = "com.apple.driver.AppleMobileFileIntegrity=0xfffffff005ab4ae0"
roots = [
"com.apple.driver.AppleARMPlatform",
"com.apple.filesystems.apfs",
]roots lists the original kernelcache components the native kernel uses. early_security_init maps a component identifier to an address that runs during prelink security initialization.
Adding a kernel flag
- Add
CONFIG_XNU_<NAME>=yto the device defconfig. - Read
XNU_<NAME>inscripts/build-xnu-4k-baseline.sh. - Add the object flags with
EXTRA_MAKE_ARGS+=("<file>.o_CFLAGS_ADD=-DXNU_<NAME>=$VALUE"). - Add the archive to
KERNEL_EXTRA_ARCHIVESandKERNEL_ARCHIVE_DEPENDENCIES. - Add the personality to
iokit/KernelConfigTables.cppthrough a patch.
Prebuilt kernel
unixnu build payload --kernel FILE packs an existing prelinked kernel. This path builds the boot image without rebuilding XNU.
Next steps
- Four-kilobyte pages explains the page size work.
- Patch reference lists every patch.
- Prelink explains the kernelcache binding.