When the CPU is powered on, it is first reset to bring it to a predictable state.
The BIOS
The BIOS is a kernel in itself. It contains routines that assist the bootloader in booting the kernel.
BIOS is 16bit code.
BIOS routines are generic and standard to maintain compatibility.
The BIOS then loads itself into memory so that it’s faster and the CPU starts executing those instructions.
The instructions in the BIOS are the first to get executed by the CPU. The instructions initialize the hardware and then loads the bootloader into memory.
The BIOS looks for storage devices with booloader in them and loads them into address 0X7C00 and instructs the CPU to jump to that address and start executing. It generally looks for a boot signature 0X55AA in the last two bytes of a sector.
The Bootloader
Bootloader is a small program which is responsible for loading the operating system.
Bootloader then loads the os kernel.
When the CPU first boots, it’s generallyon compatibility mode. In Compatibility mode we have access to 1MB of RAM and runs only 16bit code.
The bootloader is thus small to be executed in the compatibility mode. So bootloader switches the processor into 32bit protected mode and give us access to 4GB of memory.
Bootloader uses functions available in the BIOS to assist itself.
Bootloader that prints onto the screen
Mark I - Print a single character
ORG is a assembler directive that changes the program counter. Because our bootloader loads into the address 0x7c00, by using this statement you are basically telling the assembler that your program starts at that address and then the assembler can take care of addressing for the subsequent statements.
BITS tells the assembler to support only 16bit code.
The aim here is to print a character to the screen and to do that we will be using a BIOS interupt.
As mentioned earlier BIOS provides multiple routines that assist bootloader to do its job.
And as also mentioned BIOS routines are generic. We will use one such generic interupt to print to the screen.
The times instruction prefix basically generated multiple copies of the instruction. In this case 510-( - \$) times. where
$ means the current address
$$ means the start address of the current section.
which basically computes to the remaining addresses until 510 that are left empty. those addresses will be filled with instruction db 0. We are basically adding padding until 510 bytes inorder to write the boot signature in the last two bytes, ie 511 and 512.
Then at last we declare a double word with the signature 0x55AA. It is written 0xAA55 in the code because intel x86 processors are little endian.
The above code prints the character ‘A’ on the screen.
Mark II - Print a string
This is not much different from what we did before.
Here we load the message label which contains the message Hello World! into the si register.
Then we call the print subroutine. Here we call lodsb, which basically reads the si register into al register and increments.
We compare if al is 0 and if not we call print, which again performs the interrupt that was mentioned earlier to print to the screen.
What Happens When A CPU Starts: https://lateblt.tripod.com/bit68.txt. (This artivle popped up in a TLDR newsletter on the day I started documenting this).