I am writing a toy kernel for learning purposes, and I am having a bit of trouble with it. I have made a simple bootloader that loads a segment from a floppy disk (which is written in 32 bit code), then the bootloader enables the A20 gate and turns on protected mode. I can jump to the 32 bit code fine if I write it in assembler, but if I write it in C, I get a triple fault. When I disassemble the C code I can see that the first two instructions involve setting up a new stack frame. This is the key difference between the working ASM code and the failing C code. I am using NASM v2.10.05 for the ASM code, and GCC from the DJGPP 4.72 collection for the C code.

This is the bootloader code:

org 7c00h
BITS 16

entry:
mov [drive], dl         ;Save the current drive


cli
mov ax,cs               ; Setup segment registers
mov ds,ax               ; Make DS correct
mov ss,ax               ; Make SS correct        

mov bp,0fffeh
mov sp,0fffeh           ;Setup a temporary stack
sti

;Set video mode to text
;===================
mov ah, 0
mov al, 3
int 10h
;===================

;Set current page to 0
;==================
mov ah, 5
mov al, 0
int 10h
;==================

;Load the sector
;=============
call load_image
;=============

;Clear interrupts
;=============
cli
;=============

;Disable NMIs
;============
in ax, 70h
and ax, 80h ;Set the high bit to 1
out 70h, ax
;============

;Enable A20:
;===========
mov ax, 02401h
int 15h
;===========

;Load the GDT
;===========
lgdt [gdt_pointer]
;===========

;Clear interrupts
;=============
cli
;=============

;Enter protected mode
;==================
mov eax, cr0
or eax, 1       ;Set the low bit to 1
mov cr0, eax
;==================

jmp 08h:clear_pipe  ;Far jump to clear the instruction queue


;======================================================
load_image:
reset_drive:
    mov ah, 00h
    ; DL contains *this* drive, given to us by the BIOS
    int 13h
    jc reset_drive

read_sectors:
    mov ah, 02h
  
Edit
Report