Memory Management Question

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
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Memory Management Question

Post by Alboin »

(Please excuse me if I sound like I've lost my mind, but I haven't done any real osdev in a few years.)

I've been working on the memory management part of my kernel, and have been thinking about writing kmalloc and such as to make kernel work a tad easier. (Note: I'm using paging.)

I was reading about ways to do this and that, linked lists, trees, etc. and I thought: "If I'm using paging, than can't I take a lot of small chunks of physical memory and make it appear to be continuous?" For example, if I were to use a list of physical memory like:

Code: Select all

|        16k         |      8k       |  2k  | ....
(Obtained from the physical memory manager.)

Then, if I were to call something like:

Code: Select all

ptr = kmalloc(12);
I would take the 8k, 2k, and 2k from the 16k and map them to one continuous region in the process's page tables.

So, when I would free the memory, I would just unmap them from the process's memory and set them to free in my list.

I wouldn't need to search at all. All I would need would be to take any region smaller or equal to or greater than what I needed until I had the amount. If there wasn't a piece small enough I would just ask for more physical memory from the kernel and break that up.

Am I really off? Have I lost my mind? Would this even work? I feel as though I am forgetting something important.... :-k

Thanks!
Alboin
C8H10N4O2 | #446691 | Trust the nodes.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Hmmm... sounds confused to me. Pages are 4 kilobyte in size. The whole shebang malloc()'s do with lists etc. is because you don't want to allocate a 4k page just because someone requested a single byte, now would you?
Every good solution is obvious once you've found it.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Re: Memory Management Question

Post by Alboin »

Solar wrote: Hmmm... sounds confused to me. Pages are 4 kilobyte in size. The whole shebang malloc()'s do with lists etc. is because you don't want to allocate a 4k page just because someone requested a single byte, now would you?
Even in my mass confusion, I do know what malloc does. ;)

Note: This is about a virtual memory manager. It is assuming I have the physical memory manager all set and ready to go.

Anyway, I think I fixed the part that was confusing. Here is a revised post:
I was reading about ways to do this and that, linked lists, trees, etc. and I thought: "If I'm using paging, than can't I take a lot of small chunks of physical memory and make it appear to be continuous?" For example, if I were to create a list of free physical memory obtained through the physical memory manager:

Code: Select all

|        16 bytes        |      8 bytes       |  2 bytes  | ....
Then, if I were to call something like:

Code: Select all

ptr = kmalloc(12);
I would take the 8, 2, and 2 from the 16 and map them to one continuous region in the process's page tables. There would be no need for the allocated memory to actual be continuous. It would just appear continuous to the calling party.

To free the memory, I would just unmap them from the process's memory and set them to free in my list.

There would be no searching for a 'right' fitting sized chunk of memory at all. All that would be needed would be to go through the list of free regions and gather chunks of memory until there was enough. Moreover, if a region was larger than what was needed, it could be broken apart.
Thanks...
C8H10N4O2 | #446691 | Trust the nodes.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

As said above, the only size of vmem chunk that can be mapped is 4Kb (unless you want to map 4Mb, as I recall). You can't remap 2Kb or 2 bytes all by themselves under any circumstances. If you get a request to allocate 12Kb of vmem, then your vmem manager can (and should!) map that using the first 3 unallocated 4K vmem pages that it can find, however.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

bewing wrote:As said above, the only size of vmem chunk that can be mapped is 4Kb (unless you want to map 4Mb, as I recall). You can't remap 2Kb or 2 bytes all by themselves under any circumstances. If you get a request to allocate 12Kb of vmem, then your vmem manager can (and should!) map that using the first 3 unallocated 4K vmem pages that it can find, however.
#-o That's it! I knew there was something wrong!

Thanks again!
C8H10N4O2 | #446691 | Trust the nodes.
User avatar
Kevin McGuire
Member
Member
Posts: 843
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Post by Kevin McGuire »

They are layered, and the units can easily be 4096 bytes.

[physical page management] // global to the system
address ppm_alloc(); // single unit of memory
address ppm_alloc(count); // contiguous units of memory
address ppm_alloc(where, count); // contiguous units of memory
[virtual page management] // local to the process/address-space
address vpm_alloc();
address vpm_alloc(count);
address vpm_alloc(where, count);
[heap management] // local to the process or kernel
address malloc();
address free();

Where the vpm_* set of functions are local to the process/address-space, and there may exist many address-spaces. The ppm_* set of functions are global, while the heap functions are normally local to the image loaded into memory -- or the kernel image in it's little area of memory.

Some people split the linear(virtual) address space for _every_ process:
0GB - 2GB (User Land)
2GB - 4GB (Kernel Land)

Where the kernel's private vpm_* calls only work in the kernel land, and vpm_* call for user land only work in the user land. There is also generally a malloc implemented for the kernel which only works in kernel land, and the same for user land.

These allows switching back into the kernel with out changing address spaces, which makes system calls faster and such. Linux/Windows do this.

The important part is that the vpm_* functions use the ppm_* functions to acquire memory, while the heap functions use the vpm_* functons instead of the ppm_* functions.

[physical]->[virtual]->[heap]

The actual implementation of the heap (it's mechanism for breaking units/block/pages of memory into requested sizes) is up to you.
I wouldn't need to search at all. All I would need would be to take any region smaller or equal to or greater than what I needed until I had the amount. If there wasn't a piece small enough I would just ask for more physical memory from the kernel and break that up.
Once you broke this unit of memory that you allocated you would have to start searching it, right?

The malloc calls are going to be requested memory in sizes of 0 to 4096 bytes usually, these are very small chunks of memory. I would imagine you would be forced to break up a 4096 byte unit of memory unless you wanted to waste a lot of memory -- which is exactly why malloc is a little hard to implement.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Kevin McGuire wrote:Once you broke this unit of memory that you allocated you would have to start searching it, right?
Yes, yes. I was under the impression that I could map an area smaller than 4k, you see. That was my problem.
C8H10N4O2 | #446691 | Trust the nodes.
Post Reply