(莱昂氏unix源代码分析导读-14)系统初启(7)

#1进程

 

现在,是#1进程的天下了。回到main函数:

1627 if(newproc()) {                        /返回值为1,要执行以下的语句

1628      expand(USIZE+1);              /扩展进程私有空间,增大1block      

1629      estabur(0, 1, 0, 0);   

1630      copyout(icode, 0, sizeof icode);

1631      /*

1632           * Return goes to loc. 0 of user init

1633           * code just copied out.

1634      */

1635      return;

1636 }

 

首先看看expand函数,它用来扩展(或缩小)进程的私有空间:

(1)    缩小空间的情形比较简单,只需回收多余的空间即可;

(2)    如果需要扩大空间,则需要使用malloc分配所需连续空间,然后将

               current私有空间的内容拷贝到新分配的空间去,最后通过retu调用

               重新设置kisa6

 

expand调用后,进程的私有空间变大,即在核心stack栈底后多一个block的free空间,如下图所示:

 (莱昂氏unix源代码分析导读-14)系统初启(7)_第1张图片

user

到目前为止,我们的进程一直工作与kernel态,但是,Kernel态是特权阶级,大多数的进程尤其是用户进程

在大多数时间里不应该处于这种状态。

 

现在,是了解user态的时候了。有些人习惯将user态和kernel态的进程看作是两个进程,但我觉得还是把它们看

作一回事比较好——这样确定进程身份的方法仍没有变,即仍通过进程的“私有空间”kernel page #6

 

我们讨论过PDP11-40的存管系统,同kernel态一样,user态拥有8组的page地址、描述寄存器。在ppdau区域里定义了

两个数组,分别用来记录user态的page address/description Register相关的信息;

413 struct user

414{

……

436     int u_uisa[16]         /prototype of segment address

437     int u_uisd[16]         /page description saver

……

459}u

 

这里的16令人迷惑,Page Address registerPage Description Register各有8个,那么,这16从何而来呢?

答案就位于莱昂书中的第2.12小节——在更高版本的PDP-11中,user态地址被分为了“i”、“d”两部分。

而数值之所以留16entry,就是为了支持这种划分。

 

但是,我们需要知道是,莱昂在整理代码时,是按照PDP-11/40为模型进行整理的。虽然代码兼容了更

高版本的系统,我将不讨论这部分的内容。也就是说,我只考察PDP-11/40所能涉及到的代码——凡是针

对“i”、“d”划分的特殊处理都将被跳过。

 

另外一个令人迷惑的是 u_uisa[]的注释,什么是prototype?显然,u_uisa[]记录的不是Address register,那么

它是什么呢?我们将在代码中找到答案。

 

 博客地址:http://blog.csdn.net/cszhao1980 

博客专栏地址: http://blog.csdn.net/column/details/lions-unix.html

你可能感兴趣的:(unix,struct,user,prototype,扩展,代码分析)