GDT gets zeroed out and EIP = 0x3 based on qemu logs

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
DabiiXqx
Posts: 11
Joined: Sun Feb 15, 2026 12:06 am
Libera.chat IRC: dabii

GDT gets zeroed out and EIP = 0x3 based on qemu logs

Post by DabiiXqx »

[SOLVED]Hello everybody, I've recently been struggling with this bug that's making my GDT zeroed out and making my EIP go to 0x3.

I'm in intel 32 bit protected mode
I'm not using grub
I'm booting from hard disk, not iso
this is being run on qemu emulator

This only started happening after i started implementing the IDT. (It's partially implemented, it has bugs.)

Here is the log that shows the GDT zeroed out:

Code: Select all


SMM: after RSM
EAX=000000b5 EBX=00007d47 ECX=00005678 EDX=00000003
ESI=06f31fb0 EDI=06ffee71 EBP=0000695c ESP=0000695c
EIP=00007d47 EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =da80 000da800 ffffffff 00809300
CS =f000 000f0000 ffffffff 00809b00
SS =0000 00000000 ffffffff 00809300
DS =0000 00000000 ffffffff 00809300
FS =0000 00000000 ffffffff 00809300
GS =ca00 000ca000 ffffffff 00809300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT=     00000000 00000000
IDT=     00000000 000003ff
CR0=00000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000004 CCD=00000001 CCO=EFLAGS
EFER=0000000000000000
check_exception old: 0xffffffff new 0x6


Here's another log that shows the EIP = 0x3 (The gdt is not zeroed out here):

Code: Select all


     2: v=08 e=0000 i=0 cpl=0 IP=0008:00000003 pc=00000003 SP=0010:00090000 env->regs[R_EAX]=00000000
EAX=00000000 EBX=00009000 ECX=00000002 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00090000 ESP=00090000
EIP=00000003 EFL=00000082 [--S----] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00007c4a 00000017
IDT=     00000000 000003ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=f000ff54 CCO=INCL
EFER=0000000000000000
check_exception old: 0x8 new 0xd

Github repo: https://github.com/dabiiXqx/DabiiOS

If there's any documentation documenting this phenomenon, please list it here, whether it was from the intel manual or the OSDev wiki.

Help and advice is appreciated, Thank you.
Last edited by DabiiXqx on Fri Feb 20, 2026 12:19 pm, edited 1 time in total.
yucarp
Member
Member
Posts: 39
Joined: Fri Dec 05, 2025 5:19 pm
Libera.chat IRC: yucarp

Re: GDT gets zeroed out and EIP = 0x3 based on qemu logs

Post by yucarp »

Your QEMU logs aren't full, so the events that led to a triple fault are unknown. About the second one, your kernel function might be returning. Put a while loop into it.
nullplan
Member
Member
Posts: 2034
Joined: Wed Aug 30, 2017 8:24 am

Re: GDT gets zeroed out and EIP = 0x3 based on qemu logs

Post by nullplan »

You only have a single lgdt instruction in the entire codebase, and it doesn't even have a theoretical ability to set the base address to 0. Therefore your GDTR is getting reset by something else. The only thing I can think of that does something like that is a reset.

As for EIP being set to 3, I concur with yucarp that it is possible your kernel main function is returning. Normally, there is also the possibility of some buffer overflow somewhere, but I struggle to think where you might be reading input into a buffer in a kernel this simple.
Carpe diem!
User avatar
DabiiXqx
Posts: 11
Joined: Sun Feb 15, 2026 12:06 am
Libera.chat IRC: dabii

Re: GDT gets zeroed out and EIP = 0x3 based on qemu logs

Post by DabiiXqx »

nullplan wrote: Sun Feb 15, 2026 11:55 am You only have a single lgdt instruction in the entire codebase, and it doesn't even have a theoretical ability to set the base address to 0. Therefore your GDTR is getting reset by something else. The only thing I can think of that does something like that is a reset.

As for EIP being set to 3, I concur with yucarp that it is possible your kernel main function is returning. Normally, there is also the possibility of some buffer overflow somewhere, but I struggle to think where you might be reading input into a buffer in a kernel this simple.

Thank you for the advice, currenly i dont have any input going on since this OS is still in development, but do you have any clue to help me spot the cause of the reset? i can give more logs and information if you need.

And about the while loop at the end of main kernel, i jus added that but EIP still went to 0x3. so something else might be causing the 0x3 thing.
sebihepp
Member
Member
Posts: 256
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: GDT gets zeroed out and EIP = 0x3 based on qemu logs

Post by sebihepp »

I can't find the function "isr_common_stub" anywhere in your repo.
User avatar
DabiiXqx
Posts: 11
Joined: Sun Feb 15, 2026 12:06 am
Libera.chat IRC: dabii

Re: GDT gets zeroed out and EIP = 0x3 based on qemu logs

Post by DabiiXqx »

sebihepp wrote: Mon Feb 16, 2026 3:20 am I can't find the function "isr_common_stub" anywhere in your repo.

weird.

Code: Select all

%macro ISR_ERR 1
global isr_err%1
isr_err%1:
    push %1
    jmp isr_common_stub
%endmacro

%macro ISR_NOERR 1
global isr_noerr%1
isr_noerr%1:
    push 0
    push %1
    jmp isr_common_stub
%endmacro

extern func_table

ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR 8
ISR_NOERR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR_NOERR 15
ISR_NOERR 16
ISR_ERR 17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_ERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_NOERR 30
ISR_NOERR 31

isr_common_stub:
    pushad
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov eax, [esp + 32]
    mov ecx, [func_table + eax*4]
    call ecx
    popad
    add esp, 8
    iret

nullplan
Member
Member
Posts: 2034
Joined: Wed Aug 30, 2017 8:24 am

Re: GDT gets zeroed out and EIP = 0x3 based on qemu logs

Post by nullplan »

Looking through the basics some more, I noticed that your bootloader jumps to the start of the kernel image, but your build process does not in any way ensure that your entry point is actually there. You should put kernel_main into its own section and link that in first. The ENTRY directive in the linker script merely sets the entry point symbol, which is an ELF header field, but you then strip off the ELF header.

Alternatively, leave the ELF header intact and perform an indirect jump to the entry point from it in your bootloader.
Carpe diem!
User avatar
DabiiXqx
Posts: 11
Joined: Sun Feb 15, 2026 12:06 am
Libera.chat IRC: dabii

Re: GDT gets zeroed out and EIP = 0x3 based on qemu logs

Post by DabiiXqx »

nullplan wrote: Mon Feb 16, 2026 9:11 am Looking through the basics some more, I noticed that your bootloader jumps to the start of the kernel image, but your build process does not in any way ensure that your entry point is actually there. You should put kernel_main into its own section and link that in first. The ENTRY directive in the linker script merely sets the entry point symbol, which is an ELF header field, but you then strip off the ELF header.

Alternatively, leave the ELF header intact and perform an indirect jump to the entry point from it in your bootloader.


Thank you, i'll implement that
User avatar
DabiiXqx
Posts: 11
Joined: Sun Feb 15, 2026 12:06 am
Libera.chat IRC: dabii

Re: GDT gets zeroed out and EIP = 0x3 based on qemu logs

Post by DabiiXqx »

Yup, it turns out my bootloader was jumping to the wrong address. it jumped to my idt gate setter function instead of my main kernel function. thanks everyone
Post Reply