Welcome to the Linux Foundation Forum!

RISCV initialization / writing an emulator mmu

Heyas!

I'm trying to add a SV39 MMU to a RISCV64 emulator. The emulator is able to boot a linux kernel compiled without mmu-support. It looks like it should work with the MMU, but it doesn't, and right now, reading the source code, I can not figure out how it could ever work! So, here it goes:

Initialization starts in https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/head.S which first calls setup_vm() in https://github.com/torvalds/linux/blob/master/arch/riscv/mm/init.c#L1041 that sets up a page table, and then calls relocate_enable_mmu. relocate_enable_mmu enables SV39 by setting satp.mode = 8 at https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/head.S#L106.

  • The page table used at this point is trampoline_pg_dir. This page table only maps the kernel to high addresses ffffffffxxxxxxxx. But we are currently executing at a low address, 8xxxxxxx.
  • When satp.mode = 8 is set, priv is still set to machine mode.
  • Having priv=3 (machine mode) at the same time as satp.mode != 0 is undefined!

  • If I make it so that this is interpreted as mmu enabled, I get an immediat page fault, as pc isn't mapped by the new page table.

  • If I instead make it so that this means mmu is disabled, execution continues, and ends with a jump to ffffffff80001084, which /is/ mapped. But at that point, priv is still = 3, and that address isn't a physical addtess, so it fails to fetch.

How is this supposed to work?

Welcome!

It looks like you're new here. Sign in or register to get started.
Sign In

Welcome!

It looks like you're new here. Sign in or register to get started.
Sign In

Categories

Upcoming Training