A much as I want to just jump in and start writing a bootloader, I know that I need to at least make a cursory attempt at some design decisions first.  After reading a thread on OS design archived by the site osdever.net, it seems that I have more decisions to make than I first realized.  Well, that’s what this project is about (learning, that is), so let’s make a list of some design decisions that will need to be addressed (I’ll update the post when I make a decision on some of these).

  • How will this thing boot (i.e, how much will the bootloader do)?
    • MBR –> VBR –> kernel?
    • MBR straight to kernel?
    • When to switch to protected mode–in the bootloader or let the kernel handle it?
  • What kind of memory model should I use?
    • Segmentation—Apparently not very portable
    • Paging—Flat memory model, neater, more portable
  • Where will the kernel get loaded in memory?
  • Does each process get its own address space?  (sounds like a no-brainer)
  • Virtual memory?
    • ???
  • Multi-tasking/Threading?
    • At this point I don’t think there’s a reason to even consider not doing multi-tasking; so, yes, please.  However, as if the rest of this didn’t scare me enough, for some reason this bullet point frightens me.
  • Build in locking and synchronization from the start
  • What sort of process model will I use?
    • I don’t even know where to start on this one
  • How will I handle system calls?
    • Linux uses software interrupts (or did in 2003…ah, the joys of 8-year-old articles)
    • No idea how Windows handles system calls
  • How should IPC be done?
    • From the article:  “Message ports? Named pipes? Queues? Local sockets? All of the above?"
  • Networking?
    • Probably not immediately important, but should be considered fairly early-on anyway
  • Which file system should I use?
    • Probably use FAT32 in the beginning, since the FATs seem to be some of the easier file systems to support
    • FFS?  ext2/3/4?  Probably waaaay down the road.
    • Write my own?  Even farther down the road, if at all
  • Security
    • I doubt that #include <securemysystem.h> would work
    • Everything should be built with security in mind—whatever the heck that actually means

List number next is the short-list of things that need to happen, and a crude outline of when they should happen:

  • Get my development environment set up
  • Bootstrap this bad boy.  Write a bootloader.  Probably a two-parter:
    • MBR that the BIOS will jump to, which will look for an active boot partition, and then jump to the…
    • VBR that does some basic setup, then finds and loads the kernel.
    • No, I don’t want to use GRUB.  That would be cheating if I want to learn how things work.
  • Write some kernel library functions to do things that the C library would normally handle for userland applications (printf(), malloc(), str*(), assert(), panic(), etc.)
  • Paraphrasing something I read recently:  “when writing a kernel, if you #include anything that you didn’t write yourself (like stdlib.h), you’re already doing it wrong."
  • Write a rudimentary console driver.
  • Write what will become the idle thread.
  • Get trap handling working
    • Article suggests that dumping state, then panicking the kernel is a good place to start
  • Get interrupt handling working
  • Write a handler for the timer interrupt.

Wow, those are pretty lengthy lists.