Troubles with Memory Management
Posted: Sat May 16, 2015 3:35 pm
Hello together,
I am stuck with the implementation of my memory management and believe that it requires a complete redesign. First, I would like to present the current state of the kernel and then I would like to state the troubles I am having with the memory management - In fact, I believe that I am missing some crucial details, which prevent further progress. I would be very grateful if we could discuss suitable memory management solutions in some detail. By the way: If you should discover any flaws in the following description, do not hesitate to mention it - as I am here to learn and hence open for any form of constructive criticism
Current state:
To boot the kernel, I chose to use two separate binaries: one for the bootstrapping code (ELF32) and one for the kernel code (ELF64). During startup, the GRUB2 bootloader loads the bootstrap image as "kernel" and the actual kernel as a "GRUB module". The bootstrapping code handles the initial initialization steps (setup of GDT, IDT, ...) and locates the GRUB module representing the actual kernel image.
Since paging is required to jump into Long Mode, I have implemented a rudimentary paging mechanism already in the bootstrapping code. It makes use of a statically allocated pool of page-sized blocks to initialize the 4-level paging structures (PML4, PDPT, PD, PT). (Please note that at this point, there is no active physical memory management yet, as I thought the kernel would be a good place for it). The bootstrapping code maps the LOAD segment of the ELF64 kernel image to the address 0xFFFFFFFFF0000000 (the bootstrapping code does not move the kernel image within the phys. memory) and jumps to this address after performing required steps for Long Mode initialization.
Troubles/Questions:
Now, in the actual kernel I would like to implement a decent phys. memory management complemented with the paging mechanism so that it would be possible to allocate additional memory and map it to any virtual memory space. The issues I am encountering are the following:
1) Find a good way to take over control of the active paging mechanism (initialized within the bootstrapping image) inside the kernel:
To achieve this, first, I would need to know the physical address of the current paging structures. I have read that it is common to map the last page directory entry (PDE) to the beginning of the Page Directory itself. This enables modification of the Page Tables through virtual memory in 32-bit architectures withouth PAE. In case Long Mode has been initialized, the PML4 structure has 512 entries pointing to 512 PDPTs and so on... This makes it harder to localize the page table structures through virtual memory. I guess what I am trying to understand is what would be a good way to localize these structures in Long Mode.
2) Find out the physical memory address of the kernel:
To be able to implement a phys. memory manager, I need to know where the kernel is located in phys. memory so that I can mark its memory location as occupied or simply as "not free". Since the kernel has been loaded into memory as a GRUB module, only the bootloader itself and the bootstrapping code knows its location address in memory. Or is there a way how the kernel may find its actual phys. start address? (Does the GRUB memory map contain the memory occupied by GRUB modules?).
As always: Thank you very much in advance
I am stuck with the implementation of my memory management and believe that it requires a complete redesign. First, I would like to present the current state of the kernel and then I would like to state the troubles I am having with the memory management - In fact, I believe that I am missing some crucial details, which prevent further progress. I would be very grateful if we could discuss suitable memory management solutions in some detail. By the way: If you should discover any flaws in the following description, do not hesitate to mention it - as I am here to learn and hence open for any form of constructive criticism
Current state:
To boot the kernel, I chose to use two separate binaries: one for the bootstrapping code (ELF32) and one for the kernel code (ELF64). During startup, the GRUB2 bootloader loads the bootstrap image as "kernel" and the actual kernel as a "GRUB module". The bootstrapping code handles the initial initialization steps (setup of GDT, IDT, ...) and locates the GRUB module representing the actual kernel image.
Since paging is required to jump into Long Mode, I have implemented a rudimentary paging mechanism already in the bootstrapping code. It makes use of a statically allocated pool of page-sized blocks to initialize the 4-level paging structures (PML4, PDPT, PD, PT). (Please note that at this point, there is no active physical memory management yet, as I thought the kernel would be a good place for it). The bootstrapping code maps the LOAD segment of the ELF64 kernel image to the address 0xFFFFFFFFF0000000 (the bootstrapping code does not move the kernel image within the phys. memory) and jumps to this address after performing required steps for Long Mode initialization.
Troubles/Questions:
Now, in the actual kernel I would like to implement a decent phys. memory management complemented with the paging mechanism so that it would be possible to allocate additional memory and map it to any virtual memory space. The issues I am encountering are the following:
1) Find a good way to take over control of the active paging mechanism (initialized within the bootstrapping image) inside the kernel:
To achieve this, first, I would need to know the physical address of the current paging structures. I have read that it is common to map the last page directory entry (PDE) to the beginning of the Page Directory itself. This enables modification of the Page Tables through virtual memory in 32-bit architectures withouth PAE. In case Long Mode has been initialized, the PML4 structure has 512 entries pointing to 512 PDPTs and so on... This makes it harder to localize the page table structures through virtual memory. I guess what I am trying to understand is what would be a good way to localize these structures in Long Mode.
2) Find out the physical memory address of the kernel:
To be able to implement a phys. memory manager, I need to know where the kernel is located in phys. memory so that I can mark its memory location as occupied or simply as "not free". Since the kernel has been loaded into memory as a GRUB module, only the bootloader itself and the bootstrapping code knows its location address in memory. Or is there a way how the kernel may find its actual phys. start address? (Does the GRUB memory map contain the memory occupied by GRUB modules?).
As always: Thank you very much in advance