4.4.1进程内核

每个进程都有自己的内核。当进程从用户态进入内核态时,CPU就自动地设置该进程的内核,也就是说,CPU从任务状态段TSS中装入内核栈指针esp(参见下一章的进程切换一节)。

X86内核的分布如图4.2所示:

文本框: 0x018fbfff 

 


 

 

 

 

 

 

 

 


         

            4.2 内核的分布图

 

   Intel系统中,起始于末端,并朝这个内存区开始的方向增长。从用户态刚切换到内核态以后,进程的内核总是空的,因此,esp寄存器直接指向这个内存区的顶端。 在图4.2中,从用户态切换到内核态后,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结构,从而导致内核崩溃。不过,7K大小对内核已足够。

 

   task_struct结构与内核放在一起具有以下好处:

·      内核可以方便而快速地找到这个结构,用伪代码描述如下:

task_struct = (struct task_struct *) STACK_POINTER & 0xffffe000

·      避免在创建进程时动态分配额外的内存

·      task_struct结构的起始地址总是开始于页大小(PAGE_SIZE)的边界。