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

进程switch

现在让我们考虑一个问题,如何确定当前Active的进程是哪个呢?要知道,进程并不独享某段代码,

我们不可能通过当前执行的代码来确定哪个进程处于Active状态。

 

显然,应该通过进程私有的东西来确定——而进程所私有的只有一样,即Kernel page 6(即ppda所在的Page)。

我们通过KISA6来确定Active进程,即KISA6指向哪个进程的“私有空间”,则该进程就是Active进程。

 

1 保存与切换

显然,要切换Active process,首先一件事就是保存当前process的若干信息,比如pc等等。而保存信息是由

savu来实现的。savu是我们的老朋友了,它的代码如下:

 

0725 _savu:

0726 bis $340,PS

0727 mov (sp)+,r1     /Return Address

0728 mov (sp),r0      /参数(u.u_rsav) --->r0

0729 mov sp,(r0)+     /sp --->u.ursav[0]

0730 mov r5,(r0)+     /r5 --->u.ursav[1]

0731 bic $340,PS

0732 jmp (r1)           /return

 

调用例子如下:

2189 savu(u.u_rsav);

 

一般情况下,它的参数总是u.u_rsav,也即u的开始地址(也是进程私有空间的开始地址),调用之后,

会将当前spr5保存在u中。savu并没有保存pc——这并不奇怪,因为,在每次函数调用中,栈中都会

存放return address。可以通过它来恢复pc

 

而进程的切换是由retu来完成的,retu的调用一般是这样的:

2228 retu(rp->p_addr); 参数为要被Active的进程的“私有空间”起始block(即kisa6 page

 

0740 _retu:

0741 bis $340,PS

0742 mov (sp)+,r1          /return adderss ---->r1

0743 mov (sp),KISA6    /参数--->KISA6,切换了PPDA,其实也就切换了Process

0744 mov $_u,r0            /u.u_rsav

0745 1:

0746 mov (r0)+,sp         /恢复sp

0747 mov (r0)+,r5          /恢复r5

0748 bic $340,PS

0749 jmp (r1)

 

2 Return到哪里去?

retu切换了进程,同时也恢复了spr5,但并没有更新pc,即没有跳回到新进程应该执行的地方。

pc的跳转是在retu的调用者函数中完成的,让我们看一个例子:

2178 swtch()

……

2228   retu(rp->p_addr);

……

2247   return(1);

2248 }

由于切换了spswtchreturn时,不会回到调用swtch的地方。那末,它会跳回到哪里去呢?也许你会说,

跳回到“原来”调用savu保存rp进程的那个函数——很不幸,这个说法是错误的。

 

让我们仔细研究下savu的代码:

0725 _savu:

0726 bis $340,PS

0727 mov (sp)+,r1     /Return Address

0728 mov (sp),r0      /参数(u.u_rsav) --->r0

 

在保存sp之前,第727行改变了sp,弹出了Return Address——这一作法,事实上抹平了因savu调用而对栈结构

的影响,使sp中记录的Return Address成为了savu调用者函数在被调用时,写入的return Address。即,如果当初

savu的调用链如下:

 

          调用            调用

函数1------>函数2----->savu

return时,会return到函数1

 

神乎其技!

 

【思考题】:第728行是否有印刷错误?是否应该为mov (sp)+,r0——这样,栈顶才是你刚刚所说的

                    “那个Return Address

 

                     提示:请注意以下两个事实:

                    (1)    栈的清理是由调用者完成的;

                    (2)    savuretu具有相同的参数数量。

 

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

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

你可能感兴趣的:(unix,代码分析)