I am writing a boot loader, and I've got most of the details down, but I am not sure why some boot loaders relocate themselves in memory before they begin the bulk of their execution.
Can anyone explain this?
An example of this behavior is the original v0.01 Linux kernel bootloader which has the following comment in it:
boot.s is loaded at 0x7c00 by the bios-startup routines, and moves itself out of the way to address 0x90000, and jumps there.
The bootloader is stored in the first block of the bootable medium. The bootloader is stored on a specific partition of the bootable medium.
So, we can clearly say, that the bootloader is neither stored in ROM, nor in RAM, It is actually stored on Hard disk (or other Boot device, such as bootable CDROM, USB drives etc) , precisely speaking the first sector of the hard disk, which is of size 512 bytes and often referred to as the boot-sector.
When a computer is powered-up or restarted, the basic input/output system (BIOS) performs some initial tests, and then transfers control to the Master Boot Record (MBR) where the boot loader resides. Most new computers are shipped with boot loaders for some version of Microsoft Windows or the Mac OS.
The boot loaders reside in each Windows partition. Once selected, the boot loaders take over the boot process and load the operating system in accordance with the selected boot parameters.
CookieOfFortune is essentially correct (Because he wanted to move something into the place where the initial bootloader was), but it wasn't for a second bootloader, but rather the kernel itself.
From his comments:
It then loads the system at 0x10000, using BIOS interrupts. Thereafter it disables all interrupts, moves the system down to 0x0000, changes to protected mode, and calls the start of system. System then must RE-initialize the protected mode in it's own tables, and enable interrupts as needed.
He wants the kernel to be located at 0x0000...0xKERNEL_SIZE-1, however the initial bootloader is currently at 0x7C00, so if the kernel was over ~32 KB it would overwrite the bootloader as it was moving it. The fact that the kernel is located at 0x0000 also explains this comment:
"NOTE! currently system is at most 8*65536 bytes long."
If it was any longer than 512 KB starting at 0 it would run the risk of hitting the reserved area of the x86 address space.
I believe this code section contains the actual jump into the kernel
mov ax,#0x0001 | protected mode (PE) bit
lmsw ax | This is it!
jmpi 0,8 | jmp offset 0 of segment 8 (cs)
From the linked article:
In practice, the MBR usually contains a boot loader whose purpose is to load another boot loader - to be found at the start of one of the partitions. This is often a very simple program which finds the first partition marked Active, loads its first sector into RAM, and commences its execution. Since by convention the new boot loader is also loaded to adress 7C00h, the old loader may need to relocate all or part of itself to a different location before doing this. Also, ES:SI is expected to contain the address in RAM of the partition table, and DL the boot drive number. Breaking such conventions may render a bootloader incompatible with other bootloaders.
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