Grub Multiboot2 Kernel Physical Address
Posted: Fri Jan 10, 2020 5:31 am
Hi everyone, I looked around for this information but couldn't find a definitive answer so I will post here.
My question regards the physical location of my ELF-format kernel after being loaded by GRUB2.
As I understand it (please correct me if I'm wrong), since I'm using the ELF format, my kernel gets loaded at the physical address that I specify when linking it (through my linker script).
I played around a little with the script and i was able to get GRUB2 to put the kernel pretty much where I wanted in main memory.
Now my first question is, if I don't specify a location, GRUB2 puts my kernel at physical address 0 (which I thought was not available) and everything works fine. Why does it do that? How does it know that address 0 is a good place for my kernel?
I then printed the memory map from GRUB2 and it looks like the pic in the attachment (Qemu w/ 128MB RAM).
Now i can see that the first 0x09fc00 bytes are marked as available so, all in all, putting the kernel at 0 address is not a bad idea, but all of this knowledge I got after it was actually loaded.
I can, of course, specify where I want it loaded and I fooled around with it putting it in reserved memory places causing a crash which seems normal to me.
Am I wrong in saying that GRUB2 does some kind of 'thinking' and puts my kernel where it can find the first free memory chunk big enough to load the whole thing? If my kernel was bigger than 0x09fc00 and therefore couldn't fit the block of mem that starts at 0, would GRUB2 put it at 0x10000 (the first largest block that can fit my kernel) ?
More in general, can I forget about it and set the kernel loading address at 1MB (0x10000) in my linker script assuming that I have space ranging from there to the end of the free block to play around with?
As a last note, I set up the classic GDT with 1:1 mapping to physical addresses effectively ignoring segmentation.
I hope I was clear and didn't talk much bs,
thank you in advance.
FG
[EDIT]
I posted too soon, I managed to do some test and I answered some of my questions:
If I make the kernel large enough, GRUB2 won't change the loading address, it just loads it at 0 and run out of memory.
So I guess my question now is: can I always assume that starting from 1MB I will have a fairly large chunk of mem where to load my kernel?
My question regards the physical location of my ELF-format kernel after being loaded by GRUB2.
As I understand it (please correct me if I'm wrong), since I'm using the ELF format, my kernel gets loaded at the physical address that I specify when linking it (through my linker script).
I played around a little with the script and i was able to get GRUB2 to put the kernel pretty much where I wanted in main memory.
Now my first question is, if I don't specify a location, GRUB2 puts my kernel at physical address 0 (which I thought was not available) and everything works fine. Why does it do that? How does it know that address 0 is a good place for my kernel?
I then printed the memory map from GRUB2 and it looks like the pic in the attachment (Qemu w/ 128MB RAM).
Now i can see that the first 0x09fc00 bytes are marked as available so, all in all, putting the kernel at 0 address is not a bad idea, but all of this knowledge I got after it was actually loaded.
I can, of course, specify where I want it loaded and I fooled around with it putting it in reserved memory places causing a crash which seems normal to me.
Am I wrong in saying that GRUB2 does some kind of 'thinking' and puts my kernel where it can find the first free memory chunk big enough to load the whole thing? If my kernel was bigger than 0x09fc00 and therefore couldn't fit the block of mem that starts at 0, would GRUB2 put it at 0x10000 (the first largest block that can fit my kernel) ?
More in general, can I forget about it and set the kernel loading address at 1MB (0x10000) in my linker script assuming that I have space ranging from there to the end of the free block to play around with?
As a last note, I set up the classic GDT with 1:1 mapping to physical addresses effectively ignoring segmentation.
I hope I was clear and didn't talk much bs,
thank you in advance.
FG
[EDIT]
I posted too soon, I managed to do some test and I answered some of my questions:
If I make the kernel large enough, GRUB2 won't change the loading address, it just loads it at 0 and run out of memory.
So I guess my question now is: can I always assume that starting from 1MB I will have a fairly large chunk of mem where to load my kernel?