Paging and Memory Allocation Woes
Posted: Tue Aug 29, 2017 9:00 pm
Hi,
I'm at a point where I'm trying to design my kernel in such a way that it doesn't come back to bite me later. My main issue is working out how the memory "bootstrapping" process should be handled, for a few reasons:
In the .bss section of my kernel I have a few page tables, enough to allocate up to 2MB. Having done so, the next thing I need to do memory wise is enable the physical memory manager. Regardless of the data structure I use (stack, bitmap etc.), I don't think I can avoid the requirement that the (maximum) memory usage of that data structure will be proportional to the amount of actual RAM I have available (e.g for a bitmap, if I have 1GB RAM then I need 1GB/4096 bits, but for 2GB I need 2GB/4096 bits. Roughly the same thing applies for a stack structure).
So, in order to initialise this memory I need to map it into the virtual address space. In order to do this, I will need a specific number of page tables which will be proportional to the size of the PMM data structure (and thus also proportional to the amount of RAM available).
And herein lies the problem. I can't statically allocate all the page tables at compile time, because the number of tables I will need depend on the size of the PMM which depends on the size of available RAM. This means I need some (primitive) form of dynamic allocation... all whilst not having a proper PMM/VMM which I can use.
I think one potential solution would be to use recursive page table mapping, but 1) I'm not sure that's possible (since my kernel is currently mapped to the last PML4 entry in order to be able to use -mcmodel=kernel) but 2) even if it is possible I'd prefer not to use it so as to keep as much of the virtual address space for myself. (Of course, this is not too important since I'm using x86_64 and the virtual address space is massive, so I'm willing to reconsider). I'm also planning to adopt the linux strategy of mapping the whole physical address space into the higher half on boot.
How have you guys approached this problem in your own operating systems? If anyone knows how it is done in linux or other systems then I would be grateful to hear that information too.
I'm at a point where I'm trying to design my kernel in such a way that it doesn't come back to bite me later. My main issue is working out how the memory "bootstrapping" process should be handled, for a few reasons:
In the .bss section of my kernel I have a few page tables, enough to allocate up to 2MB. Having done so, the next thing I need to do memory wise is enable the physical memory manager. Regardless of the data structure I use (stack, bitmap etc.), I don't think I can avoid the requirement that the (maximum) memory usage of that data structure will be proportional to the amount of actual RAM I have available (e.g for a bitmap, if I have 1GB RAM then I need 1GB/4096 bits, but for 2GB I need 2GB/4096 bits. Roughly the same thing applies for a stack structure).
So, in order to initialise this memory I need to map it into the virtual address space. In order to do this, I will need a specific number of page tables which will be proportional to the size of the PMM data structure (and thus also proportional to the amount of RAM available).
And herein lies the problem. I can't statically allocate all the page tables at compile time, because the number of tables I will need depend on the size of the PMM which depends on the size of available RAM. This means I need some (primitive) form of dynamic allocation... all whilst not having a proper PMM/VMM which I can use.
I think one potential solution would be to use recursive page table mapping, but 1) I'm not sure that's possible (since my kernel is currently mapped to the last PML4 entry in order to be able to use -mcmodel=kernel) but 2) even if it is possible I'd prefer not to use it so as to keep as much of the virtual address space for myself. (Of course, this is not too important since I'm using x86_64 and the virtual address space is massive, so I'm willing to reconsider). I'm also planning to adopt the linux strategy of mapping the whole physical address space into the higher half on boot.
How have you guys approached this problem in your own operating systems? If anyone knows how it is done in linux or other systems then I would be grateful to hear that information too.