A while back, a friend and I tried to write a kernel in C following a tutorial. After enabling interrupts, it would receive a never ending stream of GPFs, which were correctly handled by the IDT. However, adding random bits of C code here and there made the kernel either work or break, depending on how gcc felt like compiling it. Thus, we gave up on the project.
Now, I am attempting to rewrite the kernel, but I am writing the simple portions in assembly, since I know much more about how assemblers assemble assembly than how compilers compile C. However, my new kernel errors out in the same place in the same way. Something is going wrong in my code, and I have no idea what it is.
I have run the kernel on my laptop directly, in qemu, and in bochs. Each of them causes it to receive a never-ending stream of GPFs. However, the associated error code changes slightly. On my laptop, I receive an error code of 528 whereas both qemu and bochs get error code 512. I have not been able to find any reference on what these error codes mean, so I haven't been able to debug it that way. However, when running in bochs, each GPF is associated with the following error message:
00007573171e[CPU0 ] fetch_raw_descriptor: GDT: index (207)40 > limit (17)
where the initial hex number increments by 0x30 each time.
I have figured out that this error message means that something is attempting to access 0x40 in the GDT, but for the life of me I can't figure out what that something is.
Here is the code which should set up the GDT. I have compared it to many working kernels, and they are essentially identical, the only differences being AT&T v. Intel syntax and far jumping before/after loading the other segment registers.
Code: Select all
global init_gdt
align 32
init_gdt:
lgdt [gdtr]
mov ax,0x10
mov ds,ax
mov es,ax
mov gs,ax
mov fs,ax
mov ss,ax
jmp 0x08:gdt_return
gdt_return:
ret
section .data
the_gdt:
null_desc:
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
flat_code:
db 0xff,0xff,0x00,0x00,0x00,0x9a,0xcf,0x00
flat_data:
db 0xff,0xff,0x00,0x00,0x00,0x92,0xcf,0x00
gdt_end:
gdtr:
dw gdt_end-the_gdt-1
dd the_gdt
Code: Select all
call init_gdt
Code: Select all
mov ax,0x10
However, if i place an infinite loop after the next line:
Code: Select all
mov ax,0x10
mov ds,ax
I have searched these forums and other locations for similar behavior, but with no success. Perhaps one of you has encountered a similar error and could help shed some light on the situation?