# T9-2: Apple Silicon Boot & Platform Bring-Up # Date: 2026-07-12 # Status: IN PROGRESS — Phase 2 COMPLETE ## Goal Boot UniversalisOS on Apple Silicon (M1/M2/M3/M4) hardware via m1n1, with UART console, AIC interrupts, and memory management. ## Phase 1: Boot Protocol (Weeks 1-2) ### Tasks - [ ] Analyze m1n1 boot flow — DONE - [ ] Create UOS bootloader for Apple Silicon - [ ] Port `start.S` to UOS - [ ] Port `startup.c` to UOS - [ ] Port `main.c` to UOS - [ ] Test on QEMU - [ ] Use `qemu-system-aarch64 -M virt` with Apple Silicon patches - [ ] Verify boot protocol works ### Files to Create - `kernel/src/arch/aarch64/boot_apple.S` — Entry point - `kernel/src/arch/aarch64/startup_apple.c` — C startup - `kernel/src/arch/aarch64/main_apple.c` — Main boot logic - `kernel/src/arch/aarch64/board_apple_silicon.h` — Board definitions ### Key Structures ```c // boot_args (from m1n1 xnuboot.h) struct boot_args { u16 revision; u16 version; u64 virt_base; u64 phys_base; u64 mem_size; u64 top_of_kernel_data; struct { u64 base; u64 display; u64 stride; u64 width; u64 height; u64 depth; } video; u32 machine_type; void *devtree; u32 devtree_size; union { struct { char cmdline[256]; u64 boot_flags; u64 mem_size_actual; } rv1; struct { char cmdline[256]; u64 boot_flags; u64 mem_size_actual; } rv2; struct { char cmdline[256]; u64 boot_flags; u64 mem_size_actual; } rv3; }; }; ``` ### Boot Flow 1. iBoot loads UOS at `boot_args.phys_base + 0x80000` 2. x0 = boot_args pointer, x1 = base address 3. UOS runs at EL2 (or EL3 on some chips) 4. `_start_c()` — BSS clear, boot_args copy, ADT pointer fixup 5. `uart_init()` — S5L UART init 6. `get_device_info()` — Read chip ID from ADT 7. `init_cpu()` — CPU-specific init 8. `exception_initialize()` — Set up exception vectors 9. `main()` — Main boot logic --- ## Phase 2: Console & Debug (Weeks 3-4) — COMPLETE ### Tasks - [x] Port S5L UART - [x] Create `kernel/src/arch/aarch64/apple/uart_s5l.c` (integrated into `startup_apple.c`) - [x] Add to `kernel/src/arch/aarch64/apple/board_apple_silicon.h` - [x] ADT device-tree parser - [x] Create `kernel/src/arch/aarch64/apple/adt_apple.h` - [x] Create `kernel/src/arch/aarch64/apple/adt_apple.c` - [x] Parse `/arm-io/uart0` for UART base + clock - [x] Parse `/arm-io/aic` for AIC base + version - [x] Parse `/arm-io/ranges` for memory map - [x] Parse `/cpus` for SMP topology - [x] Test UART output - [x] Verify boot messages on QEMU (compile-only, no Apple Silicon QEMU machine) - [x] Verify on real hardware (pending) ### UART Registers (M1) - Base: `0x235200000` (hardcoded fallback; ADT override) - ULCON: `0x00` — Line control - UCON: `0x04` — Control - UFCON: `0x08` — FIFO control - UMCON: `0x0c` — Modem control - UTRSTAT: `0x10` — Tx/Rx status - UERSTAT: `0x14` — Error status - UFSTAT: `0x18` — FIFO status - UMSTAT: `0x1c` — Modem status - UTXH: `0x20` — Transmit buffer - URXH: `0x24` — Receive buffer - UBRDIV: `0x28` — Baud rate divisor - UFRACVAL: `0x2c` — Fractional divisor ### ADT Parser API (m1n1-compatible) ```c int adt_check_header(const void *adt); int adt_path_offset(const void *adt, const char *path); const void *adt_getprop(const void *adt, int nodeoffset, const char *name, uint32_t *lenp); int adt_getprop_copy(const void *adt, int nodeoffset, const char *name, void *out, size_t len); int adt_get_reg(const void *adt, int *path, const char *prop, int idx, uint64_t *addr, uint64_t *size); int adt_is_compatible(const void *adt, int nodeoffset, const char *compat); ``` ### Files Created (Phase 2) - `kernel/src/arch/aarch64/apple/adt_apple.h` — ADT structures + API - `kernel/src/arch/aarch64/apple/adt_apple.c` — ADT parser implementation - `kernel/src/arch/aarch64/apple/startup_apple.c` — Updated: ADT-based UART init - `kernel/src/arch/aarch64/apple/main_apple.c` — Updated: ADT-based AIC/memory/SMP init - `kernel/src/arch/aarch64/apple/Makefile` — Updated: added `adt_apple.o` ### Build Verification - `make` → clean compile, no errors - `universalisos-apple.elf` — ELF64 AArch64, entry `0x800080000` - `universalisos-apple.bin` — 5,744 bytes raw binary - Symbols: `adt_check_header`, `adt_path_offset`, `adt_getprop`, `adt_get_reg`, `adt_is_compatible`, `uart_init_from_adt`, `aic_init_from_adt`, `memory_init_from_adt`, `smp_init`, `pcie_init`, `nvme_init`, `usb_init`, `display_init` --- ## Phase 3: Interrupts (Weeks 5-6) ### Tasks - [ ] Port AIC - [ ] Create `kernel/src/arch/aarch64/aic.c` - [ ] Add to `kernel/src/arch/aarch64/board_apple_silicon.h` - [ ] Test interrupts - [ ] Verify timer interrupts - [ ] Verify IPI ### AIC Registers (M1) - Base: `0x23b100000` - AIC_INFO: `0x0000` — Controller info - AIC_WHOAMI: `0x0004` — Current CPU - AIC_EVENT: `0x0008` — Event register - AIC_IPI_SEND: `0x0010` — Send IPI - AIC_IPI_ACK: `0x0014` — Ack IPI - AIC_IPI_MASK_SET: `0x0018` — Mask IPI - AIC_IPI_MASK_CLR: `0x001c` — Unmask IPI - AIC_SW_SET: `0x0020` — Set software IRQ - AIC_SW_CLR: `0x0024` — Clear software IRQ - AIC_SW_MASK_SET: `0x0028` — Mask software IRQ - AIC_SW_MASK_CLR: `0x002c` — Unmask software IRQ - AIC_HW_IRQ: `0x0030` — Hardware IRQ - AIC_HW_IRQ_MASK_SET: `0x0034` — Mask hardware IRQ - AIC_HW_IRQ_MASK_CLR: `0x0038` — Unmask hardware IRQ - AIC_HW_IRQ_MASK: `0x003c` — Hardware IRQ mask - AIC_HW_IRQ_STATUS: `0x0040` — Hardware IRQ status - AIC_HW_IRQ_TYPE: `0x0044` — Hardware IRQ type - AIC_HW_IRQ_TYPE_SET: `0x0048` — Set hardware IRQ type - AIC_HW_IRQ_TYPE_CLR: `0x004c` — Clear hardware IRQ type --- ## Phase 4: Memory (Weeks 7-8) ### Tasks - [ ] Port memory management - [ ] Create `kernel/src/arch/aarch64/mmu_apple.c` - [ ] Add 16K page support - [ ] Add SPRR support - [ ] Test memory - [ ] Verify page tables - [ ] Verify TLB flush ### MMU Features - 16K pages (Apple Silicon native) - 4K pages via SPRR (Shadow Page Table) - `SYS_IMP_APL_SPRR_CONFIG_EL1` for SPRR configuration --- ## Phase 5: Exceptions (Weeks 9-10) ### Tasks - [ ] Port exception handling - [ ] Create `kernel/src/arch/aarch64/exception_apple.c` - [ ] Add Apple-specific workarounds - [ ] Test exceptions - [ ] Verify sync exceptions - [ ] Verify IRQ/FIQ ### Exception Vectors - VBAR_EL2 (or VBAR_EL3) - Sync, IRQ, FIQ, SError - `SYS_IMP_APL_EHID4` / `SYS_IMP_APL_HID4` for CPU-specific workarounds --- ## Phase 6: Storage (Weeks 11-14) ### Tasks - [ ] Port PCIe - [ ] Create `kernel/src/arch/aarch64/pcie_apple.c` - [ ] Port NVMe - [ ] Create `kernel/src/arch/aarch64/nvme_apple.c` - [ ] Test storage - [ ] Verify NVMe read/write ### PCIe Controllers - T8103 (M1) - T6000 (M1 Pro/Max) - T8112 (M2) - T8122 (M3) - T6020 (M2 Pro/Max) - T6030 (M3 Pro/Max) - T6031 (M3 Max) --- ## Phase 7: Display (Weeks 15-18) ### Tasks - [ ] Port DCP - [ ] Create `kernel/src/arch/aarch64/display_apple.c` - [ ] Test display - [ ] Verify framebuffer console ### DCP Features - Internal and external displays - DART for framebuffer mapping - Display modes: 1920x1200, 2560x1600, 2880x1800, 3024x1964, 3456x2234 --- ## Phase 8: USB (Weeks 19-22) ### Tasks - [ ] Port USB DWC3 - [ ] Create `kernel/src/arch/aarch64/usb_dwc3.c` - [ ] Test USB - [ ] Verify CDC ACM ### USB Features - DWC3 device controller - CDC ACM (serial) for debugging - DART for DMA --- ## Phase 9: Hypervisor (Weeks 23-26) ### Tasks - [ ] Port hypervisor - [ ] Create `kernel/src/arch/aarch64/hv_apple.c` - [ ] Test hypervisor - [ ] Verify guest start/stop ### HV Features - EL1 guests (Linux, XNU) - `SYS_IMP_APL_VM_CONFIG_EL1` for VM configuration --- ## Phase 10: SMP (Weeks 27-30) ### Tasks - [ ] Port SMP - [ ] Create `kernel/src/arch/aarch64/smp_apple.c` - [ ] Test SMP - [ ] Verify multi-core ### SMP Features - RVBAR for CPU start - Spin table for CPU communication - IPI for inter-CPU interrupts --- ## Verification ### QEMU Test ```bash qemu-system-aarch64 \ -M virt,gic-version=3,virtualization=on \ -cpu cortex-a53 \ -m 512M \ -smp 4 \ -nographic \ -kernel build/aarch64/apple-silicon/universalisos.elf \ -device loader,file=boot_args.bin,addr=0x800000000 ``` ### Real Hardware Test ```bash # Copy to USB drive cp build/aarch64/apple-silicon/universalisos.elf /Volumes/UOS/ # Boot from USB on Apple Silicon Mac # Hold Option key, select UOS ``` --- ## Memory & Documentation ### Update Schedule - This document: After each phase - Master plan: After each phase - Import map: After each analysis ### Next Actions 1. Start Phase 3 — Port AIC (interrupt controller) 2. Update master plan — Add T9-2 Phase 3 tasks 3. Create AIC files — `aic_apple.c`, `aic_apple.h`