中国科学院大学操作系统考试思考题答案

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

1. 为什么计算机启动最开始的时候执行的是BIOS 代码而不是操作系统自身的代

码?

答:通常我们用 C 语言写的用户程序,必须在操作系统的平台上执行,即操作系统为应用程序创建进程并把应用程序的可执行代码加载到内存。计算机启动的时候,操作系统并没有在内存中,我们首先要把操作系统加载到内存,而这个工作最开始的部分,就是由bios 程序来实现的。所以计算机启动最开始执行的是bios 代码

2. 为什么BIOS只加载了一个扇区,后续扇区却是由bootsect代码加载?为什

么BIOS没有把所有需要加载的扇区都加载?

答:对BIOS 而言,“约定”在接到启动操作系统的命令后,“定位识别”只从启动扇区把代码加载到0x7c00 这个位置。后续扇区则由bootsect 代码加载,这些代码由编写系统的用户负责,与BIOS 无关。这样构建的好处是站在整个体系的高度,统一设计和统一安排,简单而有效。BIOS 和操作系统的开发都可以遵循这一约定,

灵活地进行各自的设计。例如,BIOS 可以不用知道内核镜像的大小以及其在软盘的分布等等信息,减轻了BIOS 程序的复杂度,降低了硬件上的开销。而操作系统的开发者也可以按照自己的意愿,内存的规划,等等都更为灵活。另外,如果要使用BIOS 进行加载,而且加载完成之后再执行,则需要很长的时间,因此Linux 采用的是边执行边加载的方法。

3. 为什么BIOS把bootsect加载到0x07c00,而不是0x00000?加载后又马上挪到

0x90000 处,是何道理?为什么不一次加载到位?

答:因为BIOS首先会把中断向量表加载到0x00000-0x003ff的1KB的内存空间,在加载bootsect时约定加载到0x07c00处,符合内存布局,如下。

加载之后挪到0x90000处的原因如下:首先内核会使用启动扇区中的一些数据,如第508、509 字节处的RO OT_DEV ;其次,依据系统对内存的规划,内核占用

0x0000开始的空间,因此0x7c00可能会被覆盖。因为加载到0x07c00是BIOS 约定好的,操作系统只能遵守这个约定。

4. bootsec、setup head程序之间是怎么衔接的?给出代码证据。

答:bootsect首先利用int 0x13中断分别加载setup程序及system模块,待bootsect 程序的任务完成之后,执行jmpi 0,SETUPSEG

由于bootsect 将setup 段加载到了SETUPSEG:0 的地方,在实模式下,该指令跳转到setup段的第一条指令。

setup执行了之后,内核被移到了0x00000处,系统进入了保护模式,并加载了中断描述符表和全局描述符表

lidt idt_48 lgdt gdt_48 在保护模式下,一个重要的特征就是根据GDT 决定后续执行哪里的程序。开启保护模式后,执行

jmpi 0, 8

根据保护模式的机制,该指令执行后跳转到以GDT 第2 项中的base_addr 为基地址,以0为偏移量的地方,其中base_addr为0。由于head放置在内核的头部,因此程序跳转到head中执行

5. setup程序里的cli是为了什么?

答:cli是关中断指令。因为此时需要由16位实模式向32位保护模式转变,即将进行实模式下的中断向量表和保护模式下中断描述符表的交接工作,在保护模式的中断机制尚未完成时不允许响应中断,以免发生未知的错误。

6. setup程序的最后是jmpi 0,8为什么这个8不能简单的当作阿拉伯数字8看待?答:这里8 要看成二进制1000,最后两位00 表示内核特权级,第三位0 表示GDT 表,第四位1 表示根据GDT 中的第2项来确定代码段的段基址和段限长等信息。这样,我们可以得到代码是从段基址0x00000000偏移为0处开始执行的,即head 的开始位置。注意到已经开启了保护模式的机制,这里的8 是保护模式下的段选择符,而不能当成简单的阿拉伯数字8来看待。

7. 打开A20和打开pe究竟是什么关系,保护模式不就是32位的吗?为什么还要打

开A20 ?有必要吗?

答:有必要。A20 是cpu 的第21 位地址线,A20 未打开的时候,实模式下的最大寻址为1MB+64KB,而第21根地址线被强制为0,所以相当于cpu “回滚” 到内存地址起始处寻址。打开A20仅仅意味着CPU可以进行32位寻址,且最大寻址空间是

4GB,而打开PE是使能保护模式。打开A20是打开PE的必要条件;而打开A20不一定非得打开PE。打开PE是说明系统处于保护模式下,如果不打开A20 的话,可以访问的内存只能是奇数1M 段,若要真正在保护模式下工作,必须打开A20,实现32位寻址。

8. Linux是用C语言写的,为什么没有从main还是开始,而是先运行3个汇编程

序,道理何在?

答:通常用C 语言编写的程序都是用户应用程序,这类程序的执行必须在操作系统上执行,也就是说要由操作系统为应用程序创建进程,并把应用程序的可执行代码从硬盘加载到内存。

而在计算机刚刚加电时,内存中没有操作系统程序,只有BIOS 程序在运行,需要借助BIOS分别加载bootsec、setup及system模块,然后利用这3个程序来完成内存规划、建立IDT和GDT、设置分页机制等等,并实现从开机时的16位实模式到main 函数执行需要的32 位保护模式之间的转换。

当计算机处在32位的保护模式状态下时,调用main的条件才算准备完毕。

9. 为什么不用call,而是用ret “调用” main函数?画出调用路线图,给出代码证

据。

答:CALL 指令会将EIP 的值自动压栈,保护返回现场,然后执行被调函数,档执行到被调函数的ret指令时,自动出栈给EIP并还原现场,继续执行CALL 的下一行指令。在由head程序向main函数跳转时,是不需要main函数返回的;同时由于

main 函数已经是最底层的函数了,没有更底层的支撑函数支持其返回。所以要达到既调用main又不需返回,就不采用call而是选择了ret“调用”了。调用线路图见

P42 图1-46。

代码如下:

af:

pu^hl

pushl $0

pushl $0

pushl 5L6

pushl $_main jir.p sctiip_p3ging

(见P36最下面)

setup_pag ing

ret

10•保护模式的“保护”体现在哪里?

相关文档
最新文档