Page 1 of 1

Memory Management Question

Posted: Fri Aug 24, 2007 10:46 am
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

Posted: Fri Aug 24, 2007 1:42 pm
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?

Re: Memory Management Question

Posted: Fri Aug 24, 2007 7:09 pm
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...

Posted: Fri Aug 24, 2007 8:06 pm
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.

Posted: Fri Aug 24, 2007 8:12 pm
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!

Posted: Sat Aug 25, 2007 8:34 am
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.

Posted: Sat Aug 25, 2007 8:48 am
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.