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?
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?
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