Ok so, some you might know that I’m making my own OS called BlackOS and due to my ultra-frequent updates on Facebook, you might also know that its something called boot-loader that I just coded… from scratch and on my own.
So what the hell is this boot loader and why do I create so much of cacophonous hype about it? I hope this series of posts, starting from scratch (how the system boots up), clarifies our billowing doubts. I’ll try my level best to make it a breeze as someone on Facebook asked me not to post anything too technical ;). A meagre amount of precursory knowledge maybe handy, maybe not, cuz if you can read between the lines a bit, you’ll grasp hold of “things” yourself.
<Wiki> Booting is a process in which your computer gets initialized. This process include all your hardware components in your computer and get them to work together and to load your OS which will make your computer operation. </Wiki>
Things start as soon as we press that small power-up button. The motherboard intializes its own firmware and other stuffs at this inchoate state. If its all done (yes, “if”… something can crop up like a faulty (or absent) CPU), CPU starts running. Nowadays, we have multi-core CPUs, so at the boot time, a CPU is dynamically chosen to be the bootstrap processor (BSP). This processor behaves like the “ancient” Intel 8086 processor and runs all the BIOS and other bootstrapping routines.
At this point of time, the processor is in the real mode. It can only address 1MB of memory and there is no protection ummm that is to say, any code can write anything anywhere in the memory any any any 😛
Now, after power up, all the CPU registers have defined values. Going more specific, EIP has some defined value and Intel CPUs use a hack that adds an offset to the value of the EIP so that it points to 0xFFFFFFF0. Yes, this is a hack as in real mode, CPU can only use 1MB of memory. This address is 16 bytes short of the end of 4GBs of memory. This is called the reset vector.
The motherboard ensures that the instruction at the reset vector is a jump instruction mapped to the BIOS’s entry point. Before this jump happens, implicitly, all hidden base addresses are cleared and all memory locations have the right value, “benevolence” of the memory map kept by the chip set. Keep in mind that these all memory locations are mapped to the flash memory containing the BIOS. Got it? Good :).
And now, the BIOS is executing!! I’m so happy :D!!! The BIOS runs the power-on self tests, POSTs in short. Things like missing video card or crappy hard drive complains are shown at this time. Not in the scope of this article, so I’ll skip. So, after doing “things”, BIOS tries to find the device having the OS. Choice of device is user configurable (the “first boot from” thing). Again, I’ll assume that BIOS finds the hard drive as the boot able device.
So, the BIOS reads the first 512 bytes (the first sector of the hard drive) and this is called the Master Boot Record (MBR). It consists of a tiny OS specific boot program and the partition table. The BIOS, irrespective of the contents of the MBR, loads the contents to the memory location 0x7c00. It then jumps to that location and starts executing whatever it finds there. The boot sector viruses infect the MBR and this is the way they start themselves at boot time. No, I never tried coding a boot sector virus, could be fun though ;). And this is the way all boot-loaders GRUB, LILO or NTLDR work.
This was the booting process, theoretically. There is one more complication (hack) though. Kernels these days are quite big and do not fit into the 1MB memory area available in the real mode of the processor. Still, the processor should be in real mode so as to use the BIOS. So the complication can be summed up as: “We have to use the BIOS, we cannot exceed 1MB mark and we still want to load our kernel.”. The solution to this is the unreal mode. This is not an “official” Intel operating mode. In short, it switches between protected mode and real mode to stuff the kernel into the memory by hook or by crook. And eventually leaves the processor in the real mode.
The next post shall explain the GDT (global descriptor table), the IDT (interrupt descriptor table) and also how to set up the GDT and the IDT. Probably after that we can take a look at the boot loader (OS specific boot loader) and try to understand how I coded my loader. 🙂
Till then, may the force be with you.
PS: this is a general theoretical article, you may find similar stuffs all over the internet and in all kinda books, if you find someone else’s explanation better, post a link in the comment and don’t bite me 😛 😀