feat: aarch64 MMU identity map + cooperative kernel-thread scheduling - #142
Merged
Conversation
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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_kthreadseeding a 96-byte switch frame —entryat [frame+8]=x30 slot, matchingswitch_context'sldp x29,x30,[sp],#96; ret), realsched_yield_once(prepare_switch →switch_context, kernel-thread-only), and akernel_maindemo. Exercises the #139 context switch at runtime.Verified boot log:
x86_64/riscv64 unaffected; workspace fmt/clippy/build clean.