Preparing to boot the kernel

Although wonderful full downloaders are available, I wrote once in my free time as a training exercise. I ran into a problem.

I can bootstrap and load the chain of other sectors without problems. If I were writing my own OS, it would be nice for me to go. :) Instead, I'm trying to boot Linux. The challenge that I am experiencing is twofold.

  • I understand that I need to load the kernel (Linux) into memory at 0x100000 . I know that I have to find the signature "HdrS" at offset 0x202 of the kernel. I also know that the start address must be at 0x214. However, when I go to the address in this place, it stops. Obviously, it’s rather difficult to wrap the debugger around this. :) Am I missing something in this chain of facts needed to determine the correct kernel start address?
  • I suspect that the answer to (1) may be related to the need to populate some memory area with information about hardware detection. I saw several links to this on the OSDev Wiki , but it seems I don’t see where it is and what kind of data should be there. Is the bootloader responsible for hardware discovery? If so, what data needs to be placed where?

One more note: I'm already in 32-bit protected mode, because I'm dealing with the creation of an EFI boot system, so 16-bit real mode is actually not an option that eliminates the beginning of the real location mode in the kernel.

+5
source share
1 answer

@Jester found my problem and answered both questions. The solution was actually in the file that I linked , although I skipped the corresponding section. I include here the relevant material for posterity:

In the 32-bit boot protocol, the first step in booting the Linux kernel is to configure the boot parameters (struct boot_params, traditionally called the "zero page"). The memory for struct boot_params must be allocated and initialized to all zero. Then, the installation header from offset 0x01f1 of the kernel image must be loaded into the boot_params structure and examined. The end of the installation header can be calculated as follows:

0x0202 + byte value with offset 0x0201

In addition to reading / modifying / writing the installation header of the boot_params structure, as with the 16-bit boot protocol, the loader must also fill in the additional struct boot_params fields, as described in the zero-page.txt file.

After configuring struct boot_params, the bootloader can load the 32/64-bit kernel in the same way as for the 16-bit boot protocol.

In the 32-bit boot protocol, the kernel is started by navigating to the 32-bit kernel entry point, which is the starting address of the loaded 32/64-bit kernel.

When entering, the CPU must be in 32-bit protected mode with paging disabled; GDT must be loaded with descriptors for the __BOOT_CS (0x10) and __BOOT_DS (0x18) selectors; both descriptors must be 4G flat segment; __BOOT_CS must have permission to execute / read, and __BOOT_DS must have permission to read / write; CS must be __BOOT_CS and DS, ES, SS must be __BOOT_DS; interruption must be disabled; % esi should contain the base address of the boot_params structure; % ebp,% edi and% ebx must be zero.

64-bit instructions can also be found in the same document.

+2
source

Source: https://habr.com/ru/post/1238452/


All Articles