triple fault on stack operation

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
duran
Posts: 22
Joined: Mon Jun 02, 2008 5:22 pm
Location: Sydney, Australia

triple fault on stack operation

Post by duran »

Ok, So I've just entered pmode, I loaded a GDT with 3 entries, as below:

Code: Select all

gdt_start:
    times 8 db 0               ; null segment
    ; ---- KERNEL CODE SEGMENT ----
    kcode_limlo:    dw 0x07FF
    kcode_baselo:   dw 0x0000
    kcode_basemid:  db 0
    kcode_access:   db 10011100b
    kcode_flgs:     db 0xC0
    kcode_basehi:   dw 0
    ; ---- KERNEL DATA SEGMENT ----
    kdata_limlo:    dw 0x7FF
    kdata_baselo:   dw 0
    kdata_basemid:  db 0
    kcode_access:   db 10010100b
    kcode_flgs:     db 0xC0
    kcode_basehi:   dw 0
    ; ---- REST ----

gdt_end:
I set cs to 0x8 with a far jump, this worked fine, then I set DS, ES and SS to 0x10. so far so good. Then I tried to push a register. Bochs kindly triple faulted for me, producing this error dump (An IDT was loaded, but it's full of nulls at this point in my development):
(0) [0x000000000000be94] 0008:000000000000be94 (unk. ctxt): push ax
; 6650
<bochs:2> s
00015381424e[CPU0 ] write_virtual_checks(): write beyond limit, r/w ED
00015381424e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
0c)
00015381424e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
08)
00015381424i[CPU0 ] CPU is in protected mode (active)
00015381424i[CPU0 ] CS.d_b = 32 bit
00015381424i[CPU0 ] SS.d_b = 32 bit
00015381424i[CPU0 ] EFER = 0x00000000
00015381424i[CPU0 ] | RAX=0000000000000010 RBX=0000000000004c00
00015381424i[CPU0 ] | RCX=0000000000000000 RDX=0000000000000fff
00015381424i[CPU0 ] | RSP=000000000000ffff RBP=0000000000000000
00015381424i[CPU0 ] | RSI=00000000000ec700 RDI=000000000000102c
00015381424i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00015381424i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00015381424i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00015381424i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00015381424i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00015381424i[CPU0 ] | SEG selector base limit G D
00015381424i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00015381424i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 007fffff 1 1
00015381424i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 007fffff 1 1
00015381424i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 007fffff 1 1
00015381424i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 007fffff 1 1
00015381424i[CPU0 ] | FS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00015381424i[CPU0 ] | GS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00015381424i[CPU0 ] | MSR_FS_BASE:0000000000000000
00015381424i[CPU0 ] | MSR_GS_BASE:0000000000000000
00015381424i[CPU0 ] | RIP=000000000000be94 (000000000000be94)
00015381424i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00015381424i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
(0).[15381424] [0x000000000000be94] 0008:000000000000be94 (unk. ctxt): push ax
; 6650
00015381424p[CPU0 ] >>PANIC<< exception(): 3rd (13) exception with no resolution
this seems to happen as soon as i try to do anything with the stack, push/pop/call. The other thing I noticed when looking at the segment registers is this:
<bochs:2> sreg
es:0x0010, dh=0x00c09700, dl=0x000007ff, valid=1
Data segment, base=0x00000000, limit=0x007fffff, Read/Write, Expand-down
, Accessed
cs:0x0008, dh=0x00c09f00, dl=0x000007ff, valid=1
Code segment, base=0x00000000, limit=0x007fffff, Execute/Read, Conformin
g, Accessed, 32-bit
ss:0x0010, dh=0x00c09700, dl=0x000007ff, valid=1
Data segment, base=0x00000000, limit=0x007fffff, Read/Write, Expand-down
, Accessed
ds:0x0010, dh=0x00c09700, dl=0x000007ff, valid=1
Data segment, base=0x00000000, limit=0x007fffff, Read/Write, Expand-down
, Accessed
fs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
gs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0000, dh=0x00008b00, dl=0x0000ffff, valid=1
gdtr:base=0x0000000000000800, limit=0x17
idtr:base=0x0000000000000000, limit=0x7ff
The data segment does not appear to be 32 bit pmode. Or is this merely because it is a data segment descriptor? what is the correct value for sz here?
Yargh
Member
Member
Posts: 56
Joined: Sat Jun 12, 2010 9:04 pm
Location: Somewhere else.

Re: triple fault on stack operation

Post by Yargh »

Have you actually set up a stack? It does say that rsp is 0xffff and rbp is 0.
Wait... What?
duran
Posts: 22
Joined: Mon Jun 02, 2008 5:22 pm
Location: Sydney, Australia

Re: triple fault on stack operation

Post by duran »

I mov'd 0xffff to sp previously. I initially had it set to something like 90000, but I was getting the same result, so i moved it lower down. I had not tried to do anything with rbp yet.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: triple fault on stack operation

Post by gerryg400 »

Your data and stack segments are defined as 'expand down'. Is that what you really want ? Your stack pointer is outside the limits you have set. Specifically esp is 0xffff which is less than 0x7fffff. The other value you tried (0x90000) is also less than 0x7fffff.
If a trainstation is where trains stop, what is a workstation ?
duran
Posts: 22
Joined: Mon Jun 02, 2008 5:22 pm
Location: Sydney, Australia

Re: triple fault on stack operation

Post by duran »

Probably not. the initial plan was to define a separate segment descriptor for the stack, but I opted instead to temporarily use the data segment descriptor, as I wanted to test that the call to my kernel (which i'd moved down to 0x1000) would work. the way I've set up the segments means that the limit is exactly as large as physical memory, so expand down is more than likely not going to work in this case.

I'll define another segment for the stack and see if it helps.
Yargh
Member
Member
Posts: 56
Joined: Sat Jun 12, 2010 9:04 pm
Location: Somewhere else.

Re: triple fault on stack operation

Post by Yargh »

It also sounds like you're just choosing an address for the stack, when you should actually be allocating space in your kernel somewhere for it, so it doesn't overwrite something it shouldn't.
Wait... What?
duran
Posts: 22
Joined: Mon Jun 02, 2008 5:22 pm
Location: Sydney, Australia

Re: triple fault on stack operation

Post by duran »

Originally, I was, as I was just trying to get it out of the way while stage 2 moved the kernel image down and performed the call. I've now settled on sticking it (temporarily) at the top of main memory (32MB), which seems to do fine. Once kernel is loaded, I plan to move it down into kernel space at the bottle of memory, allocating 4k for it and using segmentation to control overflows.

The stack seems to work fine now, but when I call the kernel image, which is a 0x1000 physical, and consists of this:

Code: Select all

push ebp
mov ebp, esp
pop ebp
ret
I get another triple fault when ret is executed. ebp at that point is set to 0xffffffff. I am uncertain where this value is coming from.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: triple fault on stack operation

Post by gerryg400 »

The cause of your last problem was very clear in the Bochs log you posted. I'm sure that if you look in your most recent Bochs log you will see the cause of your new problem.
If a trainstation is where trains stop, what is a workstation ?
duran
Posts: 22
Joined: Mon Jun 02, 2008 5:22 pm
Location: Sydney, Australia

Re: triple fault on stack operation

Post by duran »

Ok, I didn't get a chance to see the log again, as I changed the stack segment base address to 0, ran again, and the problem went away. I'm not entirely sure how making the stack segment larger from 2MB to 32 MB fixed this problem, given that I only ever pushed 3 values to it.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: triple fault on stack operation

Post by gerryg400 »

duran wrote:Ok, I didn't get a chance to see the log again, as I changed the stack segment base address to 0, ran again, and the problem went away. I'm not entirely sure how making the stack segment larger from 2MB to 32 MB fixed this problem, given that I only ever pushed 3 values to it.
You need to be sure. Problems don't simply go away, they need to be understood and fixed. My advice is to take the time to fix it.

BTW, did you remove the 'expands down' bit from your data and stack segments ?
If a trainstation is where trains stop, what is a workstation ?
duran
Posts: 22
Joined: Mon Jun 02, 2008 5:22 pm
Location: Sydney, Australia

Re: triple fault on stack operation

Post by duran »

I heartily agree with finding out why. Apologies for not being clear on this. As I said, the problem goes away when I change the stack segment to the same base and limit as the data segment. What I don't yet understand is why this is so. SP was in both tests set to 0x1ffffff, at the top of main memory. I called 0x8:1000, which pushed esp, mov'd esp to ebp, pop'd ebp, and returned. The first time it ran (With SS base at 0x1effff), ebp was 0xffffffff after the pop, before the return. The return failed with a CS limit violation and triple fault, as I have no interrupts defined. On the second run, after changing SS base to 0, ebp was 0 at the same point, and the return was executed without exception.

On your second question, yes. I defined a new segment for the stack with the expand-down bit set as 0. full code for what I have so far is at https://github.com/duranain/durOS. Have a look in stage2.asm for the GDT.
Post Reply