Freestanding c memory manager without sbrk()

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
isaiah0311
Member
Member
Posts: 25
Joined: Tue Mar 09, 2021 9:31 pm
Libera.chat IRC: isaiah0311

Freestanding c memory manager without sbrk()

Post by isaiah0311 »

The OS is in long mode and has paging enabled.

For memory management I have looked at several examples of custom malloc functions but there is a common issue, they all use sbrk. Since I compile with -ffreestanding, I don't have access to sbrk. So, how can I allocate memory without using sbrk?

I'm new to OS development so I apologize in advance.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Freestanding c memory manager without sbrk()

Post by iansjack »

Implement your own version of sbrk?
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Freestanding c memory manager without sbrk()

Post by nullplan »

malloc() is several levels too deep already. First you need a physical memory manager. Your boot environment tells you where the RAM is, and you need a function that returns free physical addresses and marks them as used at the same time. Common solutions to this include free lists, a stack, and bitmaps.

You will also need a virtual memory manager. That is, you will need some kind of virtual memory layout for kernel space. In Long Mode you have so much virtual memory that it might be sufficient to just use a High Water Mark allocator for virtual memory.

Finally, you will need code to connect the two. Set up page tables, set up Virtual Memory Areas (VMAs), make it possible to resolve page faults.

Once you have all of these, you can start to implement a general purpose malloc(), because now you can allocate whole pages. malloc() is more about dividing the memory down into smaller chunks such that you don't waste too much.

If you've never thought about any of the above, now is the time. This is where you have to start designing, and not blindly following tutorials.
Carpe diem!
isaiah0311
Member
Member
Posts: 25
Joined: Tue Mar 09, 2021 9:31 pm
Libera.chat IRC: isaiah0311

Re: Freestanding c memory manager without sbrk()

Post by isaiah0311 »

iansjack wrote:Implement your own version of sbrk?
I didn't think it was going to be that easy, it was. Thank you. I found a simple sbrk online and implemented it. It seems to be working now.
nullplan wrote:malloc() is several levels too deep already. First you need a physical memory manager. Your boot environment tells you where the RAM is, and you need a function that returns free physical addresses and marks them as used at the same time. Common solutions to this include free lists, a stack, and bitmaps.

You will also need a virtual memory manager. That is, you will need some kind of virtual memory layout for kernel space. In Long Mode you have so much virtual memory that it might be sufficient to just use a High Water Mark allocator for virtual memory.

Finally, you will need code to connect the two. Set up page tables, set up Virtual Memory Areas (VMAs), make it possible to resolve page faults.
So right now I have a virtual memory manager (or at least I think), which uses a union to hold a struct of header data and then a 16 byte stub for alignment. This is similar to the flat list example on the page frame allocation page on the wiki.

As for the physical manager, I'm not so sure if my code does that. I have a char global_memory[20000] variable that gets used in sbrk. I don't know if this is what you mean?

Code: Select all

char global_memory[20000] = { 0 };

void* sbrk(int increment) {
	char* p_break = global_memory;
	char* const limit = global_memory + 20000;
	char* const original = p_break;

	if (increment < global_memory - p_break || increment >= limit - p_break)
		return (void*) -1;
	p_break += increment;
	return original;
}
rdos
Member
Member
Posts: 3297
Joined: Wed Oct 01, 2008 1:55 pm

Re: Freestanding c memory manager without sbrk()

Post by rdos »

nullplan wrote: Finally, you will need code to connect the two. Set up page tables, set up Virtual Memory Areas (VMAs), make it possible to resolve page faults.
I think defining where kernel memory starts & ends + implementing the page fault handler will do. At least if you let the page fault handler fix the page directory and ptr levels too. You could allocate those on startup too, but I think letting the pagefault handler do it is more attractive. If you setup these pages as zeros, then you can assume that unallocated pages are zero entries, and then there is no need for setting up VMAs. When malloc() tries to access something in it's area, you simply let the pagefault handler allocate a physical page and set it up as kernel read&write. Also note that malloc() should not zero all of the area it uses, as this would allocate all the physical memory. Rather, it should avoid touching areas it doesn't do allocations in.

Also, I think a kernel also should have a 4k aligned (page table entry) allocation method. And probably a more efficient method to allocate many entries of the same size.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: Freestanding c memory manager without sbrk()

Post by nexos »

@isaiah0311: Your code actually has a major bug. The variable p_break must be a global variable. Else, every allocation will overwrite the last one!

Also, that global_memory array is not going to work for very long. You see, your kernel will have way more then 20000 bytes it allocates. You need a way of being even more dynamic. Have a look at https://wiki.osdev.org/Brendan%27s_Memo ... ment_Guide. This should give some direction.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Post Reply