Restart/Reiterate Everything. Voila the Long Mode!

It’s been a month – pretty long vacation away from my most beloved hobby, but I’m just a human, I have my needs. I like snowboarding, so I went to Austria and did a proper powder riding. I’m still playing in the band, and I did a few gigs here in Riga. And last but not least – I have a job – and deadlines are killing me. But enough of appologies, here it is…

OK, here it comes – every time I’m trying to write a software, or walk into the unknown in general, I reach the point where everything needs to be restarted from the beginning. Usually it’s because of many unknowns that I come across while building some new shiny toy software. It ends up in unmaintainable mess. The same story applies to my OS. So this is my rewrite story (probably No.1 in the series).

First of all, I was stuck in 32-bit mode (for too long) – and as it goes with the C, every function is global and you have to start naming them according to modes, like main16, main32, etc. – messy. Then there are problems with doing things that are not necessary, but you write them as soon as you can, just to understand how this stuff works – think interrupt handlers, APIC and ACPI in Protected Mode, while my aim is to be in full-blown 64-bit (Long) mode. So I need to move them to long mode and do as-less-as-possible to enter 64-bit mode. And then there was this thing called Paging – I have to write down this simple sentence  “Table, as far as Intel is concerned, are just chunks of bytes divided in equally defined structures” “Table is simply an array”!

So I did a complete rewrite, and now my bootstrap code does the bare minimum:

  1. Prepare registers in assembly.
  2. Jump to C which is compiled to Real Mode code.
  3. While in Real Mode do necessary queries from BIOS:
    1. Setup video mode;
    2. Enable A20 gate;
    3. Read E820 memory map;
    4. Filter and sort E820 memory map.
  4. Return to bootstrap assembly;
  5. Do a Protected mode jump (with hard coded GDT) as it was not possible to set up PML4 tables in segmented Real Mode while GCC is completely oblivious about segments.
  6. Jump to C (that’s compiled as a regular Protected Mode code) again to setup PML4 paging tables that map at least 16MB of RAM.
  7. Return to bootstrap assembly.
  8. Do the final preparations and a jump into Compatibility Mode and in Long Mode right after that.

Voila! We’re in Long Mode and we jump to C for the last time (hopefully), where all the magic can finally happen.

The Source as always is available on GitHub.