Page 1 of 1

Triple Fault, but why?

Posted: Fri Jul 16, 2004 10:41 pm
by jinksys
Here is some code I pulled from a different forum that triple faults,
Im trying to learn protected mode and this one is stumping me:

Code: Select all

.org 0x0000
 .code16 # We compile the code in 16 bits mode
 
 .globl _start
 
 _start:
 cli
 
 movw $0x7C0, %ax
 movw %ax, %ds
 
 movl $0x00000000, 0x800
 movl $0x00000000, 0x804
 movl $0x0000FFFF, 0x808 # Data segment descriptor
 movl $0x00CF9200, 0x80C # read/write
 movl $0x0000FFFF, 0x810 # Code segment descriptor
 movl $0x00CF9800, 0x814 # execute/read
 
 lgdt gdt_reg
 
 movl %cr0, %eax
 or $0x01, %al
 movl %eax, %cr0
 
 jmp $0x10, $start32
 
 gdt_reg:
 .word 0x0800
 .long 0x00000800
 
 .code32 # This part is compiled in 32 bits mode
 start32:
 movw $0x8, %ax # We set up %ds and %ss pointing on the Data segment 
 movw %ax, %ds
 movw %ax, %ss
 
 jmp . # We stay right here
 
 .fill 0x1FE - ( . - START ), 1, 0
 .byte 0x55
 .byte 0xAA

Re:Triple Fault, but why?

Posted: Sat Jul 17, 2004 12:02 am
by Brendan
Hi,

Code: Select all

 gdt_reg:
 .word 0x0800
 .long 0x00000800
That's your first problem. The GDT will be at 0x00007C00+0x00000800 not 0x00000800.

Code: Select all

 movl $0x0000FFFF, 0x808 # Data segment descriptor
 movl $0x00CF9200, 0x80C # read/write

<--SNIPPED-->

 .code32 # This part is compiled in 32 bits mode
 start32:
 movw $0x8, %ax # We set up %ds and %ss pointing on the Data segment 
 movw %ax, %ds
 movw %ax, %ss

 jmp . # We stay right here
Here's another problem. When the 32 bit code runs the base of the segment will be 0x00000000, not 0x07C00 (as it was in real mode). This will make the "jmp ." jump to 0x000000?? rather than 0x00007C??.

It's all easily fixed though, start your code with:

Code: Select all

.org 0x7C00
 .code16                    # We assemble this code in 16 bits mode
 
.globl _start
 
_start:
     jmp $0x00:$here        # Not sure about AT&T syntax here!

here:
     cli
     xorw %ax, %ax
     movw %ax, %ds
     movw %ax, %es
     movw %ax, %ss
     movw $stack_top, %sp

Cheers,

Brendan

Re:Triple Fault, but why?

Posted: Sat Jul 17, 2004 1:27 am
by jinksys
Im not expert on the subject :) but if Im not mistaken you need to do these things for protected mode to work (maybe not in this exact order):

enable A20
load a gdt
set cr0 bit to protected mode

of those three things, the code doesnt enable a20... therefore its not
able to access the extended memory? :-P Is that it?

Re:Triple Fault, but why?

Posted: Sat Jul 17, 2004 2:15 am
by DennisCGc
jinksys wrote: of those three things, the code doesnt enable a20... therefore its not
able to access the extended memory? :-P Is that it?
As I can tell, you can, but only the "odd" memory ranges, where the 20th bit isn't involved (where it's 0, instead of 1)

Re:Triple Fault, but why?

Posted: Sat Jul 17, 2004 5:56 am
by jinksys
Ive just about pulled my hair out trying to get this right...about ready to give up :-\

Here is my modified code:

Code: Select all


 _start:
 cli

 mov  %cs, %ax
 movw %ax, %ds

 lgdt %ds:gdt_register

 mov %cr0, %eax
 or $0x01, %al
 mov %eax, %cr0
 sti


 ljmp $0x8,$start32

 .code32 # This part is compiled in 32 bits mode

 start32:
 movw $0x10, %ax # We set up %ds and %ss pointing on the Data segment
 movw %ax, %ds
 movw %ax, %ss

jmp .

gdt_register:
.word (gdt_end - gdt_start -1)
.long gdt_start

gdt_start:
null_descritor:
.long 0x0
.long 0x0

code_descriptor:
 .word 0x0FFFF
 .word 0x0
 .byte 0x0
 .byte 0b10011010
 .byte 0b11001111
 .byte 0x0

 .word 0x0FFFF
 .word 0x0
 .byte 0x0
 .byte 0b10011010
 .byte 0b11001111
 .byte 0x0
gdt_end:

.fill 0x1FE - ( . - START ), 1, 0
 .byte 0x55
 .byte 0xAA
Ive been over many tutorials and they all seem to define the GDT table
differently (in a different order). My code seems to fail at the jmp into
the 32bit code. Sorry bout the lack of comments.

Re:Triple Fault, but why?

Posted: Sat Jul 17, 2004 6:36 am
by jinksys
It was fixed, although not by me:

Code: Select all

.org 0x0
 .code16

 .globl _start

 _start:
 cli

 movw $0, %ax
 movw %ax, %ds

 movl $0x00000000, 0x800
 movl $0x00000000, 0x804
 movl $0x0000FFFF, 0x808 # Data segment descriptor
 movl $0x00CF9200, 0x80C # read/write
 movl $0x0000FFFF, 0x810 # Code segment descriptor
 movl $0x00CF9800, 0x814 # execute/read

 lgdt gdt_reg

 movl %cr0, %eax
 or $0x01, %al
 movl %eax, %cr0

 jmp $0x10, $start32

 gdt_reg:
 .word 0x0017
 .long 0x00000800

 .code32 # This part is compiled in 32 bits mode
 start32:
 movw $0x8, %ax # We set up %ds and %ss pointing on the Data segment
 movw %ax, %ds
 movw %ax, %ss
 movw $0x741,0xb8000 #prints 'A' in top left to show we've not crashed
 jmp . # We stay right here

 .fill 0x1FE - ( . - START ), 1, 0
 .byte 0x55
 .byte 0xAA