ADR-017 — EL1 fetch from the TTBR1 RAM alias
- Status: Accepted (exec mile; first identity-tear cut is ADR-018)
- Date: 2026-09-11
Context
ADR-016 enabled TTBR1 walks and proved one EL1-only data page at TTBR1_PRIV. The kernel still fetched instructions from the QEMU virt identity map at 0x4008_0000. Full higher-half relocate (every pointer, every fn item, then tearing down identity) is still too large for one honest PR: rustc emits link-time identity addresses (relocation-model: static), and -kernel loads _start at TEXT_OFFSET.
This ADR is the largest Verified cut that still keeps the boot stub: alias identity RAM in TTBR1 and run a real EL1 code path (instruction fetch, not a private store) at high VA.
Decision
- RAM alias.
L1_HIGH[1]points at the sameL2_RAMused by identity TTBR0. High VA isidentity + TTBR1_BASE(0x4008_0000→0xFFFF_FF80_4008_0000). Permissions match the identity image (text RO+X, data/stacks/heap RW+NX, guards unmapped). - Shared tables (superseded for the tear mile). This ADR reused
L2_RAM. ADR-018 clones RAM tables so one identity text page can be unmapped without dropping the high twin. Full identity teardown is still Planned. - EL1 exec probe.
ttbr1_high_el1_pathis invoked through its high VA (BLR/ fn pointer). It captures PC withADR, printsttbr1: el1 execfrom that path, and returns the PC. The caller checksPCis in the TTBR1 window and near the high entry. UART MMIO stays the absolute identity0x0900_0000. VBAR_EL1high. After the MMU is on,VBAR_EL1is programmed to the high alias ofexception_vectors(ttbr1: vbar). Later BRK / IRQ / EL0 sync fetch the table via TTBR1. Identityexception::initstill installs the link address first (pre-MMU).- Identity boot stub stays.
_start, QEMU-kernelload, and link-timefnitems remain at0x4008_0000. Most EL1 data access still uses identity VAs. Do not say the kernel moved. - Still Planned. Full identity teardown (unmap all low
.text/.data/heap after a complete high-VA jump); PAN on-cpu cortex-a57; umbrella EL0 isolation. ADR-018 is the first cut (one torn text page). User TTBR0 still maps most kernel text so a missed high-VBAR path can fetch. Do not change default-cpu. - NFR-10 text is revised in place (ID unchanged). Do not mint NFR-15+.
- ADRP is not a PA. After VBAR is high, handler code that does
addr_of!(table)/user_ttbr0()must mask to the 39-bit identity VA before programmingTTBR0or comparingFAR_EL1. First attempts Failed: guardFARcompared to a high__stack_guard, then standingstay_at_el0programmed a highL1_USERas TTBR0.paging::identity_pa/linker_symare the ratchet.
Honesty
Say “EL1 fetched a real path from a TTBR1 high VA” or “VBAR lives at the high alias” only when the serial / tests pass. Do not say:
- the kernel has moved to the high half
- identity mappings were torn down
- “secure OS” / “hardened” / “EL0 isolated”
- PAN (still unclaimed on
-cpu cortex-a57)
Consequences
paging::initinstalls the RAM alias and relocates VBAR.src/ttbr1.rsowns both the private-page probe and the exec probe.- ADR-016 remains the private-page first cut. This ADR is the exec mile.
- ADR-018 splits TTBR1 RAM tables and unmaps one identity text page. ADR-019 jumps the post-MMU continuation to high VA and unmaps a 16 KiB dedicated text range. ADR-020 unmaps live identity
.textafter a vtable rewrite. Unmapping.rodata/.data/heap is still later.