I’m writing a basic bootloader just to the point where I have some sort of environment where I can write a simple C program, write it to a hard disk (no file system), and run it. That’s all I want to do.
Here is what I’ve done so far.
Stage 1:
- Set up stack and segment registers
- Change video mode to 640x480x8
- Read the next sector to memory
- far jump to it
Stage 2:
- Set up the stack and segment again (do I need to do this again?)
- Set up the GDT (this part confuses the heck out of me – TBH I just copy/paste)
- Enable A20 gate
- Enter protected mode
I have entered protected mode successfully before, but for some reason now I can’t. Bochs goes into a boot loop when I try, but as far as I can tell the code is identical to the old code that worked.
I’ve tried commenting out the call to enable A20 and GDT, but that didn’t prevent the boot loop.
I have my entire bootloader code here on PasteBin, but I’ll put some stuff here also:
Setting up the stack:
CLI ;Disable interrupts while setting up the stack
XOR AX,AX ;Real mode flat memory model
MOV DS,AX
MOV ES,AX
MOV FS,AX
MOV GS,AX
MOV SS,AX
MOV SP,0xFFFF
STI ;Enable interrupts
Enabling A20:
MOV AX,0x2401
INT 0x15
RET
Entering protected mode:
MOV EAX,CR0
OR EAX,1
MOV CR0,EAX
The GDT code is a bit long-winded and I didn’t write it myself. But, as I said, not loading the GDT doesn’t prevent the boot loop later.
By the way… if you have any general comments about my bootloader (it’s my first), feel free to mention them.
A “boot loop” probably means that your code is triple-faulting.
Since you’re running in a virtual machine anyway, I’d suggest trying
qemu, for two reasons. First, that Wikipedia article says, “In QEMU, a triple fault produces a dump of the virtual machine in the console, with the instruction pointer set to the instruction that triggered the first exception.” Having the emulator point you at the exact instruction that’s failing will make your debugging so much faster.Second, if that isn’t enough, QEMU supports attaching
gdbto the virtual CPU, which allows you to single-step through your code, print register contents, and all the usual things. See theqemumanual page for the-gdboption.