universalisos/docs/T9-2_APPLE_SILICON_BOOT.md

8.6 KiB

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

// 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

  • Port S5L UART
    • Create kernel/src/arch/aarch64/apple/uart_s5l.c (integrated into startup_apple.c)
    • Add to kernel/src/arch/aarch64/apple/board_apple_silicon.h
  • ADT device-tree parser
    • Create kernel/src/arch/aarch64/apple/adt_apple.h
    • Create kernel/src/arch/aarch64/apple/adt_apple.c
    • Parse /arm-io/uart0 for UART base + clock
    • Parse /arm-io/aic for AIC base + version
    • Parse /arm-io/ranges for memory map
    • Parse /cpus for SMP topology
  • Test UART output
    • Verify boot messages on QEMU (compile-only, no Apple Silicon QEMU machine)
    • 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)

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

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

# 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