Project Goal Set II - Getting Booted Up!
This week's goal is to lay the foundation for our operating system. You can't have an OS unless you can bootstrap it! So what is bootstrapping? Well, the term comes to us from old cliche of "pulling oneself up by one's bootstraps", an impossible proposition! In computer science, we refer to a bootstrap process as a self-starting process which has no former starter.
For us, the process of booting begins with the BIOS (Basic Input/Output System). This will load the first sector of disk, which contains a 512 byte bootloader. Our bootloader will set up a few things in real mode and then switch to protected mode. From there it sets up some necessary registers and then it calls bootmain, which is C code. bootmain loads the rest of the kernel, and then jumps into the entry point of the elf file. This week, we should focus on getting that far in our operating system!
Writing a Bootloader
Are you nuts?! There's a perfectly good bootloader in Xv6. Study it, sure, but I see no reason to write our own. Have a look at the bootasm.S file, study it until you have a more or less vague idea of what is going on. After you've done that, copy the file to your own directory and revel in the knowledge that you've just broken ground on your new OS!
We should create a function for the bootloader to call. As we have stol... borrowed a bootloader we should do what it expects! One great way to do this would be to copy the bootloader.c file. After a quick glance at the incredibly permissive LICENSE file, we can see that this will be totally cool with the good folks over at MIT, so why not? Copy that file to your directory as well!
Writing the Kernel Entry
Ok, so now we should get down to business and write our kernel entry point. There is some stuff that has to happen. Most multiboot loaders (like GRUB and the Windoze Loader thingy) expect a certain signature to kernels. We should provide that. After that we should set up a default page directory, turn on paging, and then jump into the kernel's main function. You know what, this is all sounding fairly generic! Let's copy the entry.S file (after studying it of course!)
Writing our main.c File
Enough with the blatant stealing of code. Write your darn main function! Make it loop forever. Oh, and you'll also want to set up that default page directory. Look at xv6's main.c to figure out how to do that.
Finishing up our Theft
Go through all the files you've copied. If they reference a .h file, make sure to pull that header file over. I'd give you a list, but I want to force you to read some code!
Starting Your Makefile
Here's where it all comes crashing down! You need to make your own Makefile, one which can compile a working kernel, and one which can also start qemu-nox and qemu-nox-gdb targets. You can copy some of this from the xv6 Makefile, but you are really going to have to study how this thing works. Simply copying it won't do! It shouldn't take you too long to work out how to make this target work, though if you really really have trouble with it, I may share my Makefile with you in class.
Testing and Wrapping Up
If you've done this correctly, you will have copied a fair bit of code, written like 2 lines of code that just spins, and copied a prodigious amount of build script goodness. Test your OS by using a qemu and gdb to verify that you've reached your kernel. Make sure that you know for certain that your main function is running. Next week we will start making this do stuff!