Page 1 of 1

Looking for AARCH64 page table code

Posted: Sat Jun 11, 2022 5:51 pm
by kzinti
I've been trying to figure out page tables / mapping on AARCH64 for the past few days and can't seem to get anything working.

qemu for aarch64 doesn't have "info mem" and since I am using UEFI, my bootloader is not loaded directly by qemu making GDB usage unavailable (or very complex, I couldn't figure it out).

So I am looking for some help / pointers here. Anyone has working simple code for aarch64 page tables (4 levels) or documentation? I've looked at Linux source code (ugh) and a bunch of references, but I am struggling here.

Some details:
1 ) I use UEFI (Tianocore), qemu command is "qemu-system-aarch64 -m 8G -net none -drive format=raw,file=rainbow-efi-aarch64.img -machine virt -cpu cortex-a53 -device virtio-gpu-pci"
2 ) The bootloader runs in EL1 and only TTBL0_EL1 is used (the MMU is also enabled)
3 ) I am trying to setup recursive mapping for my kernel using TTBL1_EL1.
4 ) The kernel is mapped to 0xFFFFFFFF800000000000000000000000, I set T1SZ to 17.
5 ) I update TCR_EL1 (the TTBL1 parts only) and then set TTBL1_EL1
6 ) Jumping to the kernel triggers a page fault (synchronization error)
7 ) In qemu's monitor, I can't read the memory I mapped (x /g 0xFFFFFFFF800000000000000000001000 -->"ffffffff80001000: Cannot access memory"
8 ) Relevant code: https://github.com/kiznit/rainbow-os/bl ... eTable.cpp, which is basically adapter from my x86_64 code that works fine (https://github.com/kiznit/rainbow-os/bl ... eTable.cpp)
9 ) Here is the code that updates TTBL1_EL1 and TCR_EL1: https://github.com/kiznit/rainbow-os/bl ... line.S#L39
10) Flags are defined here: https://github.com/kiznit/rainbow-os/bl ... memory.hpp
11) I understand I need 4 levels of page tables since (64-17 = 47 bits, which is 8 + 9 + 9 + 9).

Thanks!

Re: Looking for AARCH64 page table code

Posted: Sat Jun 11, 2022 6:20 pm
by kzinti
Writing these posts are really good at helping me finding problems.

I think part of the problem is setting T1SZ to 17 and thus having 47 bits of virtual memory space. On x86_64, we have 48 bits of virtual memory. So I changed T1SZ to 16 to get 48 bits on aarch64 as well. I can now read the virtual memory under QEMU's monitor. It appears to contain a bit of garbage and mostly zeroes, not what I expected, but this is progress.

EDIT: ok I verified that memory mapping works now: what I see when dumping virtual memory is the same thing I see when dumping physical memory. Still getting Synchronous Exception when jumping to the kernel, but it looks like progress.

Thanks for the help Kzinti!