1,先看个示意图吧.(每个进程都单独各自对应有类似下面这一块空间)
2,每个进程都有一个task_struct任务结构(1.7KB左右),和一片用于系统空间堆栈的存储空间,他们在物理内存空间中也是联系在一起的,当给进程申请task_struct任务结构空间时,系统将连同系统的堆栈空间一起分配(共8KB=0x015fbfff-0x015fa000+1=0x1fff+1=2^13)
每个进程在内核态下都会开辟一个内核栈,一般就是8KB(8192),一般把thread_info这个结构体和
内核栈放在一起,这样内核就可以很方便从ESP寄存器中获取当前CPU上正在运行的thread_info
结构体的首地址,通过thread_info就可以找到PCB了。这个PCB就是当前进程的PCB。
将esp中的值屏蔽掉末尾的13位(2^13=8192)即是thread_info的首地址。
3,每个进程都有个thread_info这个结构,这个结构和task_struct是一一对应的。
具体的字段如下:(linux-2.6.38)
内核栈放在一起,这样内核就可以很方便从ESP寄存器中获取当前CPU上正在运行的thread_info
结构体的首地址,通过thread_info就可以找到PCB了。这个PCB就是当前进程的PCB。
将esp中的值屏蔽掉末尾的13位(2^13=8192)即是thread_info的首地址。
3,每个进程都有个thread_info这个结构,这个结构和task_struct是一一对应的。
具体的字段如下:(linux-2.6.38)
26 struct thread_info {
27 struct task_struct *task; /* main task structure */
28 struct exec_domain *exec_domain; /* execution domain */
29 __u32 flags; /* low level flags */
30 __u32 status; /* thread synchronous flags */
31 __u32 cpu; /* current CPU */
32 int preempt_count; /* 0 => preemptable,
33 <0 => BUG */
34 mm_segment_t addr_limit;
35 struct restart_block restart_block;
36 void __user *sysenter_return;
37 #ifdef CONFIG_X86_32
38 unsigned long previous_esp; /* ESP of the previous stack in
39 case of nested (IRQ) stacks
40 */
41 __u8 supervisor_stack[0];
42 #endif<