操作系统高级教程-思考题-最新版

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.进程0创建进程1时,为进程1建立了自己的task_struct、内核栈,第一个页表,分别位于物理内存16MB的顶端倒数第一页、第二页。请问,这个了页究竟占用的是谁的线性地址空间,内核、进程0、进程1、还是没有占用任何线性地址空间?说明理由并给出代码证据。

答:两次都是通过调用get_free_page()在物理内存里申请一个物理页,由于在head.s中决定内核的物理地址和线性地址是一一对应的。因此这两个页都在内核的线性地址空间内。

setup_paging:

movl $1024*5,%ecx/* 5 pages - pg_dir+4 page tables */

xorl %eax,%eax

xorl %edi,%edi/* pg_dir is at 0x000 */

cld;rep;stosl

movl $pg0+7,_pg_dir/* set present bit/user r/w */

movl $pg1+7,_pg_dir+4/* --------- " " --------- */

movl $pg2+7,_pg_dir+8/* --------- " " --------- */

movl $pg3+7,_pg_dir+12/* --------- " " --------- */

movl $pg3+4092,%edi

movl $0xfff007,%eax/* 16Mb - 4096 + 7 (r/w user,p) */

std

1:stosl/* fill pages backwards - more efficient :-) */

subl $0x1000,%eax

jge 1b

2.假设:经过一段时间的运行,操作系统中已经有5个进程在运行,且内核分别为进程4、进程5分别创建了第一个页表,这两个页表在谁的线性地址空间?用图表示这两个页表在线性地址空间和物理地址空间的映射关系。

答:大师兄!!

3.进程0开始创建进程1,调用了fork(),跟踪代码时我们发现,fork代码执行了两次,第一次,跳过init()直接执行了for(;;) pause(),第二次执行fork代码后,执行了init()。奇怪的是,我们在代码中并没有看见向后的goto语句,也没有看到循环语句,是什么原因导致反复执行?请说明理由,并给出代码证据。

答:大师兄!!

4.copy_process函数的参数最后五项是:long eip,long cs,long eflags,long esp,long ss。查看栈结构确实有这五个参数,奇怪的是其他参数的压栈代码都能找得到,确找不到这五个参数的压栈代码,反汇编代码中也查不到,请解释原因。

答:在执行int n这条中断指令时(在此即为int 0x80),系统会自动把ss esp rflags cs eip这五个寄存器的值压入栈中。

5.用图表示下面的几种情况,并从代码中找到证据:

a、当进程获得第一个缓冲块的时候,hash表的状态。

b、经过一段时间的运行,已经2000多个buffer_head挂到hash_table上时,hash表(包括所有的buffer_head)的整体状态。

c、经过一段时间的运行,有的缓冲块已经没有进程使用了(空闲),这样的空闲缓冲块是否会从hash_table上脱钩?

d、经过一段时间的运行,所有的buffer_head都挂到hash_table上了,这时,又有进程申请空闲缓冲块,将会发生什么?解释原因并找到代码证据。

答:

见书上P100-P01.

6.rd_load()执行完之后,虚拟盘已经成为可用的块设备,并成为根设备。在向虚拟盘中copy任何数据之前,虚拟盘中是否有引导块、超级块、i节点位图、逻辑块位图、i节点、逻辑块?请解释其中的道理,并给出代码证据。

答:在rd_load()执行之前,虚拟盘经初始化后中存放的全是0。

rd_init()中的代码段:---P46

cp = rd_start;

for (i=0; i < length; i++)

*cp++ = '\0';

且拷贝数据也是从虚拟盘开始处进行存放的。

rd_load()中的代码:---P121

cp = rd_start;

while (nblocks) {

if (nblocks > 2)

bh = breada(ROOT_DEV, block, block+1, block+2, -1);

else

bh = bread(ROOT_DEV, block);

}

(void) memcpy(cp, bh->b_data, BLOCK_SIZE);

}

7.在虚拟盘被设置为根设备之前,操作系统的根设备是软盘(包括软驱),请说明设置软盘为根设备的技术路线,并给出代码证据。

(提示:注意bootsect.s的249行,508这个数值。

.org 508

root_dev:

.word ROOT_DEV

答:在bootsect.s程序的开始处有一条语句对ROOT_DEV进行赋值。之后执行如下代码,确定所使用的根设备:

seg cs

mov ax,root_dev

cmp ax,#0

jne root_defined

seg cs

mov bx,sectors

mov ax,#0x0208! /dev/ps0 - 1.2Mb

相关文档
最新文档