操作系统高级教程-思考题-最新版
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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