Page 1 of 1
Using memory during boot
Posted: Wed Mar 21, 2012 7:05 pm
by bradhe
So my silly kernel can boot (kind of). Now I'd like to be able to allocated and use memory.
I'm using the int15 e820 API to detect memory, and that seems to be working just fine. I've implemented it in ASM, and call it from C. What I'd like to do, though, is pass a pointer to a location in which the table built by int15 e820 can be stored, and then return the number of records in the table. The prototype would like something like this:
Code: Select all
extern int detect_memory_e820(void **);
My question is: When I can't tell if I'm going to step on someone else's in-use memory, how should I reserve (I don't think allocate is the right word here) memory for use like this? What is the best practice before you have an allocator init'd and working? Or does it even matter, maybe I'm over thinking it or misunderstand something?
Thanks!
Re: Using memory during boot
Posted: Wed Mar 21, 2012 10:31 pm
by Nessphoro
I assume this is at boot-time.
If so, then you don't need to worry about "step[ing] on someone else's in-use memory," because there is no such thing as "someone else."
Now all you need is some kind of static allocator, which won't be able to recycle memory (but the memory map is probably not gonna change).
A simple static allocator might look like this.
Code: Select all
unsigned int KernelEnd; //End of your kernel data
void* Allocate(unsigned int Size)
{
void* allocated=(void*)KernelEnd;
KernelEnd+=Size;
return allocated;
}
Re: Using memory during boot
Posted: Wed Mar 21, 2012 11:14 pm
by bradhe
Nessphoro wrote:I assume this is at boot-time.
If so, then you don't need to worry about "step[ing] on someone else's in-use memory," because there is no such thing as "someone else."
Now all you need is some kind of static allocator, which won't be able to recycle memory (but the memory map is probably not gonna change).
A simple static allocator might look like this.
Code: Select all
unsigned int KernelEnd; //End of your kernel data
void* Allocate(unsigned int Size)
{
void* allocated=(void*)KernelEnd;
KernelEnd+=Size;
return allocated;
}
Yup, wow that is simple. Thank you
Re: Using memory during boot
Posted: Thu Mar 22, 2012 8:07 am
by brain
There is 'someone else' in terms that the bios, pci devices etc all reserve ram that you cant use.
At least within protected mode this ram must be excluded from allocation, usually by not putting it into the pagetables of a process and making the process memory model appear one flat continous memory block.
The bios call you are using indicates the regions you shouldnt touch, take note of its values and be carerful not to tread on any reserved memory ranges or you could cause all kinds of hell such as remapping pci irqs or writing to LFB's of graphics cards etc, or worse! At very least, your OS won't work as expected when it accesses these areas.
Re: Using memory during boot
Posted: Thu Mar 22, 2012 8:26 am
by bluemoon
bradhe wrote:My question is: When I can't tell if I'm going to step on someone else's in-use memory, how should I reserve (I don't think allocate is the right word here) memory for use like this? What is the best practice before you have an allocator init'd and working? Or does it even matter, maybe I'm over thinking it or misunderstand something?
Thanks!
I do it this way:
Code: Select all
1. scan the memory map and calculate the amount of memory need to setup my page allocator (for stack, it is number of free pages * 4 or 8, or 4MiB for ~4GiB ram)
2. find a region in the memory map that have enough room to store the structure of (1), remember the starting end ending position (just 2 integers)
3. map those pages
4. loop thru' the memory map, for each free page:
4.a) if page < 1M, I simply skip it so it is not available to allocation at all
4.b) skip if the page is the kernel body, bss, or stack
4.c) skip if the page is within the region of (2)
4.d) OK, the page is usable, put it into the structure located on (3)