task_struct 进程描述符为何要这样分配?

进程描述符: struct_task,定义于<linux/sched.h>,进程的task_struct存放在进程内核栈的尾端.


    把task_struct结构与内核栈放在一起的好处:内核中大部分处理进程的代码都是通过进程描述符进行的。 因而current宏查找到当前进程的描述符的速度就尤为重要。对于寄存器不富裕的体系结构来说,通过预先分配和重复使用task_struct可以避免动态分配和释放所带来的资源消耗,UNIX的一个特点就是创建进程迅速。

   在Intel系统中,栈起始于末端(栈底),并朝栈底的方向增长。从用户态刚切换到内核态以后,进程的内核栈总是空的,因此,esp寄存器直接指向这个内存区的顶端。从用户态切换到内核态后,esp寄存器包含的地址为0x018fc00。进程描述符存放在从0x015fa00开始的地址。只要把数据写进栈中,esp的值就递减。

 

在/include/linux/sched.h中定义了如下一个联合结构:

union task_union {
      struct task_struct task;
      unsigned long stack[2408];
};

 
    从这个结构可以看出,内核栈占8kb的内存区。实际上,进程的task_struct结构所占的内存是由内核动态分配的,更确切地说,内核根本不给task_struct分配内存,而仅仅给内核栈分配8K的内存,并把其中的一部分给task_struct使用。

    task_struct结构大约占1K字节左右,其具体数字与内核版本有关,因为不同的版本其域稍有不同。因此,内核栈的大小不能超过7K,否则,内核栈会覆盖

task_struct结构,从而导致内核崩溃。

 

    kernel利用current里寻找task_struct的位置,假设栈的大小为8k(13个二进制位),我们可以将进程栈的地址的后13位屏蔽掉,这样得到的刚好就是进程栈的起

始地址,而thread_info刚好就是位于进程栈的底部,所以进程栈的起始地址就是struct thread_info的地址,得到了thread_info的地址,我们就很容易找到

task_struct的地址了。

 


汇编实现过程为

movl %-9162 ,%eax

andl   %esp ,%eax


寄存器esp存放进程栈的当前地址,eax最后存放的就是进程栈的起始地址。current使用current_thread_info来实现这个过程。

 

 

 


linux-3.14.12 内核分析:


#define get_current() (current_thread_info()->task)
#define current get_current()



/* how to get the thread information struct from c */
static inline struct   thread_info *current_thread_info(void)
{
    return (struct thread_info *)
        (current_stack_pointer & ~(THREAD_SIZE - 1));
}


#define current_stack_pointer ({        \
    unsigned long sp;            \
    asm("mov %%esp,%0" : "=g" (sp));    \
    sp;                    \
})


arch/x86/include/asm/page_32_types.h:

#define THREAD_SIZE_ORDER    1

#define THREAD_SIZE        (PAGE_SIZE << THREAD_SIZE_ORDER)



arch/x86/include/asm/page_types.h:

#define PAGE_SHIFT    12
#define PAGE_SIZE    (_AC(1,UL) << PAGE_SHIFT)




include/linux/sched.h:

union thread_union {
    struct thread_info thread_info;
    unsigned long stack[THREAD_SIZE/sizeof(long)];
};



 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值