Page 1 of 1

[SOLVED] STI == Fatal Error

Posted: Wed Mar 05, 2008 8:22 pm
by 01000101
Hey, recently I've been working on an experimental kernel written in Intel Assembly. What is happening is that when I enable interrupts, I get a triple fault from BOCHs saying that my CS selector is null. I'm pretty sure I set both the GDT and IDT entries properly, but then again, I'm getting an error so I'm not tooooo confident in that.

here's the bochs output.

Code: Select all

00001796618i[BIOS ] Booting from 0000:7c00
00005623545e[CPU0 ] return_protected: CS selector null
00005623545i[CPU0 ] CPU is in protected mode (active)
00005623545i[CPU0 ] CS.d_b = 32 bit
00005623545i[CPU0 ] SS.d_b = 32 bit
00005623545i[CPU0 ] EFER   = 0x00000000
00005623545i[CPU0 ] | RAX=000000000010ff11  RBX=0000000000000000
00005623545i[CPU0 ] | RCX=0000000000100000  RDX=0000000000000100
00005623545i[CPU0 ] | RSP=00000000000823bf  RBP=000000000008ffc0
00005623545i[CPU0 ] | RSI=00000000ffff88cb  RDI=0000000000080001
00005623545i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00005623545i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00005623545i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00005623545i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00005623545i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of DF if tf sf zf af PF cf
00005623545i[CPU0 ] | SEG selector     base    limit G D
00005623545i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00005623545i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00005623545i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00005623545i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00005623545i[CPU0 ] |  ES:0008( 0001| 0|  0) 00000000 000fffff 1 1
00005623545i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00005623545i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00005623545i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00005623545i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00005623545i[CPU0 ] | RIP=000000000000fdac (000000000000fdac)
00005623545i[CPU0 ] | CR0=0x00000011 CR1=0x0 CR2=0x0000000000000000
00005623545i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00005623545i[CPU0 ] >> retf 0xc888 : CA88C8
I'll provide the IDT and GDT setup routines as well.

IDT setup:

Code: Select all

setup_real_idt:
        pusha
        call remap_irqs
        mov word  [0x00501000 + 00], word  0x07FF     ; Limit
        mov dword [0x00501000 + 02], dword 0x00501010 ; Base
        lidt [0x00501000]
        popa
        ret

;-------------------------------------------------------------;
;                    SETUP IDT ENTRY                          ;
; Registers Used:                                             ;
;   EAX = IRQ Entry Offset                                    ; 
;   EBX = IDT Base Address                                    ; 
;   EDX = IRQ Handler Base                                    ; 
;-------------------------------------------------------------;

setup_idt_entry:
        pusha
        add eax, 32
        imul eax, eax, 8
        mov ebx, 0x00501010
        
        mov word  [ebx + eax + 00], dx
        mov word  [ebx + eax + 02], word 0x0008
        mov byte  [ebx + eax + 04], byte 0x00
        mov byte  [ebx + eax + 05], byte 0x8E
        shr edx, 16
        mov word  [ebx + eax + 06], dx
        popa
        ret
GDT setup:

Code: Select all

call setup_real_gdt
        lgdt [0x00500000]
        
        jmp 08h:10200h 

setup_real_gdt:
        pusha
        mov word  [0x00500000 + 00], word  0x0017     ; Limit
        mov dword [0x00500000 + 02], dword 0x00500010 ; Base
        mov dword [0x00500010 + 00], dword 0x00000000 ; Null desc
        mov dword [0x00500010 + 04], dword 0x00000000 
        mov dword [0x00500010 + 08], dword 0x0000FFFF ; Code desc 
        mov dword [0x00500010 + 12], dword 0x00CF9A00
        mov dword [0x00500010 + 16], dword 0x0000FFFF ; Data desc
        mov dword [0x00500010 + 20], dword 0x00CF9200
        popa
        ret
before all of this, I set an entire meg of memory to 0 @ 0x00500000 just to make sure there is no garbage still there to mess things up.

[edit] BTW, this is also my first kernel attempt in assembly as I am usually a C programmer so any pointers / general tips would be appreciated [/edit]

Posted: Thu Mar 06, 2008 2:37 am
by JamesM
You should probably investigate as to why ES == CS. If they're both non-conforming code segments, then why does ES == CS? And if they're both data segments, then why does ES == CS?!

Posted: Thu Mar 06, 2008 3:43 am
by Combuster
I'm wondering for starters, why there's a far return, and WHY IT POPS 0xc888 ITEMS from the stack in the process.

To me, it looks like you're running something you didn't write in the first place

Posted: Thu Mar 06, 2008 2:09 pm
by 01000101
To me, it looks like you're running something you didn't write in the first place
I assure you that this is all my code. There is deffinately not enough code here to produce a pop with so many values getting popped. The code I posted is probably 70% of the entire thing.

Also, I have no idea why the ES == CS, I've scanned the code and the only time ES is ever written to .. or even read from, is when I set it to the Data descriptor 0x10. It seems to change on its own.

The only far return I can think of is from STI? because that is the only place it crashes at. The next instruction after STI is a hlt, so it's not getting that far.

Posted: Thu Mar 06, 2008 8:17 pm
by pcmattman
HLT only halts the processor until the next interrupt fires, so putting it after STI isn't a great idea. Try a "jmp $" (or "jmp ." in AT&T syntax) instead.

Posted: Thu Mar 06, 2008 9:23 pm
by 01000101
wait? hlt allows interrupts, but jmp $ doesnt?

I thought jmp just jumps to the same location over and over again, kind of like a for(;;);.... and that deffinately allows interrupts to.. interrupt.

Posted: Fri Mar 07, 2008 1:07 am
by pcmattman
I said that HLT halts the processor UNTIL the next interrupt fires, and then it will continue to the next opcode.

If the opcode after that isn't specified and interrupts are enabled, you'll get stuck running unknown code.

Posted: Tue Mar 11, 2008 10:03 am
by jal
pcmattman wrote:If the opcode after that isn't specified and interrupts are enabled, you'll get stuck running unknown code.
Which is no doubt exactly what happens, given that Bochs dump.


JAL

Posted: Tue Mar 11, 2008 2:02 pm
by 01000101
indeed it was.
Thanks for the help.