Initialization Order of Operations – getting to pmode

I was playing around with my initialization code and realized I had a problem. I had stripped down my boot sector so that it basically just loaded up my environment initialization code (which is a mixture of assembly and C) and threw control to that. I eliminated the code that enabled the A20 gate (since I moved this to the init code) and removed the code that put the processor into protected mode with a simple flat memory mode. However, when I tried to boot my code in the emulator, it would triple fault, which basically means the processor was put into a bad state and pooped out.

After thinking about it for a bit, I realized my error. By removing the code that put the processor in protected mode, I was keeping things running in 16-bit real mode. The initialization code that I was trying to pass control to was compiled as a 32-bit ELF file and converted to a 32-bit flat binary file. If I wasn’t putting the processor into 32-bit protected mode, then I obviously couldn’t hand it a bunch of 32-bit code to execute.

Duh.

So I restored the code that puts the processor into 32-bit protected mode, using a very simple GDT that sets up a flat memory model. Voila! Everything was back in working order. I was hoping to delay enabling 32-bit protected mode until I had the environment completely set up, but instead I will have to go with the following strategy:

1. In the boot sector, load up the initialization code into memory, enable the A20 gate, and enable pmode with a simple flat memory model. Then hand control to the initialization code.

2. In the initialization code, fully set up the operating environment – set up the proper GDT, IDT, TSS, setup paging, etc, etc. Load up the kernel. Then activate the new memory model, turn on paging, load up the interrupts, and refresh pmode. Once we’ve got a properly initialized environment, hand over control to the kernel.