User context
-
Whatever5k
User context
One more question concerning that topic:
I managed to create a kernel context (including cs, ds & co., eax & co., eip and so on). Now I want to go on with creating user processes. Therefore, I need a user context. It's quite similar to the kernel's one - but there's a difference, actually two: the user ESP and the user SS.
What do I need those two for? Are they used to identify the user's stack? If yes, what do I need the "normal" stack pointer for? Isn't it sufficient to have one user stack?
I managed to create a kernel context (including cs, ds & co., eax & co., eip and so on). Now I want to go on with creating user processes. Therefore, I need a user context. It's quite similar to the kernel's one - but there's a difference, actually two: the user ESP and the user SS.
What do I need those two for? Are they used to identify the user's stack? If yes, what do I need the "normal" stack pointer for? Isn't it sufficient to have one user stack?
-
Tim
Re:User context
Each thread must have two stacks: a kernel stack and a user stack.
The kernel stack is used while in ring 0. SS0 and ESP0 are stored in the TSS and the CPU switches to the kernel stack automatically when an interrupt occurs.
The user stack is used while in ring 3 and is the only stack that applications see. Set a pointer to the user stack at the end of the thread's context.
The kernel stack is used while in ring 0. SS0 and ESP0 are stored in the TSS and the CPU switches to the kernel stack automatically when an interrupt occurs.
The user stack is used while in ring 3 and is the only stack that applications see. Set a pointer to the user stack at the end of the thread's context.
-
Whatever5k
Re:User context
That is, when an interrupt occurs/a system call is made, right?Tim Robinson wrote: The kernel stack is used while in ring 0.
Well, that makes sense after all. Both, kernel and user stack, work completely independent from each other, correct? By the way, do I have to care about the values stored in the TSS after a ring-switch occured?
-
Tim
Re:User context
If you're using software switching, you will need to update TSS.ESP0 on every thread switch.
-
Whatever5k
Re:User context
I see... - ESP0 is the stack pointer of ring0 thread, that is the kernel - right? But back to the user context: could I do s.th. similar to following?
But what do I need the user SS for? I don't have a stack segment in my GDT, not even for the kernel. Is it necessary to have one?
Code: Select all
base = malloc(4096);
user_esp = base + 8192 - sizeof(context);
-
distantvoices
- Member

- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:User context
the ss is the segment in which your stack resides. If you don't have an extra stack segment, you can indicate the selector for your data segment here, be it the user data segment be it the kernel data segment.
The user ss you need for distinction and protection issues: Imagine you do interruptses and all this stuff on one and the same stack. I think, you would come to a very mess at the end because the different processes don't know whether they return to their own function or to an other. and task switching would be something difficult too. With user and kernel stacks you have two different environments available: one active whilst normal operation in user space, and one active, when the process is interrupted, performs a system call or similar.
these are my thoughts.
The user ss you need for distinction and protection issues: Imagine you do interruptses and all this stuff on one and the same stack. I think, you would come to a very mess at the end because the different processes don't know whether they return to their own function or to an other. and task switching would be something difficult too. With user and kernel stacks you have two different environments available: one active whilst normal operation in user space, and one active, when the process is interrupted, performs a system call or similar.
these are my thoughts.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
-
Whatever5k
Re:User context
I see.
Now can I do s.th. like following?
I know this is just a quick-and-dirty version - but what about the basic idea?
Now can I do s.th. like following?
Code: Select all
void create_user_context(void)
{
...
proc->base = malloc(..);
proc->stack = proc->base + STACK_SIZE - sizeof(context);
ctx = (context*) proc->stack;
/* fill context */
ctx->ds = ... = (int) &USER_DS;
ctx->cs = (int) &USER_CS;
...
proc->kernel_base = malloc(...);
proc->kernel_esp = proc->kernel_base + SIZE;
}
void schedule()
{
/* take another process */
....
/* process p is next to run */
system_tss.esp0 = (unsigned long) p->kernel_esp; /* update TSS */
return p->stack;
}
-
distantvoices
- Member

- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:User context
It is like this. I'd only prefer to do the tss patching in the isr-stub. Make the TSS known to your interrupt handler layer. you can access the elements by adding an offset
to the base adress of it. sort of [tss+4] for esp0,[tss+56] for esp.
Thus I imagine you pass a pointer to a structure to the asm stub which contains esp and esp0.
In the asm-stub you then have this pointer in eax and:
... save regs ...
push esp
call... [your isr]
add esp,4 (to skip the previously pushed esp?)
mov esp,[eax] -> first 4 bytes -> esp
mov [sys_tss+4],[eax+4] -> second 4 bytes - esp0
...eoi instructions ...
...restore registers and so forth ...
iretd
If I write entirely and utterly weird crap pls tell me so that I can learn something of it.
to the base adress of it. sort of [tss+4] for esp0,[tss+56] for esp.
Thus I imagine you pass a pointer to a structure to the asm stub which contains esp and esp0.
In the asm-stub you then have this pointer in eax and:
... save regs ...
push esp
call... [your isr]
add esp,4 (to skip the previously pushed esp?)
mov esp,[eax] -> first 4 bytes -> esp
mov [sys_tss+4],[eax+4] -> second 4 bytes - esp0
...eoi instructions ...
...restore registers and so forth ...
iretd
If I write entirely and utterly weird crap pls tell me so that I can learn something of it.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
-
Whatever5k
Re:User context
Well, it doesn't really matter where I change my TSS stuff - I can also change in the scheduler, no problem with that.
-
Whatever5k
Re:User context
Hm, it doesn't work yet: I get a GPF. I've got a question concerning that. when a privilege change occurs on a exception, user_ss and user_esp are pushed on the stack, too. But how can I deal with that so that I can handle both, kernel and user exceptions. I have something like this:
Now when user_ss and user_esp are *not* pushed on the stack, I will get funny results because my regs_t structure includes user_ss and user_esp. So, what to do?
Code: Select all
gpf_fault:
PUSH_REGS
call fault
typedef struct {
gs
fs
...
eflags
user_esp;
user_ss;
}
void fault(regs_t regs)
{
printf("regs->eax = ....");
printf("regs->user_ss = ...");
}
-
Tim
Re:User context
You must ignore the user SS and user ESP fields when the RPL of EIP is equal to zero.
pype: Tim means, "the RPL of CS", of course
pype: Tim means, "the RPL of CS", of course