Page 1 of 1
Bootstrap malloc realizations
Posted: Fri Jan 05, 2024 11:35 am
by mrjbom
Hi.
I'm about to start writing a physical memory manager, but I realized that it requires allocating and releasing memory(trivial for a bi-linked list of free areas), which means I need a way to allocate memory from the beginning.
I came up with this solution, I will reserve a few megabytes for the heap and from it I will allocate memory only for the needs of the main memory manager.
Are there any good implementations of something like malloc that I could give my fixed pre-allocated heap to, and then quietly use when creating the main allocator?
Perhaps there are some good articles on this topic.
I would like it to be simple enough, but not too slow, since the main allocator will be actively using it.
Re: Bootstrap malloc realizations
Posted: Fri Jan 05, 2024 6:49 pm
by nexos
This indeed can be a complicated issue. In my kernel I rolled my own bootloader, so I have the bootloader allocate a pool of memory for me. Then I initialize my slab allocator, but initially it allocates page frames from this pool. Once the actual memory manager is setup, then I will switch the allocator at runtime to using that to allocate page frames. This has the advantage that data structures can be allocated from the slab (up to a certain size, defined by the size of your pool). In your case of using GRUB, I would suggest having some code at the top of your boot sequence that finds a free memory region in the memory map and using that as an initial pool.
Re: Bootstrap malloc realizations
Posted: Fri Jan 05, 2024 7:18 pm
by thewrongchristian
mrjbom wrote:Hi.
I'm about to start writing a physical memory manager, but I realized that it requires allocating and releasing memory(trivial for a bi-linked list of free areas), which means I need a way to allocate memory from the beginning.
I came up with this solution, I will reserve a few megabytes for the heap and from it I will allocate memory only for the needs of the main memory manager.
Are there any good implementations of something like malloc that I could give my fixed pre-allocated heap to, and then quietly use when creating the main allocator?
Perhaps there are some good articles on this topic.
I would like it to be simple enough, but not too slow, since the main allocator will be actively using it.
You can use a simple bump-allocator. Initialise a pointer to the end of your kernel bss, then when you need to allocate, the pointer becomes what you return, and you advance the next pointer beyond the memory just allocated.
The details of my allocator are in this thread:
viewtopic.php?f=1&t=36742
I use it to allocate my arbitrarily sized bootstrap objects, such as the bitmap for the physical memory.
Re: Bootstrap malloc realizations
Posted: Sat Jan 06, 2024 3:55 am
by Jiyahana
Is it possible to use pre-allocated heap for the memory manager and explore lightweight allocators like dlmalloc or ptmalloc.
Re: Bootstrap malloc realizations
Posted: Sat Jan 06, 2024 7:54 pm
by songziming
thewrongchristian wrote:
You can use a simple bump-allocator. Initialise a pointer to the end of your kernel bss, then when you need to allocate, the pointer becomes what you return, and you advance the next pointer beyond the memory just allocated.
Some important data structure might be located right after kernel BSS, such as multiboot info, ELF symbol table, memory map, etc. Advancing kernel_end pointer might overwrite those data.
I reserve some space at the end of kernel BSS, which I call early_alloc_buff. During system startup, I allocate memory inside this buffer, kernel_end pointer cannot go beyond the end of early_alloc_buff. Since early_alloc_buff is inside kernel BSS, GRUB won't place data there. When all important data is consumed or backed up (into that early_alloc_buff), I can then remove the buffer limit, and kernel_end pointer can go beyond the end of early_alloc_buff.
This kind of allocation is only used in startup, to allocate space for data structures whose size is unknown at compile time, such as GDT, struct page array, etc. And those memory is never freed.
Once page allocator and kernel heap is initialized, the early bump alloc should be disabled.
PS. actually I reserve two early buffers, one for read-only data, one for read-write data. Const data section is mapped with RW bit off.
Re: Bootstrap malloc realizations
Posted: Sun Jan 07, 2024 4:48 am
by mrjbom
songziming wrote:thewrongchristian wrote:
You can use a simple bump-allocator. Initialise a pointer to the end of your kernel bss, then when you need to allocate, the pointer becomes what you return, and you advance the next pointer beyond the memory just allocated.
Some important data structure might be located right after kernel BSS, such as multiboot info, ELF symbol table, memory map, etc. Advancing kernel_end pointer might overwrite those data.
I reserve some space at the end of kernel BSS, which I call early_alloc_buff. During system startup, I allocate memory inside this buffer, kernel_end pointer cannot go beyond the end of early_alloc_buff. Since early_alloc_buff is inside kernel BSS, GRUB won't place data there. When all important data is consumed or backed up (into that early_alloc_buff), I can then remove the buffer limit, and kernel_end pointer can go beyond the end of early_alloc_buff.
This kind of allocation is only used in startup, to allocate space for data structures whose size is unknown at compile time, such as GDT, struct page array, etc. And those memory is never freed.
Once page allocator and kernel heap is initialized, the early bump alloc should be disabled.
PS. actually I reserve two early buffers, one for read-only data, one for read-write data. Const data section is mapped with RW bit off.
It's a good idea, I'll probably do it.