Own OS: First Successful Output

This may seem like a small accomplishment to many, but I now have Own OS boot code that takes one CPU core from 16-bit mode to 32-bit mode to 64-bit mode using code developed and assembled/linked with Inventor IDE.  Until now, so far as I’ve been able to find, no linker has supported 16-bit, 32-bit, and 64-bit code smoothly linked together in one output file.  If that’s the case, Inventor IDE is the first linker to support this, and it makes developing an operating system bootloader an absolute breeze compared with the alternative, which is to:

  1. The 16-bit Master Boot Record (MBR) or Boot Sector (BS) loads the rest of the 16-bit bootloader.
  2. The 16-bit bootloader finds and reads in a file on the drive containing the 32-bit bootloader with an entry point at a hard-coded address.
  3. Switch to 32-bit mode and jump to the hard-coded address.
  4. The 32-bit bootloader finds and reads in a file on the drive containing the 64-bit bootloader with an entry point at a hard-coded address.
  5. Switch to 64-bit mode and jump to the hard-coded address.
  6. The 64-bit bootloader actually starts loading the OS after starting the other CPU cores.

Now it’s as simple as:

  1. The 16-bit Master Boot Record (MBR) or Boot Sector (BS) load the entire rest of the bootloader.
  2. Switch to 32-bit mode and jump to the 32-bit starting function (address determined automatically by the linker)
  3. Switch to 64-bit mode and jump to the 64-bit starting function (ditto)
  4. The 64-bit function actually starts loading the OS after starting the other CPU cores.

Eliminating the need to find and read in files from a filesystem reduces the size and complexity of the code many-fold.  Plus, now the entire OS should easily fit in the 30KB of disk space I’ve got for the bootloader, so that first step will load the entire OS from the drive.  I would show a screenshot or photo, but it doesn’t write to the harddrive yet (it’s probably for the best), and I don’t have a working camera anymore.  Nonetheless, here’s roughly (just in a different font) what was output:

Output showing the PwnOS bootloader switching from 16-bit mode to 32-bit mode to 64-bit mode

Output showing the Own OS bootloader switching from 16-bit mode to 32-bit mode to 64-bit mode

There have been similar linkers for just 16-bit and 32-bit code, most notably JLOC.  I would link to the original site, but the site vanished many years ago, which explains why there’s no support for 64-bit code.  There’s also the standard linker for linux, LD.  Although it supports 64-bit code and has extensive scripting options, I can’t seem to find any evidence that it can link code of different modes together, not to mention that I’d still need to have a custom assembler to output data to some format it supports that keeps the necessary information.  Also, if LD supported this, linux could get to 64-bit mode in less than 1KB of code, and that certainly isn’t the case right now.

Hopefully other people will be up for trying this out with Inventor IDE Alpha 5b once it’s out (just the settings dialog box left).  Anyway, I’ve written some code for more extensive debugging that I’m anxious to test out, and I still need to get the other CPU cores up and running, but that should be much easier now.  😀

Advertisements

~ by Neil Dickson on June 7, 2009.

2 Responses to “Own OS: First Successful Output”

  1. Cool, good job with the innovative linker!

    I am curious as to how well it would run in an emulator; I happen to have one handy that supports multiple cpus in 64bit mode 🙂

  2. Hi Calvin!
    I’ll be sure to send over an image once I get multiple CPUs up and running. The basic debug logging seems to work okay, though I’ll need more stuff to output before it’ll be useful. 😉

    It’s funny the weird dependency chain I found way back when in order to start up the rest of the CPUs. First, I have to find any Interrupt Source Overrides in the ACPI tables, since it turns out that the Programmable Interval Timer usually gets moved from IRQ0 to IRQ2 nowadays. The timer’s needed to time the INIT-SIPI-SIPI sequence used to start the other CPUs, so if I expect it on the wrong IRQ, it doesn’t work. Before starting the INIT-SIPI-SIPI, though, I have to disable the old PICs and configure the I/O APIC in order to handle both the timer and the InterProcessor Interrupts. So much arbitrary work for so little, though hopefully there’s a way to figure out where the real RAM is using the ACPI tables, so it’s not completely a waste.

    Oh, and I’ve finally managed to figure out why it wasn’t working in QEMU; it turns out that the version of QEMU that works under 64-bit Vista doesn’t support many of the CPU features that I check for with CPUID. I’m not currently using most of those features, so it works if I just don’t check for them. 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: