1.为什么开始启动计算机的时候,执行的是bios**而不是操作系统自身的**?
计算机启动的时候,内存未初始化,cpu不能直接从外设运行操作系统,所以必须将操作系统加载至内存中,而这个工作最开始的部分,bios需要完成一些检测工作,和设置实模式下的中断向量表和服务程序,并将操作系统的引导扇区加载值0x7c00处,然后将跳转至0x7c00。这些就是由bios程序来实现的。所以计算机的启动最开始执行的是bios**。
2.为什么bios只加载了一个扇区,后续扇区却是由bootsect**加载?为什么bios没有直接把所有需要加载的扇区都加载?
对于bios来说,“约定”在接到启动操作系统的命令后,“定位识别”只从启动扇区把**加载到0x7c00这个位置。后续扇区则由bootsect**加载,这些**由编写系统的用户负责,与bios无关。这样构建的好处就是站在整个体系的高度,统一设计和统一安排,简单而有效。
bios和操作系统的开发都可以遵循这一约定,灵活地进行各自的设计。操作系统的开发也可以按照自己的意愿,内存的规划等等都很灵活。
3.为什么bios把bootsect加载到0x07c00,而不是0x00000?加载后又马上挪到0x90000处,是何道理?为什么不一次加载到位?
1)因为bios将从0x00000开始的1kb字节构建中断向量表,接着的256k字节内存空间构建了bios数据区,所以不能把bootsect加载到0x00000,0x07c00是bios设置的内存地址,不是bootsect能够决定的。
2)首先,在启动扇区中会有一些数据,将会被内核利用到。
其次,依据系统对内存的规划,内核终会将占用0x0000其中的空间,因此0x7c00可能被覆盖。将该扇区挪到0x90000,在中,获取一些硬件数据保存在0x90000-0x901ff处,可以对一些后面内核将要利用的数据集中保存和管理。
程序之间是怎么衔接的?给出**证据。
1)bootsect跳转到setup程序:jumpi 0 ,setupseg
这句**跳转到0x90200处,即setup程序加载的位置,cs:ip指向setup程序的第一条指令,意味着setup开始执行。
2)setup跳转到head程序,cpu工作模式首先转变为保护模式然后执行jumpi 0,8
0指的是段内偏移,8是保护模式下的段选择符:01000,其中两位表示内核特权级,第三位0代表gdt,1表示gdt表中中的内核**段,段基址为0x00000000,而head程序地址就在这里,意味着head程序开始执行。
程序的最后是jmpi 0,8 ,为什么这个8不能简单的当作阿拉伯数字8看待,究竟有什么内涵?
这里面的8要看作是二进制的1000,最后两位00表示内核特权级,第三位0表示gdt表,第四位1表示所选的表的1项来确定内核**段的段基址和段线长等信息。这样我们得到的**就是从段基址0x00000000偏移为0处开始执行,即head的开始位置。
6.保护模式在“保护”什么?它的“保护”体现在**?特权级的目的和意义是什么?分页有“保护”作用吗?
1)在gdt、ldt及idt中,均有自己的界限,特权级等属性,这是对描述符所描述的对象的保护。
2)在不同的特权级间访问的时候,系统会对cpl、rpl、dpl、iopl等进行检验,对不同层级的程序进行保护,还限制某些特殊指令的使用如lgdt、lidt、cli等。
3)分页机制中pde和pte中的r/w和u/s等,提供了页级保护。分页机制将线性地址与物理地址加以映射,提供了对物理地址的保护。
特权级目的:在于保护高特权的段,其中操作系统的内核处于最高的特权级。
特权级意义:在于保护模式中的特权级,对操作系统的“主奴机制”影响深远。
7.在setup程序里曾经设置过gdt,为什么在head程序中将其废弃,又重新设置了一个?为什么设置两次,而不是一次搞好?
原来的gdt位于setup中,将来此段内存会被缓冲区覆盖,所以必须将gdt设置所在位置。如果先将gdt设置在head所在区域,然后移动system模块,则gdt会被覆盖,如果先移动system在复制gdt,则对应的程序会被覆盖掉,必须重建gdt。若先移动system至0x0000再将gdt复制到0x5cb8-0x64b8处,虽然可以实现,但由于与连接时不在同一文件,setup无法直接获取head中的gdt的偏移量,需事先写入,这会使设计失去一般性,给程序编写带来很大不便。
8.进程0的task_struct在哪?具体内容是什么?
进程0的task_struct是操作系统设计者事先写好的,位于内核数据区,存储在user_task中(因为在进程0未激活之前,使用的是boot阶段的user_task)
static union task_union init_task =
具体内容如下:
包含了进程0的进程状态,进程0的ldt、进程0的tss等等。其中ldt设置了**段和堆栈段的基址和线长(640kb)。而tss则保存了各种寄存器的值,包括各个段选择符。
9.内核的线性地址空间是如何分页的?画出从0x000000开始的7个页(包括页目录表、页表所在页)的挂接关系图,就是页目录表的前四个页目录项、第一个个页表的前7个页表项指向什么位置?
给出**证据。
在setup_paging开始创建分页机制。将页目录表和4个页表放在物理内存的起始位置开始的5个页空间内容全部清零(每页4kb),然后设置页目录表的前4项,分别指向4个页表。然后开始从高地址向低地址方向填写4个页表,依次指向内存从高地址向低地址方向的各个页面。
即将第4个页表的最后一项(pg3+4092指向的位置)指向寻址范围的最后一个页面。即从0xfff000开始的4kb大小的内存空间。将第4个页表的倒数第二个页表项(pg3-4+4092)指向倒数第二个页面,即0xfff000-0x1000开始的4kb字节的内存空间。
中:setup_paging:
movl $1024*5, %ecx
xorl %eax,%eax
xorl %edi,%eax
xorl %edi,%edi
cld;rep;stosl
movl $pg0+7 pg
movl 10.在head程序执行结束的时候,在idt的前面有184个字节的head程序的剩余**,剩余了什么?为什么要剩余?
11.为什么不用call,而是用ret“调用”main函数?画出调用路线图,给出**证据。
12.用文字和图说明中断描述符表是如何初始化的,可以举例说明(比如:set_trap_gate(0,÷_error)),并给出**证据。
13.在ia-32中,有大约20多个指令是只能在0特权级下使用,其他的指令,比如cli,并没有这个约定。奇怪的是,在linux0.
11中,3特权级的进程**并不能使用cli指令,这是为什么?请解释并给出**证据。
14.进程0的task_struct在哪?具体内容是什么?给出**证据。
进程0的task_struct位于内核数据区,即task结构的第0项init_task。
struct task_struct* task[nr_tasks] =
具体内容:包含了进程0的进程状态、进程0的ldt、进程0的tss等等。其中ldt设置了**段和堆栈段的基址和限长(640kb),而tss则保存了各种寄存器的值,包括了各个段选择符。
具体值如下(课本p68)
15.在里。
#define _set_gate(gate_addr,type,dpl,addr) \
_asm__ movw %%dx,%%ax\t" \
"movw %0,%%dx\t" \
"movl %%eax,%1\t" \
"movl %%edx,%2" \
: "i" (short) (0x8000+(dpl<<13)+(type<<8)))
"o" (char *)gate_addr)))
"o" (4+(char *)gate_addr)))
"d" (char *)addr)),a" (0x00080000))
#define set_intr_gate(n,addr) \
_set_gate(&idt[n],14,0,addr)
#define set_trap_gate(n,addr) \
_set_gate(&idt[n],15,0,addr)
#define set_system_gate(n,addr) \
_set_gate(&idt[n],15,3,addr)
这里中断门、陷阱门、系统调用都是通过_set_gate设置的,用的是同一个嵌入汇编**,比较明显的差别是dpl一个是3,另外两个是0,这是为什么?说明理由。p61
dpl表示的是特权级,0和3分别表示0特权级和3特权级。异常处理是由内核来完成,linux处于对内核的保护,不允许用户进程直接访问内核。但是有些情况下,用户进程又需要内核**的支持,因此就需要系统调用,它是用户进程与内核打交道的接口,是由用户进程直接调用的。
因此其在3特权级下。
16.进程0 fork进程1之前,为什么先调用move_to_user_mode()?用的是什么方法?解释其中的道理。
因为在linux-011中,除进程0之外,所有进程都是由一个已有进程在用户态下完成创建的,但是此时进程0还处于内核态,因此要调用move_to_user_mode()函数,模仿终端返回的方式,实现进程0的特权级从内核态转化成用户态,又因为在linux-0.11中转换特权级时采用中断和中断返回的方式,调用系统中断实现从3到0的特权级转换,中断返回时转换为3特权级。因此,进程0从0特权级到3特权级转换时采用的是模拟中断返回。
17.在linux操作系统中大量使用了中断、异常类的处理,究竟有什么好处?
操作系统高级教程 思考题
1.进程0创建进程1时,为进程1建立了自己的task struct 内核栈,第一个页表,分别位于物理内存16mb的顶端倒数第一页 第二页。请问,这个了页究竟占用的是谁的线性地址空间,内核 进程0 进程1 还是没有占用任何线性地址空间?说明理由并给出 证据。答 两次都是通过调用get free pag...
高级操作系统
分布式系统概念 一个分布式系统是若干个独立的计算机的集合,但是对该系统的用户来说,感觉该系统就像一台计算机一样。分布式操作系统 是对分布式系统提供资源管理的软件系统。通常表现为中间件形式。一 分布式系统的关键目标。分布式系统的4个关键目标 1 必须是资源共享的。要让用户方便地访问资源,并且以一种受控...
高级操作系统
目录。1.分布式操作系统透明性的含义是什么?课本8.5分布式系统的透明性 2 2.简述一种分布式操作系统的时钟同步算法 2 3.为什么需要动态负载平衡?影响其效率的3个主要因素是什么?3 4.论述windows操作系统的安全性 3 4.1 windows操作系统的安全性讨论 3 4.1.1 wind...