Page 1 of 2
Windows kernel stacks
Posted: Thu Jun 05, 2014 6:31 pm
by icealys
Since each thread gets a kernel mode stack and a user mode stack, I am wondering how windows stores the SS and ESP values for each thread and stores them inside the Task State Segment when required. Wouldn't the kernel need to store that information in the kernel's main thread's stack? If so, how does it switch to its own stack to get information? In this case do you think it would use an inline assembly instruction like mov, so it could just access the memory location instead of having to actually be in its own stack to access data?
Re: windows kernel stack
Posted: Thu Jun 05, 2014 6:36 pm
by alexfru
There's no "main" thread in the Windows kernel. There's an idle thread. There are worker threads, etc. But there's no main one. The kernel isn't really an application to have a main thread.
Re: windows kernel stack
Posted: Thu Jun 05, 2014 6:44 pm
by icealys
But it still must have a stack that it can switch to...in that case would it store its stack location and the stack locations of all other threads inside global variables?
Re: Windows kernel stacks
Posted: Thu Jun 05, 2014 7:46 pm
by thepowersgang
If windows does its thread switching in the standard stack-per-thread model, then the globally allocated thread structure contains the current value of ESP for that thread. So, yes, the stack locations are in global variables (indirectly, as they're in structures pointed to by a set of global variables).
Re: windows kernel stack
Posted: Fri Jun 06, 2014 1:30 am
by max
icealys wrote:But it still must have a stack that it can switch to...
It has the kernel stack of the task that is active in the moment the switch occurs. For example in a microkernel, there are no kernel task where the kernel just does something. The kernel only lives within system call and interrupt handlers. idk how Windows does this - but here is one way to do it in a microkernel (on x86), assuming the current process runs in usermode:
- timer interrupt occurs
- CPU sets ESP0 from the TSS as the stack pointer
- CPU pushes eip, cs, eflags, esp, ss
- kernels interrupt handler code is called, pushes rest of registers (eax, ecx...)
- scheduler is called, selects the next task
- ESP0 in the TSS is set to the kernel stack pointer of the next task
- switch to the next tasks page directory
- switch kernel stack to the new kernel stack
- register values are popped from the kernel
- IRET, CPU pops eip, cs, eflags, esp and ss
Therefore, the ESP to the user stack of each task is stored on its kernel stack, and the kernel only operates on the kernel stack of the task thats active.
Re: Windows kernel stacks
Posted: Fri Jun 06, 2014 3:45 am
by alexfru
Every thread in Windows has its own kernel stack. If a thread never leaves the kernel mode, that's its only stack, unless there are some special arrangements. If a thread switches between the user and the kernel modes (as result of an app invoking a system call or simply being interrupted by an IRQ), it switches its current stack between the two. TSS.SS0 and TSS.ESP0 point to the kernel stack of the current thread. Switches to level 0 (kernel) from level 3 (user) make the CPU load SS and ESP from these fields of the TSS. The old SS:ESP gets saved on the kernel stack by the CPU. When returning to level 3 (user) from level 0 (kernel) the old SS:ESP pair is taken from the kernel stack by the CPU, thus restoring the user stack.
See the stack layout on interrupts/exceptions with and without privilege/level change/transition. There were illustrations in the i80386 Programmer's Manual (I don't remember if they are still there in more recent CPU manuals; Intel appears to have a habit of changing perfectly understandable diagrams, illustrations, formulas and text to some inpenetrable stuff).
Re: Windows kernel stacks
Posted: Fri Jun 06, 2014 8:15 pm
by icealys
what if you have something like an anonymous pipe and two different processes use the same structure in kernel memory to check if the buffer is ready to be read from? Would it just use global memory in that case or would it switch to a different kernel stack than the current thread's kernel stack in order to allocate space? Actually, wouldn't the heap be used for that purpose and also the purpose for allocating space on the fly to store ss0 and esp0 for all threads that are running so when the time is right it can then switch those values into the TSS.
Re: Windows kernel stacks
Posted: Fri Jun 06, 2014 10:19 pm
by Brendan
Hi,
icealys wrote:what if you have something like an anonymous pipe and two different processes use the same structure in kernel memory to check if the buffer is ready to be read from? Would it just use global memory in that case or would it switch to a different kernel stack than the current thread's kernel stack in order to allocate space? Actually, wouldn't the heap be used for that purpose and also the purpose for allocating space on the fly to store ss0 and esp0 for all threads that are running so when the time is right it can then switch those values into the TSS.
If data has to exist after the function that allocated it returns, then the data can't be allocated on the stack (because returning from a function frees anything on the function's stack).
If you've got a function that creates a pipe (including allocating a buffer for the pipe); then that buffer can't be allocated on the stack.
Cheers,
Brendan
Re: Windows kernel stacks
Posted: Sat Jun 07, 2014 11:02 am
by icealys
Does anyone know where the values for SS0 and ESP0 are stored for every thread before they are copied to the Task State Segment? Because I read that only one TSS structure is used in software context switching, so those values must be stored somewhere.
I get it now. I read this from stackoverflow.
There is just one common kernel memory. In it each process has it's own task_struct + kernel stack (by default 8K).
In a context switch the old stack pointer is saved somewhere and the actual stack pointer is made to point to the top of the stack (or bottom depending on the hardware architecture) of the new process which is going to run.
Re: Windows kernel stacks
Posted: Sat Jun 07, 2014 11:17 am
by Brendan
Hi,
icealys wrote:Does anyone know where the values for SS0 and ESP0 are stored for every thread before they are copied to the Task State Segment? Because I read that only one TSS structure is used in software context switching, so those values must be stored somewhere.
Typically you have some sort of structure ("thread data block") to keep track of the thread's ESP0, plus things like what state the thread is in, how much CPU time it has used, which process it belongs to and various other things. I tend to use the same "thread data block" to store the thread's FPU/MMX/SSE/AVX state and kernel stack too. I'd expect all the different versions of Windows would do something vaguely similar.
Cheers,
Brendan
Re: Windows kernel stacks
Posted: Sat Jun 07, 2014 2:18 pm
by icealys
Ok. I was a little confused about the thread data block. I was confusing it with the thread control block. So with that said, would the process environment block(PEB) and the thread environment block
(TEB) be stored on the heap ? Also, I was thinking about it and I realized that the OS scheduler would have to be written in assembly, am I right?
Re: Windows kernel stacks
Posted: Sat Jun 07, 2014 11:16 pm
by Brendan
Hi,
icealys wrote:Ok. I was a little confused about the thread data block. I was confusing it with the thread control block. So with that said, would the process environment block(PEB) and the thread environment block
(TEB) be stored on the heap ?
I have no idea what names Microsoft gives to various internal structures in Windows, or how they manage memory in kernel-space. It's just a lot easier to assume that whatever they do it isn't good enough for my project and ignore them.
icealys wrote:Also, I was thinking about it and I realized that the OS scheduler would have to be written in assembly, am I right?
A scheduler can be split into 2 parts. One big part that decides what to do when, and a small part that does the actual switch from one task to another. The small part would have to be written in assembly.
Cheers,
Brendan
Re: Windows kernel stacks
Posted: Sun Jun 08, 2014 4:03 pm
by icealys
I am a little confused about something. Wikipedia said that the PCB is allocated on the kernel stack. How Would that structure, including the thread control block for each thread, remain in the kernel stack ? After the OS allocates the space on the stack wouldn't the function reclaim that space once it ends?
like doing this...
mov esp, ebp
pop ebp
once the function ends, now ebp would be back at the bottom and any space allocated from the previous function would be overwritten.
Re: Windows kernel stacks
Posted: Sun Jun 08, 2014 6:42 pm
by alexfru
If you want to look at it in terms of function calls and returns, you may think that the "function" that allocates the structure as a local variable does not return.
Re: Windows kernel stacks
Posted: Sun Jun 08, 2014 7:06 pm
by icealys
I didn't even stop to think that was possible because of the OS having to switch to user mode. But I guess its possible the more I think about it.