ARM MMU Implementation (Raspberry Pi)
Posted: Tue Nov 17, 2020 7:27 am
Hi everyone ! I'm currently trying to implement "virtual memory" on my kernel targetting raspberry pi zero.
I made a kernel for x86 before, and i'm trying to understand how paging works on ARM. (ARMv6 !!)
Basically, what i understood is :
- There is one "page directory" equivalent, the level 0 base translation table, which has a size of 16KiB, and contains either pointers to "page tables" i.e. level 1 tables containing either 4KB (small) or 64KB (large) pages, or direct "sections" mapping of size 1MiB (or supersections, 16MiB).
- Given the size of the base translation table, i can address up to 4GiB virtual memory with 1MiB section mapping, which is more than enough for me as the pi as only 512 MiB RAM, and not that much memory mapped stuff.
- The translation of a virtual address on a section mapping is done using the first 12 bits to seek for section in base translation table
- Section descriptors constains BADDR physical address 1MiB-aligned of the section
Correct me if i'm wrong, but assuming i'm right :
- performance-wise, does it make sense to map memory using only 1MiB sections ?
I believe they are much faster to resolve because of only 1 level of indirection, and with 512 MiB of RAM, i think i can afford to map memory for the kernel/processes 1 MiB at a time...
Am i gonna need 4KB pages ?
- i believe i should use TTBR1 to map kernel memory, for context switch optimisation, and that i need to specify how high i want the kernel to be, and high adresses will use TTBR1 to translate, while low will use TTBR0. How do i identity map my code before jumping higher half then ?
I made a kernel for x86 before, and i'm trying to understand how paging works on ARM. (ARMv6 !!)
Basically, what i understood is :
- There is one "page directory" equivalent, the level 0 base translation table, which has a size of 16KiB, and contains either pointers to "page tables" i.e. level 1 tables containing either 4KB (small) or 64KB (large) pages, or direct "sections" mapping of size 1MiB (or supersections, 16MiB).
- Given the size of the base translation table, i can address up to 4GiB virtual memory with 1MiB section mapping, which is more than enough for me as the pi as only 512 MiB RAM, and not that much memory mapped stuff.
- The translation of a virtual address on a section mapping is done using the first 12 bits to seek for section in base translation table
- Section descriptors constains BADDR physical address 1MiB-aligned of the section
Correct me if i'm wrong, but assuming i'm right :
- performance-wise, does it make sense to map memory using only 1MiB sections ?
I believe they are much faster to resolve because of only 1 level of indirection, and with 512 MiB of RAM, i think i can afford to map memory for the kernel/processes 1 MiB at a time...
Am i gonna need 4KB pages ?
- i believe i should use TTBR1 to map kernel memory, for context switch optimisation, and that i need to specify how high i want the kernel to be, and high adresses will use TTBR1 to translate, while low will use TTBR0. How do i identity map my code before jumping higher half then ?