Skip to content

feat: aarch64 MMU identity map + cooperative kernel-thread scheduling - #142

Merged
kernalix7 merged 2 commits into
mainfrom
feat/aarch64-mmu-and-scheduler
Jul 13, 2026
Merged

feat: aarch64 MMU identity map + cooperative kernel-thread scheduling#142
kernalix7 merged 2 commits into
mainfrom
feat/aarch64-mmu-and-scheduler

Conversation

@kernalix7

Copy link
Copy Markdown
Owner

Two verified aarch64 bring-up increments (both runtime-checked in qemu-system-aarch64 -M virt,gic-version=3).

MMU identity map

Builds a TTBR0_EL1 L1 identity table (TCR T0SZ=27, 4 KiB granule, 1 GiB blocks): entry 0 → 0..1 GiB Device-nGnRnE (GIC/PL011), entry 1 → 0x4000_0000..0x8000_0000 Normal WB/WA (RAM). Installs TTBR0, flushes TLB, sets SCTLR_EL1.M|C|I. Boots with the MMU ON, no translation faults under qemu -d int.

Cooperative kernel-thread scheduling

New arch/aarch64/kthread.rs (pool + spawn_kthread seeding a 96-byte switch frame — entry at [frame+8]=x30 slot, matching switch_context's ldp x29,x30,[sp],#96; ret), real sched_yield_once (prepare_switch → switch_context, kernel-thread-only), and a kernel_main demo. Exercises the #139 context switch at runtime.

Verified boot log:

[ONCRIX/aarch64] … GICv3 initialized / Generic timer armed
[ONCRIX/aarch64] cooperative scheduler: bring-up demo start
[ONCRIX/aarch64] cooperative scheduler: thread A ran
[ONCRIX/aarch64] cooperative scheduler: thread B ran
[ONCRIX/aarch64] cooperative scheduler: thread A/B ran, back on boot thread

x86_64/riscv64 unaffected; workspace fmt/clippy/build clean.

Build a translation table so SCTLR_EL1.M can be set (previously deferred
because enabling the MMU without TTBR0_EL1 faulted the next fetch). With
TCR T0SZ=27 (37-bit VA) + 4 KiB granule the top level is L1 (1 GiB
blocks). _start populates a BSS-resident, 4 KiB-aligned L1 table
(__ttbr0_l1) with two identity block descriptors — entry 0 maps 0..1 GiB
Device-nGnRnE (GICD 0x0800_0000, GICR 0x080A_0000, PL011 0x0900_0000),
entry 1 maps 0x4000_0000..0x8000_0000 Normal WB/WA (RAM; kernel at
0x4008_0000) — installs TTBR0_EL1, flushes the TLB (tlbi vmalle1 + dsb
ish), and enables SCTLR_EL1.M|C|I.

Verified: 'qemu-system-aarch64 -M virt,gic-version=3' boots with the MMU
ON through heap/GICv3/timer to the halt loop, no translation faults under
'qemu -d int'. x86_64/riscv64 unaffected.
Make the aarch64 kernel actually schedule, exercising the #139
switch_context at runtime:
- New arch/aarch64/kthread.rs mirrors the x86_64 kthread pool (static
  16 KiB stacks, CpuContext + used bitmap, MAX_KTHREADS=32, DAIF-based
  with_interrupts_disabled). spawn_kthread seeds a 96-byte switch frame
  at the stack top — entry is written to [frame+8] (the x30 slot popped
  by 'ldp x29, x30, [sp], #96'), the other 11 slots zeroed, and
  CpuContext.sp = frame base — so the first switch into the thread ret's
  to entry.
- sched_glue::sched_yield_once replaces its no-op with a real
  kernel-thread-only cooperative switch (prepare_switch → null-check →
  switch_context; no TSS/CR3/syscall-mirror). read_cr3 now reads
  TTBR0_EL1.
- kernel_main runs a bring-up demo: two kernel threads print and
  yield_now(); boot yields into them.

Verified in QEMU (MMU on): boot → thread A ran → thread B ran → back on
boot thread, no faults. x86_64 unchanged.
@kernalix7
kernalix7 merged commit fc167bb into main Jul 13, 2026
2 checks passed
@kernalix7
kernalix7 deleted the feat/aarch64-mmu-and-scheduler branch July 13, 2026 02:27
kernalix7 added a commit that referenced this pull request Jul 15, 2026
The riscv64 boot ran with paging off (satp = 0). Build a minimal Sv39
identity map and turn it on, mirroring the aarch64 #142 approach. Sv39's
root (L2) table maps 1 GiB gigapages; _start populates a BSS-resident,
4 KiB-aligned root table (__riscv_root_pt) with two identity leaf PTEs
(flags V|R|W|X|A|D = 0xCF):
  L2[0] -> 0x0000_0000..0x4000_0000  device MMIO (CLINT 0x0200_0000,
           PLIC 0x0C00_0000, NS16550 0x1000_0000)
  L2[2] -> 0x8000_0000..0xC000_0000  RAM (OpenSBI + kernel at 0x8020_0000)
then sets satp = MODE_SV39 | (root >> 12) with sfence.vma before/after.

Verified: 'qemu-system-riscv64 -M virt -bios default' boots with paging
ON all the way to the halt loop (UART/PLIC/timer all reached through the
identity map), with zero S-mode page faults under 'qemu -d int' (the
remaining illegal-insn traps are pre-existing OpenSBI-firmware HPM
probing, unrelated). x86_64/aarch64 unaffected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant