I'm new to OSDev and generally to OS development, but I really like the structure of the Wiki and its articles. Huge props to the authors!
My first question in this Forum is about the different paging implementations. I have a good grasp about the theory for the different paging levels (x86 with 2-level and x86_86 with 4-level paging). However, I'm stuck in what seems to be the actual implementation of the paging system. I would like to show what I did so far and what my researches have thaught me as well as show you why I'm genuinely confused about what approach to choose and how the approaches exactly work during runtime.
What I did so far:
I completed the Bare Bones x86 Tutorial and read a good amount of the topics of GDT, IDT, etc. The current state of my OS:
- - Bare Bones x86 Tutorial finished
- For loading a 64-bit kernel, I chose the approach using a separate loader
The first approach is the one used in the Wiki, using a static array of length 1024 for the page directory on x86. However, as mentioned in the same article, this is a temporary workaround, as dynamic allocation is "too basic to be missing". Also, extending this to a 4-level paging mechanism would probably lead to something like the following:
Code: Select all
static uint64_t pml4[512];
static uint64_t pdpt[512][512];
static uint64_t pde[512][512][512];
static uint64_t pt[512][512][512][512];
The second approach was used on a different tutorial, guiding the developer to an OS built in Rust. Here, the space for the tables is being reserved in assembler, using the resb instruction with a value of 4096. While I get why the value is 4096 (512 entries for each table in each level and 8 byte for each entry -> 512 * 8 = 4096), I don't get why only 4096 bytes for each tables is reserved. As far as I understand, the only thing happening there is reserving space for one PML4, one PDPT, one PD and one PT. What about the missing 511 PDPTs and the 511 * 512 PDs and the rest of the page tables?
Both of the approaches listed above have something in common, which is my question here: How do I set up paging in a dynamic approach?
My first intuition was initializing an array with length 512 for the PML4 table. When mapping, you would check if the entry for the given linear address has a PRESENT flag set for the PDPT. In the initial state, no entries have this flag set, so I would need to "create" a new PDPT (how? using some kind of kmalloc just for page tables?) and set the entry of the PML4 to the newly allocated PDPT. The same goes for the PD and the PT when further mapping the linear address to a physical address. But I don't know where to store the newly created tables, as the heap won't be a good idea I guess. Maybe the idea might even be completely wrong.
I hope I could properly explain my problem to you and hope, you can give me some insight about what to do exactly.
Thanks for your help!