Windows kernel stacks

Programming, for all ages and all languages.
icealys
Member
Member
Posts: 60
Joined: Mon Feb 17, 2014 3:54 pm

Windows kernel stacks

Post 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?
Last edited by icealys on Thu Jun 05, 2014 6:38 pm, edited 1 time in total.
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: windows kernel stack

Post 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.
icealys
Member
Member
Posts: 60
Joined: Mon Feb 17, 2014 3:54 pm

Re: windows kernel stack

Post 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?
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Windows kernel stacks

Post 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).
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
max
Member
Member
Posts: 616
Joined: Mon Mar 05, 2012 11:23 am
Libera.chat IRC: maxdev
Location: Germany
Contact:

Re: windows kernel stack

Post 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.
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: Windows kernel stacks

Post 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).
icealys
Member
Member
Posts: 60
Joined: Mon Feb 17, 2014 3:54 pm

Re: Windows kernel stacks

Post 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.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Windows kernel stacks

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
icealys
Member
Member
Posts: 60
Joined: Mon Feb 17, 2014 3:54 pm

Re: Windows kernel stacks

Post 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.
Last edited by icealys on Sat Jun 07, 2014 11:32 am, edited 1 time in total.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Windows kernel stacks

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
icealys
Member
Member
Posts: 60
Joined: Mon Feb 17, 2014 3:54 pm

Re: Windows kernel stacks

Post 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?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Windows kernel stacks

Post 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. :roll:
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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
icealys
Member
Member
Posts: 60
Joined: Mon Feb 17, 2014 3:54 pm

Re: Windows kernel stacks

Post 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.
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: Windows kernel stacks

Post 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. :)
icealys
Member
Member
Posts: 60
Joined: Mon Feb 17, 2014 3:54 pm

Re: Windows kernel stacks

Post 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.
Post Reply