feat(adapter): higher-half kernel (linked at PHYS_OFFSET, boot trampoline, no low mappings), fix SBI ecall clobbers

This commit is contained in:
2026-10-27 00:25:20 +01:00
parent 55758ae5b2
commit b87a62475f
20 changed files with 208 additions and 143 deletions

View File

@@ -27,16 +27,52 @@ pub fn kernel_ptr() -> *mut kernel::Kernel<platform::RiscVPlatform> {
KERNEL.as_ptr()
}
// Firmware enters `_start` at the physical load address with the MMU off,
// but the kernel is linked in the upper half. Using only PC-relative code,
// the stub turns on `boot_page_table`, which maps RAM twice (at its
// physical address, just so the next instruction still exists, and in the
// upper half) plus the MMIO window high, then jumps to its own high address.
// kmain replaces this table with the real one, which maps nothing low.
global_asm!(
r#"
.section .text.entry
.globl _start
_start:
la sp, _stack_top
lla t0, boot_page_table
srli t0, t0, 12
li t1, 8 << 60
or t0, t0, t1
csrw satp, t0
sfence.vma
ld t0, start_high_address
jr t0
start_high:
lla sp, _stack_top
call kmain
spin:
wfi
j spin
.pushsection .rodata
.balign 8
start_high_address:
.quad start_high
.popsection
# Sv39 root of 1 GiB leaves; an entry is (PA >> 12) << 10 | flags, with
# flags V|R|W|A|D = 0xc7, plus X = 0xcf.
.pushsection .data
.balign 4096
boot_page_table:
.quad 0
.quad 0
.quad 0x200000cf # [2] 0x8000_0000 -> RAM, for the jump only
.fill 253, 8, 0
.quad 0x000000c7 # [256] PHYS_OFFSET + 0 -> MMIO
.quad 0
.quad 0x200000cf # [258] PHYS_OFFSET + 0x8000_0000 -> RAM
.fill 253, 8, 0
.popsection
"#
);