Right now I'm reading the book "Linux Kernel Development 3d Edition" by Robert Love. There he write about the thread_info struct which contains the pointer to task_struct struct and, as I understood, located at the bottom or at the top of kernel stack of process (depends on architecture). I wasn't familiar with Linux kernel API until recently and I wasn't known of current() method existence. There is an excerpt from the book related to how current() method actually works:
On x86, current is calculated by masking out the 13 least-significant bits of the stack pointer to obtain the thread_info structure.This is done by the current_thread_info() function.The assembly is shown here: movl $-8192, %eax andl %esp, %eax This assumes that the stack size is 8KB.When 4KB stacks are enabled, 4096 is used in lieu of 8192.
My questions are:
For thous who will read this topic, the questions I have voiced can lead to conclusion that the author don't understand properly the process of memory allocation and administration. Ok, that's may be right due to the fact that in my mind I can represent the memory allocated for the stack as the ribbon full of bits (or bytes). All of this bytes accessible by a specific memory address represented as some decimal value. The origin of the stack is the lowest memory address and the fin of the stack is the highest value of memory address. But HOW, HOW can we get the pointer to the thread_info struct located at the, say, end of the stack only by masking out 13 least-significant bits of ARBITRARY located stack pointer (If I understood correctly, we masking out bits of the stack pointer ADDRESS represented as decimal value).
From what I think I've understood, task_struct is the C structure that acts as the process descriptor, holding everything the kernel might need to know about a processes. At the end of the process kernel stack lives another struct, thread_info , which has a pointer to the processes task_struct .
The kernel stack is also used for interrupt handler execution, for the interrupts that occur while a particular thread is running. As we have talked about already, the interrupts are almost always doing something for another, blocked process/thread.
struct thread_info is stored at the bottom of stack if stack grows down and up if stack grows up. Let, Kernel Stack is 8KB of size. Also, it should have struct thread_info in it. This gives the remaining size of 8192-52 = 8140 Bytes.
From the perspective of Virtual memory system, task_struct is allocated by the Slab allocator, so that it's located in the kernel space.
Each process only gets 8192 bytes of kernel stack, aligned to a 8192-byte boundary, so whenever the stack pointer is altered by a push or a pop, the low 13 bits are the only part that changes. 2**13==8192.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With