Even though there are wonderfully complete boot loaders available, I've been writing one on and off in my spare time as an educational exercise. I've run into a problem.
I am able to perform an initial boot and chain load other sectors with no problem. If I were writing my own OS I'd be good to go. :) Instead, I'm trying to bootstrap Linux. The challenge I'm having is two-fold.
An additional point to take note of is that I am already in 32 bit protected mode because I'm dealing with creating an EFI boot system, so 16 bit real mode isn't really an option here, eliminating the real mode start location in the kernel.
@Jester found my issue and answered both questions. The solution was actually in the file that I had linked, though I had missed the relevant section. I'm including the relevant piece here for posterity:
In 32-bit boot protocol, the first step in loading a Linux kernel should be to setup the boot parameters (struct boot_params, traditionally known as "zero page"). The memory for struct boot_params should be allocated and initialized to all zero. Then the setup header from offset 0x01f1 of kernel image on should be loaded into struct boot_params and examined. The end of setup header can be calculated as follow:
0x0202 + byte value at offset 0x0201
In addition to read/modify/write the setup header of the struct boot_params as that of 16-bit boot protocol, the boot loader should also fill the additional fields of the struct boot_params as that described in zero-page.txt.
After setting up the struct boot_params, the boot loader can load the 32/64-bit kernel in the same way as that of 16-bit boot protocol.
In 32-bit boot protocol, the kernel is started by jumping to the 32-bit kernel entry point, which is the start address of loaded 32/64-bit kernel.
At entry, the CPU must be in 32-bit protected mode with paging disabled; a GDT must be loaded with the descriptors for selectors __BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat segment; __BOOT_CS must have execute/read permission, and __BOOT_DS must have read/write permission; CS must be __BOOT_CS and DS, ES, SS must be __BOOT_DS; interrupt must be disabled; %esi must hold the base address of the struct boot_params; %ebp, %edi and %ebx must be zero.
64 bit instructions can also be found in this same document.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With