Chinaunix首页 | 论坛 | 博客
  • 博客访问: 859381
  • 博文数量: 82
  • 博客积分: 2283
  • 博客等级: 大尉
  • 技术积分: 2007
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-15 22:19
文章分类

全部博文(82)

文章存档

2012年(82)

分类: LINUX

2012-07-30 20:34:51


进程描述符: struct_task,定义于,进程的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来实现这个过程。


阅读(5356) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

zhe_wang2012-08-09 20:07:59

可以尝试自己写个模块实现自己的my_current。