#1进程
现在,是#1进程的天下了。回到main函数:
1627 if(newproc()) { /返回值为1,要执行以下的语句
1628 expand(USIZE+1); /扩展进程私有空间,增大1个block
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空间,如下图所示:
user态
到目前为止,我们的进程一直工作与kernel态,但是,Kernel态是特权阶级,大多数的进程尤其是用户进程
在大多数时间里不应该处于这种状态。
现在,是了解user态的时候了。有些人习惯将user态和kernel态的进程看作是两个进程,但我觉得还是把它们看
作一回事比较好——这样确定进程身份的方法仍没有变,即仍通过进程的“私有空间”kernel page #6。
我们讨论过PDP11-40的存管系统,同kernel态一样,user态拥有8组的page地址、描述寄存器。在ppda的u区域里定义了
两个数组,分别用来记录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 register和Page Description Register各有8个,那么,这16从何而来呢?
答案就位于莱昂书中的第2.12小节——在更高版本的PDP-11中,user态地址被分为了“i”、“d”两部分。
而数值之所以留16个entry,就是为了支持这种划分。
但是,我们需要知道是,莱昂在整理代码时,是按照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