Page 3 of 4
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 11:52 am
by bluecode
The error code must be poped of the stack before iret.
@Humble: indeed
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 2:17 pm
by TheChuckster
Thank you everybody especially Humble! At least I fixed something even though it still page faults. ;D
The LDTR is invalid from the start even before I multitask. Would fixing this fix my problem?
If so, how do I fix it?
Code: Select all
cs:s=0x0008, dl=0x0000ffff, dh=0x00cf9a00, valid=1
ss:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9200, valid=7
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
fs:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
gs:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
ldtr:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
tr:s=0x0028, dl=0x003e0068, dh=0x00008910, valid=1
What does ldtr mean? Load Task Register? Here's how I'm loading it:
0x28 is my TSS gate descriptor.
mov ax, 0x28
ltr ax
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 4:16 pm
by B.E
ldtr is the Local Discriptor Table Register.
A segment register can either referance the GDT or the LDT for the segment discriptor. for more information see section 2.1.1 of manual 3
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 4:36 pm
by TheChuckster
Ah. I see. So it doesn't matter?
Back to square one. My user apps are writing to invalid addresses (extremely high). Could an invalid stack segment cause that?
If so, how would be stack segment go about being invalid?
Especially when my pushes and pops are FINE. Take a look for yourself.
Code: Select all
pusha
push ds
push es
push fs
push gs
mov eax, 0x10
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
push esp
call TaskSwitch
mov esp, eax
pop gs
pop fs
pop es
pop ds
popa
iret
Code: Select all
pusha
push byte 0
push byte XX ; depends on the interrupt
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
mov eax, irq_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
Code: Select all
isr_common_stub:
push byte 0
push byte XX ; depends on the interrupt
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
mov eax, fault_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
Wait a second? Don't I need a pop esp in the Task Switch?
If not, what are some other possibilities that may be causing this page fault if the isolating factor is merely the introduction of ring 3 tasks into the kernel?
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 4:54 pm
by Humble
Note:
if its an IRQ handler u should :
this for the master pic
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 5:18 pm
by B.E
the fact that it is page faulting means that is going to a page that is not present.
how do you set up your page entries?
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 5:37 pm
by TheChuckster
I do send the EOI to the Master PIC via inline assembly in my task switching function. Ring 0 task switching works perfectly, paging and all!
Now as soon as go to Ring 3, my user code is suddenly trying to write to addresses like 0xFFFFFFFC8 (according to CR2 when the exception fires). Exactly the same user code is running -- just at a different priviledge level. How is ring 3 doing this to me?! My stack looks fine!
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 6:23 pm
by B.E
Code: Select all
push esp
call TaskSwitch
mov esp, eax ;what is the value of eax
assigming that eax is zero.
Code: Select all
pop gs ;esp = -2 (0xFFFFFFFFE)
pop fs ;esp = -4 (0xFFFFFFFFC)
pop es ;esp = -6 (0xFFFFFFFFA)
pop ds ;esp = -8 (0xFFFFFFFF8)
popa ;esp = -56 (0xFFFFFFFC8)
which means it is a stack overflow.
assuming that your kernel is loaded at 0xC000000 and that the pages are maped as supervisor. the reason why it worked at CPL=0 is because. CPL=0 has complete can access any menory wither it is set to readyonly or not.
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 6:38 pm
by TheChuckster
Thank you. My task switcher returns a value of the stack it WANTS to change to:
return Tasks[CurrentTask].esp0;
By GCC calling conventions that SHOULD go in eax, but it's not. I checked the value of Tasks[CurrentTask].esp0. It is correct. Should I just do some inline assembly to move the value into esp instead?
My kernel is at the 1 MB mark. All RAM past 32 MB is marked unpresent. Surely it would have errored?
Re:Switching Segments Causes Page Fault
Posted: Mon Nov 28, 2005 6:55 pm
by B.E
I wonder if your updating the esp value or CurrentTask is wrong
Re:Switching Segments Causes Page Fault
Posted: Tue Nov 29, 2005 3:51 am
by Pype.Clicker
Ch. 6 " Task Management" , p. 6-7
"The limit field must have a value equal to or greater than 67H, one byte less than the minimum size of a TSS"
Re:Switching Segments Causes Page Fault
Posted: Tue Nov 29, 2005 4:06 am
by Candy
Pype.Clicker wrote:
Ch. 6 " Task Management" , p. 6-7
"The limit field must have a value equal to or greater than 67H, one byte less than the minimum size of a TSS"
It probably assumes the G bit is off. If you enable the G-bit, you could probably get away with 67h / 1000h rounded up, or 1. That'd be a full page.
Note, I'm not sure it works with G-bit set.
Re:Switching Segments Causes Page Fault
Posted: Fri Dec 16, 2005 9:23 pm
by TheChuckster
I've revisited the problem today. I'm still absolutely confounded by it.
*--stack = (unsigned int)0x23; // CPL3 SS
*--stack = (unsigned int)Tasks[id].esp0; //ESP
*--stack = 0x200; //This is CPL3 EFLAGS
*--stack = 0x1B; //This is CPL3 CS
*--stack = (unsigned int)thread; //This is EIP
*--stack = 0; //EAX
*--stack = 0; //ESI
*--stack = 0; //EBP
*--stack = (unsigned int)Tasks[id].esp3; //ESP
*--stack = 0; //EBX
*--stack = 0; //EDX
*--stack = 0; //ECX
*--stack = 0; //EAX
*--stack = 0x10; //DS
*--stack = 0x10; //ES
*--stack = 0x10; //FS
*--stack = 0x10; //GS
This inital stack setup is probably the problem. It's just I don't know what to set the ESP field to. That's probably what's messing things up too as well. If said theory is correct that the stack is wrapping to the end of the memory, then the second line is wrong. Right?
Should I be offsetting my ESP0 to point to the END of the initial stack? That would be 64 bytes subtracted from it. Well I just tried it and my theory is wrong. The stack is still being smashed.
Can anyone nudge me on my way to enlightment?
Re:Switching Segments Causes Page Fault
Posted: Fri Dec 16, 2005 9:49 pm
by TheChuckster
Yeah. Now I'm even more confused than before. What is happening?
Should I be updating esp0 in my TSS?
Anyone?
Re:Switching Segments Causes Page Fault
Posted: Fri Dec 23, 2005 7:21 am
by UM
TheChuckster wrote:
*--stack = (unsigned int)Tasks[id].esp0; //ESP
I?m not very sure about this, but i think at this stack position should rather be esp3, not esp0. And because the stack normally grows downward to lower adresses, the esp for a new stack should point to the highest stack address...