Bootloader: Difference between revisions
Jump to navigation
Jump to search
[unchecked revision] | [unchecked revision] |
Content added Content deleted
m (fixed broken link) |
(Moved practical aspects to Rolling your own bootloader) |
||
Line 1: | Line 1: | ||
A bootloader is a program written to load a more complex [[Kernels|kernel]]. |
A bootloader is a program written to load a more complex [[Kernels|kernel]]. Implementation details are gathered in [[Rolling Your Own Bootloader]] |
||
== What does a bootloader do == |
== What does a bootloader do == |
||
Line 8: | Line 8: | ||
* Transfer control to the kernel |
* Transfer control to the kernel |
||
On the x86, the bootloader runs in |
On the x86, the bootloader runs in [[Real Mode]]. Consequently it has easy access to BIOS resources and functions. Therefore it's a good place to perform memory map detection, detecting available video modes, loading additionnal files etc. The bootloader will collect this information and present it in a way the kernel will be able to understand |
||
=== Loading your kernel === |
=== Loading your kernel === |
||
You will have to decide where in memory you are going to load your kernel. Your kernel generally depends on it. |
|||
In RealMode, the easiest is to stay below the 1MB barrier, which means you practically have 512KB of memory to load things. You may wish the kernel to be loaded at a well-known position, say 0x10000 physical (es=0x1000, bx=0 when calling INT13h). |
|||
If your kernel is bigger (or is expected to grow bigger) than this, you'll probably prefer to have the kernel above the 1MB barrier, which means you need to activate [[A20 Line|A20 gate]] and switch to [[Unreal Mode]] to load the kernel (with A20 alone, you cannot have more than 64K above 1MB). |
|||
Note that BIOS will still be unable to write to memory above 1MB, so you need to read stuff in a buffer below 1MB and then perform a rep movsd to place the data where they ultimately should go. |
|||
The bits of your kernel are somewhere on some disk (presumably the booting disk, but this is not mandatory). Question is: where on the disk ? Is it a regular file on a [[FAT|FAT-formatted]] floppy ? is it a collection of consecutive sectors in the "reserved area" of the FAT12 floppy (in which case you may need a dedicated tool to format the disk and install the kernel on it) ? Or is the floppy simply left unformatted and kernel pasted directly with a disk image tool |
The bits of your kernel are somewhere on some disk (presumably the booting disk, but this is not mandatory). Question is: where on the disk ? Is it a regular file on a [[FAT|FAT-formatted]] floppy ? is it a collection of consecutive sectors in the "reserved area" of the FAT12 floppy (in which case you may need a dedicated tool to format the disk and install the kernel on it) ? Or is the floppy simply left unformatted and kernel pasted directly with a disk image tool |
||
Line 29: | Line 23: | ||
Some kernels require some extra information to run. For example, You'll need to tell Linux the root partition to start from. Pretty useful information to have is a map of the address space - effectively a map of where physical memory is and where not. Other popular queries regard video modes. |
Some kernels require some extra information to run. For example, You'll need to tell Linux the root partition to start from. Pretty useful information to have is a map of the address space - effectively a map of where physical memory is and where not. Other popular queries regard video modes. |
||
In general, anything that involves a BIOS call are easier to do in [[ |
In general, anything that involves a BIOS call are easier to do in [[Real Mode]], so better do them while in real mode than trying to come back to real mode for a trip later. |
||
A very simple solution here is to organize your informations as a flat table (ala BIOS data area). An alternative could be to add those informations as a structured flow: you keep an index at a well-known address (or at some address you'll pass to the kernel when loaded) and that index gives for each "key" the address of the corresponding datastructure. E.g. |
|||
organization lookup code (eax == signature) |
|||
+------+------+ mov esi, well_known_index_address |
|||
| RAM. | 1234 | .loop: |
|||
| VBE. | 5678 | cmp [esi],'END.' |
|||
| MODS | 9ABC | je .notfound |
|||
| DISK | DEF0 | add esi,8 |
|||
| END. | ---- | cmp [esi-4],eax |
|||
+------+------+ jne .loop |
|||
mov eax,[esi] |
|||
ret |
|||
=== Establishing an environment === |
=== Establishing an environment === |