Page 1 of 3
Application problem
Posted: Mon Jul 11, 2011 3:16 am
by Nessphoro
Greetings sirs,
Today I've finished my ELF loader and a syscall interface so I decided to write a Hello World program in C++ for my OS, I haven't go a C Runtime -yet, but I already made crt0 which just calls
main and exits. But every time control reaches
it page faults with CR2 address 0xFFFFFFFC which is unheard of since in crt0 I did output the address of
main and it's nowhere close (Something like 0x80000B0. 0x8000000 Being the load address.)
So I though a problem was in "call," so I replaced it with "jmp" instead, at which point it did enter
main but any operation which "uses" memory (ex. Get an address of a const char*) fails with a page fault on the same CR2 address - 0xFFFFFFFC.
So I would like to hear, at least something, from the great wisdom of OsDev about this unusual problem
Re: Application problem
Posted: Mon Jul 11, 2011 3:38 am
by Velko
You forgot to set up stack, didn't you? 0xFFFFFFFC is actually very close to 0x00000000 (just 4 bytes "before").
Re: Application problem
Posted: Mon Jul 11, 2011 1:11 pm
by Nessphoro
Nope, the stack is set up at 0xF0000000-0xF0002000, or so I put in ESP, which seems to be the cause - because it doesn't work
**EDIT**
Never mind problem found - x86 stupid architecture was screwing up the things by looking into TSS on syscall, and not changing the values back, Usermode stack= Kernel Stack
Still don't know how to fix it though, I'll just backup from Ring 3 for now then.
**EDIT2**
On task switch ESP is not being copied over - EBP, and all the other regs are - but not ESP, do not know why.
Re: Application problem
Posted: Mon Jul 11, 2011 4:09 pm
by bluemoon
Within your scheduler the esp is most likely ESP0. You should save the ESP3.
Re: Application problem
Posted: Mon Jul 11, 2011 4:12 pm
by Nessphoro
I disabled TSS, but regardless I just enabled it, and told my Scheduler to put tasks ESP in ESP3 on load - doesn't work. By the way I use software switching
Re: Application problem
Posted: Mon Jul 11, 2011 4:38 pm
by bluemoon
Do you aware that:
1. There is no such instruction to disable or enable TSS. They will be used by the processor if needed.
2. When goes between different ring (say, ring3->ring0 or rin0->ring3), a stack switch occurs and the respective stack is save/loaded from current TSS.
3. For the reason of (2), you need at least one TSS for the purpose of valid stack switch.
So, on your scheduler process-switch (I avoid the term task which confuse the idea of processor task), are you sure you save register contents to ring3 stacks but not ring0 stack?
Re: Application problem
Posted: Mon Jul 11, 2011 5:47 pm
by Nessphoro
Yes sir, but I noted above that until I solve the problem I'll just keep everything in Ring 0, and by disabling TSS I meant not loading it, since the problem as I see it is not in TSS itself
Re: Application problem
Posted: Mon Jul 11, 2011 6:19 pm
by bluemoon
I see, so back the the original question, what's the register dump when #PF occur?
It should provide useful information on ESP and EIP (on stack)
Re: Application problem
Posted: Mon Jul 11, 2011 7:23 pm
by Nessphoro
Register dump has everything but ESP set to the applications data
First breakpoint - just before syscall to printf
Printf
PF - Opcode E8 - call to main
P.S. Answer to your previous question, I save registers onto the kernel heap
Re: Application problem
Posted: Mon Jul 11, 2011 7:58 pm
by bluemoon
Nessphoro wrote:Nope, the stack is set up at 0xF0000000-0xF0002000
In your screenshot, the stack is on 0xDFFFFFXX range, is that intended changes ?
The error code also seems weird. A code of 6 suggests a write protection issued in user mode code, and the address 0xFFFFFFFC usually is the recursive directory pointer - so you are modifying the 1st level page directory in user mode; but it does not match the activity on EIP generating the #PF.
Re: Application problem
Posted: Mon Jul 11, 2011 8:44 pm
by Nessphoro
Thats the thing, I explicitly set in my code the value of ESP - but it just doesn't appear to work, instead it always sets ESP to the kernel stack
Which is at as you stated 0xE0000000 ( It starts there)
Re: Application problem
Posted: Tue Jul 12, 2011 10:41 am
by mariuszp
You should remember that the stack extends backwards in memory - this means that ESP should not point to the start of the stack - it should point to stack_start + stack_size.
Re: Application problem
Posted: Tue Jul 12, 2011 1:20 pm
by Nessphoro
Yes sir, I know that
Re: Application problem
Posted: Tue Jul 12, 2011 1:35 pm
by Gigasoft
bluemoon wrote:Do you aware that:
...
2. When goes between different ring (say, ring3->ring0 or rin0->ring3), a stack switch occurs and the respective stack is save/loaded from current TSS.
...
Sorry, but this is completely wrong. When a call is made to a numerically lower privilege level (i.e. ring3->ring0), ESP and SS are loaded from the TSS, and the old ESP and SS are pushed onto the new stack (along with DS, ES, FS, GS if in Virtual 8086 mode). When returning to a higher privilege level, ESP and SS (and the others, if applicable) are popped, and the old values are not saved.
The thread's ESP0 therefore has to be loaded into the TSS on each task switch. It also has to be updated on all nested calls to user mode and restored afterwards.
Re: Application problem
Posted: Tue Jul 12, 2011 1:54 pm
by Nessphoro
Actually, hold on.
So I would load the current task's ESP into ESP0? Shouldn't the kernel's stack go there?