mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Discuss alternative frame stack designs
This commit is contained in:
@@ -186,7 +186,18 @@ multiboot_start: 0x11d400, multiboot_end: 0x11d9c8
|
|||||||
So the kernel starts at 1MiB (like expected) and is about 105 KiB in size. The multiboot information structure was placed at `0x11d400` by GRUB and needs 1480 bytes. Of course your numbers could be a bit different due to different versions of Rust or GRUB (or some differences in the source code).
|
So the kernel starts at 1MiB (like expected) and is about 105 KiB in size. The multiboot information structure was placed at `0x11d400` by GRUB and needs 1480 bytes. Of course your numbers could be a bit different due to different versions of Rust or GRUB (or some differences in the source code).
|
||||||
|
|
||||||
## A frame allocator
|
## A frame allocator
|
||||||
When we create a paging module in the next post, we will need free physical frames to create new page tables. So we need some kind of allocator that keeps track of physical frames and gives us a free one when needed. We can use the information about memory areas to write such a frame allocator.
|
When we create a paging module in the next post, we will need free physical frames to create new page tables. So we need some kind of allocator that keeps track of physical frames and gives us a free one when needed. There are various ways to write such a frame allocator.
|
||||||
|
|
||||||
|
We could create some kind of linked list from the free frames. For example, each frame could begin with a pointer to the next free frame. Since the frames are free, this would not overwrite any data. Our allocator would just save the head of the list and could easily allocate and deallocate frames by updating pointers. Unfortunately, this approach has a problem: It requires reading and writing these free frames. So we would need to map all physical frames to some virtual address, at least temporary. Another disadvantage is that we need to create this linked list at startup. That implies that we need to set over one million pointers at startup if the machine has 4GiB of RAM.
|
||||||
|
|
||||||
|
Another approach is to create some kind of data structure such as a [bitmap or a stack] to manage free frames. We could place it in the already identity mapped area right behind the kernel or multiboot structure. That way we would not need to (temporary) map each free frame. But it has the same problem of the slow initial creating/filling. In fact, we will use this approach in a future post to manage frames that are freed again. But for the initial management of free frames, we use a different method.
|
||||||
|
[bitmap or a stack]: http://wiki.osdev.org/Page_Frame_Allocation#Physical_Memory_Allocators
|
||||||
|
|
||||||
|
In the following, we will use Multiboot's memory map directly. The idea is to maintain a simple counter that starts at frame 0 and is increased constantly. If the current frame is available (part of an available area in the memory map) and not used by the kernel or the multiboot structure (we know their start and end addresses), we know that it's free and return it. Else, we increase the counter to the next possibly free frame. That way, we don't need to create a data structure when booting and the physical frames can remain unmapped. The only problem is that we cannot reasonably free frames again, but we will solve that problem in a future post (by adding an intermediate frame stack that saves freed frames).
|
||||||
|
|
||||||
|
<!--- TODO link future post -->
|
||||||
|
|
||||||
|
So let's start implementing our memory map based frame allocator.
|
||||||
|
|
||||||
### A Memory Module
|
### A Memory Module
|
||||||
First we create a memory module with a `Frame` type (`src/memory/mod.rs`):
|
First we create a memory module with a `Frame` type (`src/memory/mod.rs`):
|
||||||
|
|||||||
Reference in New Issue
Block a user