Page 1 of 1
Start of free memory in GRUB
Posted: Tue Feb 03, 2009 7:42 am
by AndrewAPrice
I'm loading my kernel using GRUB. I'm automatically assuming the start of the free memory is at 2MB, but I don't want to make this assumption anymore. How can I tell where the start my free memory is (that is, a pointer past my kernel, all the modules and GRUB structures, to where the great void* begins)?
Re: Start of free memory in GRUB
Posted: Tue Feb 03, 2009 8:13 am
by jal
MessiahAndrw wrote:I'm loading my kernel using GRUB. I'm automatically assuming the start of the free memory is at 2MB, but I don't want to make this assumption anymore. How can I tell where the start my free memory is (that is, a pointer past my kernel, all the modules and GRUB structures, to where the great void* begins)?
Iirc, GRUB passes the address and size of the modules. So the highest loaded module + its size os where you can start trashing things. If you do not have modules, you can always define some symbol at the end of your kernel, and use that as an offset (that's what I do currently).
JAL
Re: Start of free memory in GRUB
Posted: Tue Feb 03, 2009 8:21 am
by AJ
Hi,
The only way to accurately do this, is to use the memory map. You need to subtract all GRUB modules, strings and other data from this memory map, subtract your known kernel location (use start and end symbols) and then traverse this newly modified memory map looking for locations that the BIOS says are free.
I go through the memory map looking for the largest free memory range and use that as a basis for placing my kernel (well - second stage boot loader, really) heap. Problem is, if you are updating the memory map, you need a scratchpad area to do that in...
Cheers,
Adam
Re: Start of free memory in GRUB
Posted: Tue Feb 03, 2009 8:22 am
by Brendan
Hi,
MessiahAndrw wrote:I'm loading my kernel using GRUB. I'm automatically assuming the start of the free memory is at 2MB, but I don't want to make this assumption anymore. How can I tell where the start my free memory is (that is, a pointer past my kernel, all the modules and GRUB structures, to where the great void* begins)?
In theory, you can't assume that your code was booted from GRUB (it could've been booted by any multi-boot compliant boot loader) and the only thing you can rely on is that the boot loader is multi-boot compliant.
Unfortunately the multi-boot specification doesn't say anything about which areas are free to use (until you've parsed the multi-boot information structure and setup a memory manager or something, but you need to use some RAM to do that). The only sane way out of this is to use your code's ".bss" for everything initially.
For example, for my code I create a stack in my ".bss", then parse the multi-boot information structure and collect any information I need to keep in my ".bss". Then I setup a basic memory manager (a temporary "free page bitmap" for the first 32 MiB) in the ".bss", while marking any usable RAM as "free" and marking any RAM used by loaded modules as "not free". Then I use the temporary "free page bitmap" to allocate RAM for a full-sized "free page bitmap", and then use this full-sized "free page bitmap" for everything else.
The only other option is to use the area of RAM reserved for the BIOS, because the multi-boot specification says that the boot loader must leave the BIOS in a functional state. This means the RAM from 0x00000000 to 0x00000400 could be used by your code without worrying about overwriting the multi-boot information structure or loaded modules (but this is only an option if you never use the BIOS).
Note: If you only care about GRUB, then it seems to put data for the multi-boot information structure in the area between 0x00020000 and 0x00030000; with the "kernel" at 0x00100000 followed by any modules, where the modules are page aligned (regardless of whether you ask for them to be page-aligned or not). For example, if your "kernel" has 4 KiB of code/data and 8 KiB of ".bss", then the first module will probably start at 0x00103000. However this may depend on which version of GRUB, how it was compiled, which stages where installed, etc.
Cheers,
Brendan
Re: Start of free memory in GRUB
Posted: Tue Feb 03, 2009 10:07 am
by Combuster
You could also use the multiboot header to force a huge BSS section (and thus keep modules out of the first MBs after your kernel), which works independent of whatever multiboot compliant loader you are using.
Re: Start of free memory in GRUB
Posted: Tue Feb 03, 2009 1:59 pm
by jal
Combuster wrote:You could also use the multiboot header to force a huge BSS section (and thus keep modules out of the first MBs after your kernel), which works independent of whatever multiboot compliant loader you are using.
The problem with BSS sections is that Grub insists on zero-ing it. Yes, I know that's according to spec, but it's quite annoying if not needed, since rather slow in bochs :) (not only BSS, but all sections declared with nobits).
JAL