The process Kernel stack of Linux kernel 2.4 and 2.6 is not the same as the task descriptor storage. Here we will summarize it.
In kernel 2.4, the stack is defined as follows:
union task_union { struct task_struct task; unsigned long stack[INIT_TASK_SIZE/sizeof(long)]; };
Init_task_size can only be 8 K.
When the kernel assigns a task_struct structure to each process, two consecutive physical pages (8192 bytes) are actually allocated ),. The bottom part is used as the task_struct structure (about 1 kb), and the top part of the structure is used as the kernel stack (about 7 KB ). Access the task_struct structure of the process, and use a macro to operate the current,
It is defined as follows in 2.4:
#define current get_current()static inline struct task_struct * get_current(void){ struct task_struct *current; __asm__("andl %%esp,%0; ":"=r" (current) : "" (~8191UL)); return current;}
~ 8191ul indicates that the minimum 13 BITs is 0,
The remaining bits are all 1.
% ESP points to the kernel stack. When the minimum value of % ESP is shielded, the beginning of "two consecutive physical pages" is obtained, which is the beginning of task_struct, the pointer to task_struct is obtained.
In kernel 2.6, the stack is defined as follows:
union thread_union { struct thread_info thread_info; unsigned long stack[THREAD_SIZE/sizeof(long)];};
According to the Kernel configuration, thread_size can be 4 K bytes (1 page) or 8 K bytes (2 pages ). Thread_info is 52 bytes long.
Is the kernel stack when it is set to 8 KB: thread_info at the beginning of the memory zone, the kernel stack grows from the end down. The process descriptor is not in this memory zone, and the thread_info and process descriptor are interconnected through the task and thread_info pointers respectively. So the current definition of getting the current process descriptor is as follows:
#define current get_current()static inline struct task_struct * get_current(void){ return current_thread_info()->task;}static inline struct thread_info *current_thread_info(void){ struct thread_info *ti; __asm__("andl %%esp,%0; ":"=r" (ti) : "" (~(THREAD_SIZE - 1))); return ti;}
Blocks the 12-bit Kernel stack based on the thread_size.
LSB (4 K) or 13-bit LSB (8 K) to obtain the starting position of the kernel stack.
struct thread_info { struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ unsigned long flags; /* low level flags */ unsigned long status; /* thread-synchronous flags */ ... ..}
Refer:
1.
Http://hi.baidu.com/zqfazqq/blog/item/12db349980343b0b6f068c5d.html
2.
Linux kernel source code scenario analysis (Volume 1, page267)
3.
Deep understanding of Linux kernel (version 3rd,
Page90, page164)