OSDev.org
https://forum.osdev.org/

Stumped on long mode triple fault
https://forum.osdev.org/viewtopic.php?f=1&t=57143
Page 1 of 1

Author:  orbitaldecay [ Mon Mar 04, 2024 1:06 pm ]
Post subject:  Stumped on long mode triple fault

Hey folks,

I'm in the middle of writing a long mode boot loader. I am running into problems with the IDT. When I manually test interrupts after initializing the IDT, I get a triple fault (on the int 0x80 instruction). I do not currently have a TSS because my understanding is that I do not need one (yet) so long as I am not leaving ring 0 and my ISTs for all of my interrupts are zero (which they should be). Any help would be greatly appreciated. Here is the relevant code:

Code:
   org 0x7c00
   bits 16

%define IDT_ADDR 0x6000
%define KERNEL_ADDR 0x10000
%define STACK_ADDR 0x6000

   ; Canonicalize IP
   jmp 0x0000:start
start:
   ; Clear the direction flag
   cld

   ; Clear data segment
   xor ax, ax
   mov ds, ax

   ; Turn on A20 gate (fast A20)
a20:   in al, 0x92
   or al, 2
   out 0x92, al

   ; Set up long mode paging (identity map first 2 MB)
   mov edi, 0x1000
   mov cr3, edi
   xor eax, eax
   mov ecx, 4096
   rep stosd
   mov edi, cr3
   mov dword [edi], 0x2003
   add edi, 0x1000
   mov dword [edi], 0x3003
   add edi, 0x1000
   mov dword [edi], 0x4003
   add edi, 0x1000
   mov ebx, 3
   mov ecx, 512
page:   mov dword [edi], ebx
   add ebx, 0x1000
   add edi, 8
   loop page

   ; Enable PAE
pae:   mov eax, cr4
   or eax, 1 << 5
   mov cr4, eax

   ; Switch to long mode
   cli
   mov ecx, 0xc0000080   ; LM-bit
   rdmsr
   or eax, 1 << 8
   wrmsr
   mov eax, cr0      ; Enable paging and protected mode
   or eax, 1 << 31 | 1 << 0
   mov cr0, eax
   lgdt [gdtr]
   jmp CODE_SEG:lmode

   bits 64

lmode:   mov ax, DATA_SEG
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov ss, ax
   mov rsp, STACK_ADDR

   ; Create IDT
   mov rdi, IDT_ADDR
   xor rcx, rcx
   dec cl
idt:   mov ax, isr
   stosw
   mov ax, CODE_SEG
   stosw
   mov ax, 0x8e00
   stosw
   xor rax, rax
   stosw
   stosd
   stosd
   loop idt

   ; Load IDT and test
   lidt [IDT_ADDR]
   int 0x80

spin:   jmp spin

   ; Default isr
isr:
   mov dword [0xb8000], ') : '
   iretq

idtr:
   dw (256 * 16) - 1
   dq IDT_ADDR

gdt:
gdtr: ; null segment also
   dw gdt_end - gdt - 1
   dd gdt
   dw 0

gdt_code:
   dw 0xffff   ; limit
   dw 0x0000   ; base
   db 0      ; base
   db 0x9a      ; access byte
   db 10101111b   ; flags / limit
   db 0      ; base

gdt_data:
   dw 0xffff
   dw 0x0000
   db 0
   db 0x92
   db 11001111b
   db 0
gdt_end:

CODE_SEG equ gdt_code - gdt
DATA_SEG equ gdt_data - gdt

times 510 - ($ - $$) db 0

   dw 0xAA55


And here is a log of the triple fault in QEMU:

Code:
check_exception old: 0x8 new 0xe
Triple fault
CPU Reset (CPU 0)
RAX=0000000000000000 RBX=0000000000200003 RCX=0000000000000000 RDX=0000000000000000
RSI=0000000000000000 RDI=0000000000006ff0 RBP=0000000000000000 RSP=0000000000006000
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=0000000000007ce3 RFL=00000046 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000007cfe 00000017
IDT=     000000008e000008 00007ce7
CR0=80000011 CR2=000000008e000088 CR3=0000000000001000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=ffffffffffffffff CCO=CLR
EFER=0000000000000500
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
XMM08=0000000000000000 0000000000000000 XMM09=0000000000000000 0000000000000000
XMM10=0000000000000000 0000000000000000 XMM11=0000000000000000 0000000000000000
XMM12=0000000000000000 0000000000000000 XMM13=0000000000000000 0000000000000000
XMM14=0000000000000000 0000000000000000 XMM15=0000000000000000 0000000000000000

Author:  Octocontrabass [ Mon Mar 04, 2024 1:32 pm ]
Post subject:  Re: Stumped on long mode triple fault

orbitaldecay wrote:
Code:
   lidt [IDT_ADDR]

Shouldn't that be "lidt [idtr]"?

Author:  orbitaldecay [ Mon Mar 04, 2024 1:39 pm ]
Post subject:  Re: Stumped on long mode triple fault

Octocontrabass wrote:
orbitaldecay wrote:
Code:
   lidt [IDT_ADDR]

Shouldn't that be "lidt [idtr]"?


Well don't I feel silly. Thank you so much!

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/