当前位置:文档之家› 中科院操作系统高级教程_思考题_2015最新完整版

中科院操作系统高级教程_思考题_2015最新完整版

中科院操作系统高级教程_思考题_2015最新完整版
中科院操作系统高级教程_思考题_2015最新完整版

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字节构建了了中断向量表,接着的256KB字节内存空间构建了BIOS数据区,所以不能把bootsect加载到0x00000. 0X07c00是BIOS设置的内存地址,不是bootsect能够决定的。

2)首先,在启动扇区中有一些数据,将会被内核利用到。

其次,依据系统对内存的规划,内核终会占用0x0000其实的空间,因此0x7c00可能会被覆盖。将该扇区挪到0x90000,在setup.s中,获取一些硬件数据保存在0x90000~0x901ff处,可以对一些后面内核将要利用的数据,集中保存和管理。

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

1)bootsect跳转到setup程序:jmpi 0,SETUPSEG;

这条语句跳转到0x90200处,即setup程序加载的位子,CS:IP指向setup程序的第一条指令,意味着setup开始执行。

2)setup跳转到head程序:CPU工作模式首先转变为保护模式然后执行jmpi 0,8

0指的是段内偏移,8是保护模式下的段选择符:01000,其中后两位表示内核特权级,第三位0代表GDT,1则表示GDT表中的第一项,即内核代码段,段基质为0x0000000,而head 程序地址就在这里,意味着head程序开始执行。

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

cli为关中断,以为着程序在接下来的执行过程中,无论是否发生中断,系统都不再对此中断进行响应。

因为在setup中,需要将位于0x10000 的内核程序复制到0x0000 处,bios中断向量表覆盖掉了,若此时如果产生中断,这将破坏原有的中断机制会发生不可预知的错误,所以要禁示中断。

6.setup程序的最后是jmpi 0,8 为什么这个8不能简单的当作阿拉伯数字8看待?

这里8要看成二进制1000,最后两位00表示内核特权级,第三位0表示GDT表,第四位1表示所选的表(在此就是GDT表)的1项来确定代码段的段基址和段限长等信息。这样,我们可以得到代码是从段基址0x00000000、偏移为0处开始执行的,即head的开始位置。

注意到已经开启了保护模式的机制,所以这里的8不能简单的当成阿拉伯数字8来看待。

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

1、打开A20仅仅意味着CPU可以进行32位寻址,且最大寻址空间是4GB。打开PE是进入保护模式。A20是cpu的第21位地址线,A20未打开的时候,实模式中cs:ip最大寻址为1MB+64KB,而第21根地址线被强制为0,所以相当于cpu“回滚”到内存地址起始处寻址。当打开A20的时候,实模式下cpu可以寻址到1MB以上的高端内存区。A20未打开时,如果打开pe,则cpu进入保护模式,但是可以访问的内存只能是奇数1M段,即0-1M,2M-3M,4-5M等。A20被打开后,如果打开pe,则可以访问的内存是连续的。打开A20是打开PE的必要条件;而打开A20不一定非得打开PE。

2、有必要。打开PE只是说明系统处于保护模式下,但若真正在保护模式下工作,必须打开A20,实现32位寻址。

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

main 函数运行在32 位的保护模式下,但系统启动时默认为16 位的实模式,开机时的16 位实模式与main 函数执行需要的32 位保护模式之间有很大的差距,这个差距需要由3 个汇编程序来填补。其中bootsect 负责加载,setup 与head 则负责获取硬件参数,准备idt,gdt,开启A20,PE,PG,废弃旧的16 位中断响应机制,建立新的32 为IDT,设置分页机制等。这些工作做完后,计算机处在了32位的保护模式状态了,调用main的条件就算准备完毕。

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

call指令会将EIP的值自动压栈,保护返回现场,然后执行被调函数的程序,等到执行被调函数的ret指令时,自动出栈给EIP并还原现场,继续执行call的下一条指令。然而对操作系统的main函数来说,如果用call调用main函数,那么ret时返回给谁呢?因为没有更底层的函数程序接收操作系统的返回。用ret实现的调用操作当然就不需要返回了,call做的压栈和跳转动作需要手工编写代码。

after_page_tables:

pushl $__main; //将main的地址压入栈,即EIP

setup_paging:

ret; //弹出EIP,针对EIP指向的值继续执行,即main函数的入口地址。

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

1)在GDT、LDT 及IDT 中,均有自己界限,特权级等属性,这是对描述符所描述的对象的保护

2)在不同特权级间访问时,系统会对CPL、RPL、DPL、IOPL 等进行检验,对不同层级的程序进行保护,同还限制某些特殊指令的使用,如lgdt, lidt,cli 等

3)分页机制中PDE 和PTE 中的R/W 和U/S 等,提供了页级保护。分页机制将线性地址与物理地址加以映射,提供了对物理地址的保护。

P438

11.特权级的目的和意义是什么?为什么特权级是基于段的?

目的:在于保护高特权级的段,其中操作系统的内核处于最高的特权级。

意义:保护模式中的特权级,对操作系统的“主奴机制”影响深远。

在操作系统设计中,一个段一般实现的功能相对完整,可以把代码放在一个段,数据放在一个段,并通过段选择符(包括CS、SS、DS、ES、FS和GS)获取段的基址和特权级等信息。特权级基于段,这样当段选择子具有不匹配的特权级时,按照特权级规则评判是否可以访问。特权级基于段,是结合了程序的特点和硬件实现的一种考虑。

12.在setup程序里曾经设置过一次gdt,为什么在head程序中将其废弃,又重新设置了一个?为什么折腾两次,而不是一次搞好?

原来的GDT 位于setup 中,将来此段内存会被缓冲区覆盖,所以必须将GDT 设置head.s 所在位置。

如果先将GDT 设置在head 所在区域,然后移动system 模块,则GDT 会被覆盖掉,如果先移动system 再复制GDT,则head.s 对应的程序会被覆盖掉,所以必须重建GDT。若先移动system 至0x0000 再将GDT 复制到0x5cb8~0x64b8 处,虽可以实现,但由于setup.s 与head.s 连接时不在同一文件,setup 无法直接获取head 中的gdt 的偏移量,需事先写入,这会使设计失去一般性,给程序编写带来很大不便。

13.在head程序执行结束的时候,在idt的前面有184个字节的head程序的剩余代码,剩余了什么?为什么要剩余?

剩余的内容:0x5400~0x54b7 处包含了after_page_tables、ignore_int 中断服务程序和setup_paging 设置分页的代码。

原因:after_page_tables中压入了一些参数,为内核进入main函数的跳转做准备。为了谨慎起见,设计者在栈中压入了L6,以使得系统可能出错时,返回到L6处执行。ignore_int: 使用ignore_int将idt全部初始化,因此如果中断开启后,可能使用了未设置的中断向量,那么将默认跳转到ignore_int处执行。这样做的好处是使得系统不会跳转到随机的地方执行错误的代码,所以ignore_int不能被覆盖。setup_paging:为设置分页机制的代码,它在分页完成前不能被覆盖

14.进程0的task_struct在哪?具体内容是什么?给出代码证据。

进程0的task_struct位于内核数据区,即task结构的第0项init_task。

struct task_struct * task[NR_TASKS] = {&(init_task.task), };

具体内容:包含了进程0的进程状态、进程0的LDT、进程0的TSS等等。其中ldt设置了代码段和堆栈段的基址和限长(640KB),而TSS则保存了各种寄存器的值,包括各个段选择符。具体值如下:(课本P68)

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

这两个页占用的是内核的线性地址空间,依据在setup_paging(文件head.s)中,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

上面的代码,指明了内核的线性地址空间为0x000000 ~ 0xffffff(即前16M),且线性地址与物理地址呈现一一对应的关系。为进程1分配的这两个页,在16MB的顶端倒数第一页、第二页,因此占用内核的线性地址空间。

进程0的线性地址空间是内存前640KB,因为进程0的LDT中的limit属性限制了进程0能够访问的地址空间。进程1拷贝了进程0的页表(160项),而这160个页表项即为内核

第一个页表的前160项,指向的是物理内存前640KB,因此无法访问到16MB的顶端倒数的两个页。

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

这两个页面均占用内核的线性空间。

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

首先在copy_process()函数中,对进程1 做个性化调整设置,调整tss的数据。

Int copy_process(int nr, long ebp,…)

P92

然后再执行到如下代码:

#define switch_to()……

ljmp….

p196

程序在执行到“ljmp %0/n/t”这一行,ljmp通过cpu任务们机制自动将进程1 的tss值恢复给cpu,自然也将其中tss.eip恢复给cpu,现在cpu指向fork的if(_res >=0)这一行。

而此时的_res值就是进程1中tss的eax的值,这个值在前面被写死为0,即p->tss.eax=0;所以直行到return (type) _res这一行返回值为0.

V oidmain(void)

if(!fork())

init();

返回后,执行到main函数中if(!fork())这一行,!0值为真,调用init()函数。

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

copy_process执行时因为进程调用了fork函数,会导致中断,中断使CPU硬件自动将SS、ESP、EFLAGS、CS、EIP这几个寄存器的值按照顺序压入进程0内核栈,又因为函数专递参数是使用栈的,所以刚好可以做为copy_process的最后五项参数。

19.为什么static inline _syscall0(type,name)中需要加上关键字inline?

因为_syscall0(int,fork)展开是一个真函数,普通真函数调用事需要将eip入栈,返回时需要讲eip出栈。inline是内联函数,它将标明为inline的函数代码放在符号表中,而此处的fork 函数需要调用两次,加上inline后先进行词法分析、语法分析正确后就地展开函数,不需要有普通函数的call\ret等指令,也不需要保持栈的eip,效率很高。若不加上inline,第一次调用fork结束时将eip 出栈,第二次调用返回的eip出栈值将是一个错误值。

20.根据代码详细说明copy_process函数的所有参数是如何形成的?

long eip, long cs, long eflags, long esp, long ss;这五个参数是中断使CPU自动压栈的。

long ebx, long ecx, long edx, long fs, long es, long ds为__system_call压进栈的参数。

long none 为__system_call调用__sys_fork压进栈EIP的值。

Int nr, long ebp, long edi, long esi, long gs,为__system_call压进栈的值。

21.根据代码详细分析,进程0如何根据调度第一次切换到进程1的。(P103-107)

1.进程0通过fork函数创建进程1,使其处在就绪态。

2.进程0调用pause函数。pause函数通过int 0x80中断,映射到sys_pause函数,将自身设为可中断等待状态,调用schedule函数。

3.schedule函数分析到当前有必要进行进程调度,第一次遍历进程,只要地址指针不为为空,就要针对处理。第二次遍历所有进程,比较进程的状态和时间骗,找出处在就绪态且counter 最大的进程,此时只有进程0和1,且进程0是可中断等待状态,只有进程1是就绪态,所以切换到进程1去执行。

22.内核的线性地址空间是如何分页的?画出从0x000000开始的7个页(包括页目录表、页表所在页)的挂接关系图,就是页目录表的前四个页目录项、第一个个页表的前7个页表项指向什么位置?给出代码证据。

head.s再setup_paging开始创建分页机制。将页目录表和4个页表放到物理内存的起始位置,从内存起始位置开始的5个页空间内容全部清零(每页4kb),然后设置页目录表的前4项,使之分别指向4个页表。然后开始从高地址向低地址方向填写4个页表,依次指向内存从高地址向低地址方向的各个页面。即将第4个页表的最后一项(pg3+4092指向的位置)指向寻址范围的最后一个页面。即从0xFFF000开始的4kb 大小的内存空间。将第4个页表的倒数第二个页表项(pg3-4+4092)指向倒数第二个页面,即0xFFF000-0x1000开始的4KB字节的内存空间,依此类推。

Head.s中:(P39)

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 /* --------- " " --------- */

_pg_dir用于表示内核分页机制完成后的内核起始位置,也就是物理内存的起始位置0x000000,以上四句完成页目录表的前四项与页表1,2,3,4的挂接

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

完成页表项与页面的挂接,是从高地址向低地址方向完成挂接的,16M内存全部完成挂接(注意页表从0开始,页表0-页表3)

图见P39

23.用文字和图说明中断描述符表是如何初始化的,可以举例说明(比如:set_trap_gate(0,÷_error)),并给出代码证据。

对中断描述符表的初始化,就是将异常处理一类的中断服务程序与中断描述符表进行挂接。以set_trap_gate(0,÷_error)为例,0就表示该中断函数的地址挂接在中断描述符表的第0项位置处,而&devide_error就是该异常处理函数的地址,对set_trap_gate(0,÷_error)进行宏展开后得到

%0=0x8f00,%1指向idt[0]的起始地址,%2指向四个字节之后的地址处。

#1、将地址&devide_error放在EAX的低两个字节,EAX的高两字节不变。#2把0x8f00放入EDX的低两字节,高两字节保持不变。#3、把EAX放在%1所指的地址处,占四字节。#4、将EDX放在%2所指的地址处,占四字节。

24.进程0 fork进程1之前,为什么先要调用move_to_user_mode()?用的是什么方法?解释其中的道理。(P78-79)

因为在Linux-0.11中,除进程0之外,所有进程都是由一个已有进程在用户态下完成创建的。但是此时进程0还处于内核态,因此要调用move_to_user_mode()函数,模仿中断返回的方式,实现进程0的特权级从内核态转化为用户态。又因为在Linux-0.11中,转换特权级时采用中断和中断返回的方式,调用系统中断实现从3到0的特权级转换,中断返回时转换为3特权级。因此,进程0从0特权级到3特权级转换时采用的是模仿中断返回。

25.进程0创建进程1时调用copy_process函数,在其中直接、间接调用了两次get_free_page 函数,在物理内存中获得了两个页,分别用作什么?是怎么设置的?给出代码证据。(P89 91 92P97-98 )

第一个设置进程1的tasks_truct,另外设置了进程1的堆栈段

sched.c

struct task_struct *current = &(init_task.task);

fork.c

p = (struct task_struct *) get_free_page();

*p = *current;

p->tss.esp0 = PAGE_SIZE + (long) p;

其中*current 即为进程0的task结构,在copy_process中,先复制进程0的task_struct,然后再对其中的值进行修改。esp0 的设置,意味着设置该页末尾为进程1的堆栈的起始地址。第二个为进程1的页表,在创建进程1执行copy_process中,执行copy_mem(nr,p)时,内核为进程1 拷贝了进程0 的页表(160 项)。

copy_mem

if (copy_page_tables(old_data_base,new_data_base,data_limit)){

其中,copy_page_tables 内部

from_page_table = (unsigned long *) (0xfffff000 & *from_dir);

if (!(to_page_table = (unsigned long *) get_free_page()))

for ( ; nr-- > 0 ; from_page_table++,to_page_table++) {

… }

获取了新的页,且从from_page_table 将页表值拷贝到to_page_table 处。

26.在IA-32中,有大约20多个指令是只能在0特权级下使用,其他的指令,比如cli,并没有这个约定。奇怪的是,在Linux0.11中,在3特权级的进程代码并不能使用cli指令,会报特权级错误,这是为什么?请解释并给出代码证据。

根据Intel Manual,cli和sti指令与CPL和EFLAGS[IOPL]有关。

CLI:如果CPL 的权限高于等于eflags中的IOPL的权限,即数值上:cpl <= IOPL,则IF 位清

除为0;否则它不受影响。EFLAGS 寄存器中的其他标志不受影响。

#GP(0) –如果CPL大于(特权更小)当前程序或过程的IOPL,产生保护模式异常。

由于在内核IOPL的值初始时为0,且未经改变。进程0在move_to_user_mode中,继承了内核的eflags。

move_to_user_mode()

"pushfl\n\t" \

"iret\n" \

而进程1再copy_process中,在进程的TSS中,设置了eflags中的IOPL位为0。总之,通

设置IOPL,可以限制3 特权级的进程代码使用cli。

27.根据代码详细分析操作系统是如何获得一个空闲页的。(P89-90)

通过逆向扫描页表位图mem_map,并由第一空页的下标左移12位加LOW_MEM得到该页的物理地址,位于16M 内存末端。代码如下(get_free_page)

unsigned long get_free_page(void)

64 {

65 register unsigned long __res asm("ax");

66

67 __asm__("std ; repne ; scasb\n\t" //反向扫描串,al(0)与di不等则重复

68 "jne 1f\n\t" //找不到空闲页跳转1

69 "movb $1,1(%%edi)\n\t" //将1付给edi+1的位置,在mem_map中将找到0的项引用计------------------------------------------数置为1

70 "sall $12,%%ecx\n\t" //ecx算数左移12位,页的相对地址

71 "addl %2,%%ecx\n\t" //LOW MEN +ecx页物理地址

72 "movl %%ecx,%%edx\n\t"

73 "movl $1024,%%ecx\n\t"

74 "leal 4092(%%edx),%%edi\n\t" //将edx+4kb的有效地址赋给edi

75 "rep ; stosl\n\t" //将eax赋给edi指向的地址,目的是页面清零。

76 " movl %%edx,%%eax\n"

77 "1: cld"

78 :"=a" (__res)

79 :"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES),

80 "D" (mem_map+PAGING_PAGES-1) //edx,mem_map[]的嘴鸥一个元素

81 );

82 return __res;

83 }

28、用户进程自己设计一套LDT表,并与GDT挂接,是否可行,为什么?(P259)

不可行。首先,用户进程不可以设置GDT、LDT,因为Linux0.11将GDT、LDT这两个数据结构设置在内核数据区,是0特权级的,只有0特权级的额代码才能修改设置GDT、LDT;而且,用户也不可以在自己的数据段按照自己的意愿重新做一套GDT、LDT,如果仅仅是形式上做一套和GDT、LDT一样的数据结构是可以的,但是真正起作用的GDT、LDT是CPU硬件认定的,这两个数据结构的首地址必须挂载在CPU中的GDTR、LDTR上,运行时CPU只认GDTR和LDTR指向的数据结构,其他数据结构就算起名字叫GDT、LDT,CPU也一概不认;另外,用户进程也不能将自己制作的GDT、LDT挂接到GDRT、LDRT 上,因为对GDTR和LDTR的设置只能在0特权级别下执行,3特权级别下无法把这套结构挂接在CR3上。

29、保护模式下,线性地址到物理地址的转化过程是什么?(P260-261)

在保护模式下,先行地址到物理地址的转化是通过内存分页管理机制实现的。其基本原理是将整个线性和物理内存区域划分为4K大小的内存页面,系统以页为单位进行分配和回收。每个线性地址为32位,MMU按照10-10-12的长度来识别线性地址的值。CR3中存储着页目录表的基址,线性地址的前十位表示也目录表中的页目录项,由此得到所在的页表地址。21~12位记录了页表中的页表项位置,由此得到页的位置,最后12位表示页内偏移。

30、为什么get_free_page()将新分配的页面清0?(P265)

因为无法预知这页内存的用途,如果用作页表,不清零就有垃圾值,就是隐患。

31、内核和普通用户进程并不在一个线性地址空间内,为什么仍然能够访问普通用户进程的页面?(P272)

内核的线性地址空间和用户进程不一样,内核是不能通过跨越线性地址访问进程的,但由于早就占有了所有的页面,而且特权级是0,所以内核执行时,可以对所有的内容进行改动,“等价于”可以操作所有进程所在的页面。

32、详细分析一个进程从创建、加载程序、执行、退出的全过程。

1.创建进程,调用fork函数。

a)准备阶段,为进程在task[64]找到空闲位置,即find_empty_process();

b)为进程管理结构找到储存空间:task_struct和内核栈。

c)父进程为子进程复制task_struct结构

d)复制新进程的页表并设置其对应的页目录项

e)分段和分页以及文件继承。

f)建立新进程与全局描述符表(GDT)的关联

g)将新进程设为就绪态

2.加载进程

a)检查参数和外部环境变量和可执行文件

b)释放进程的页表

c)重新设置进程的程序代码段和数据段

d)调整进程的task_struct

3.进程运行

a)产生缺页中断并由操作系统响应

b)为进程申请一个内存页面

c)将程序代码加载到新分配的页面中

d)将物理内存地址与线性地址空间对应起来

e)不断通过缺页中断加载进程的全部内容

f)运行时如果进程内存不足继续产生缺页中断,

4.进程退出

a)进程先处理退出事务

b)释放进程所占页面

c)解除进程与文件有关的内容并给父进程发信号

d)进程退出后执行进程调度

33、详细分析多个进程(无父子关系)共享一个可执行程序的完整过程。

假设有三个进程A、B、C,进程A先执行,之后是B最后是C,它们没有父子关系。A进程启动后会调用open函数打开该可执行文件,然后调用sys_read()函数读取文件内容,该函数最终会调用bread函数,该函数会分配缓冲块,进行设备到缓冲块的数据交换,因为此时为设备读入,时间较长,所以会给该缓冲块加锁,调用sleep_on函数,A进程被挂起,调用schedule()函数B进程开始执行。

B进程也首先执行open()函数,虽然A和B打开的是相同的文件,但是彼此操作没有关系,所以B继承需要另外一套文件管理信息,通过open_namei()函数。B进程调用read函数,同样会调用bread(),由于此时内核检测到B进程需要读的数据已经进入缓冲区中,则直接返回,但是由于此时设备读没有完成,缓冲块以备加锁,所以B将因为等待而被系统挂起,之后调用schedule()函数。

C进程开始执行,但是同B一样,被系统挂起,调用schedule()函数,假设此时无其它进程,则系统0进程开始执行。

假设此时读操作完成,外设产生中断,中断服务程序开始工作。它给读取的文件缓冲区解锁并调用wake_up()函数,传递的参数是&bh->b_wait,该函数首先将C唤醒,此后中断服务程序结束,开始进程调度,此时C就绪,C程序开始执行,首先将B进程设为就绪态。C执行结束或者C的时间片削减为0时,切换到B进程执行。进程B也在sleep_on()函数中,调用schedule函数进程进程切换,B最终回到sleep_on函数,进程B开始执行,首先将进程A 设为就绪态,同理当B执行完或者时间片削减为0时,切换到A执行,此时A的内核栈中tmp对应NULL,不会再唤醒进程了。

34、缺页中断是如何产生的,页写保护中断是如何产生的,操作系统是如何处理的?

每一个页目录项或页表项的最后3位,标志着所管理的页面的属性,分别是U/S,R/W,P.如果和一个页面建立了映射关系,P标志就设置为1,如果没有建立映射关系,则就是0.进程执行时,线性地址被MMU即系,如果解析出某个表项的P位为0,就说明没有对应页面,此时就会产生缺页中断。

当两个进程共享了一个页面,即R/w为1,导致该页面设为“只读”属性,当其中一个进程需要压栈时就会引发页写保护中断。当页写保护中断产生时,系统会为进程申请新页面,并把原页面内容复制到新页面里。

35、为什么要设计缓冲区,有什么好处?(P310)

缓冲区是内存与外设(块设备,如硬盘等)进行数据交互的媒介。内存与外设最大的区别在于:外设(如硬盘)的作用仅仅就是对数据信息以逻辑块的形式进行断电保存,并不参与运算(因为CPU无法到硬盘上进行寻址);而内存除了需要对数据进行保存以外,还要通过与CPU和总线的配合,进行数据运算(有代码和数据之分);缓冲区则介于两者之间,有了缓冲区这个媒介以后,对外设而言,它仅需要考虑与缓冲区进行数据交互是否符合要求,而不需要考虑内存中内核、进程如何使用这些数据;对内存的内核、进程而言,它也仅需要考虑与缓冲区交互的条件是否成熟,而并不需要关心此时外设对缓冲区的交互情况。它们两者的组织、管理和协调将由操作系统统一操作,这样就大大降低了数据处理的维护成本。缓冲区的好处主要有两点:①形成所有块设备数据的统一集散地,操作系统的设计更方便、更灵活;②对块设备的文件操作运行效率更高。

36、操作系统如何利用buffer_head中的b_data,b_blocknr,b_dev,b_uptodate,b_dirt,b_count,b_lock,b_wait管理缓冲块的?

buffer_head负责进程与缓冲块的数据交互,让数据在缓冲区中停留的时间尽可能长。

b_data 是缓冲块的数据内容。

b_dev和b_blocknr两个字段把缓冲块和硬盘数据块的关系绑定,同时根据b_count决定是否废除旧缓冲块而新建缓冲块以保证数据在缓冲区停留时间尽量长。

b_dev为设备标示,b_blocknr标示block块好。b_count用于记录缓冲块被多少个进程共享了。

b_uptodate和b_dirt用以保证缓冲块和数据块的正确性。b_uptodate为1说明缓冲块的数据就是数据块中最新的,进程可以共享缓冲块中的数据。b_dirt为1时说明缓冲块数据已被进程修改,需要同步到硬盘上。

b_lock为1时说明缓冲块与数据块在同步数据,此时内核会拦截进程对该缓冲块的操作,直到交互结束才置0。b_wait用于记录因为b_lock=1而挂起等待缓冲块的进程数。

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

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

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

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

D经过一段时间的运行,所有的buffer_head都挂到hash_table上了,这时,又有进程申请空闲缓冲块,将会发生什么?

A

getblk(int dev, int block) get_hash_table(dev,block) -> find_buffer(dev,block) -> hash(dev, block)

哈希策略为:

#define _hashfn(dev,block)(((unsigned)(dev block))%NR_HASH)

#define hash(dev,block) hash_table[_hashfn(dev, block)]

此时,dev为0x300,block为0,NR_HASH为307,哈希结果为154,将此块插入哈希表中次位置后

B

//代码路径:fs/buffer.c:

static inline void insert_into_queues(struct buffer_head * bh)

{

/*put at end of free list */

bh->b_next_free= free_list;

bh->b_prev_free= free_list->b_prev_free;

free_list->b_prev_free->b_next_free= bh;

free_list->b_prev_free= bh;

/*put the buffer in new hash-queue if it has a device */

bh->b_prev= NULL;

bh->b_next= NULL;

if (!bh->b_dev)

return;

bh->b_next= hash(bh->b_dev,bh->b_blocknr);

hash(bh->b_dev,bh->b_blocknr)= bh;

bh->b_next->b_prev= bh

}

C

不会脱钩,会调用brelse()函数,其中if(!(buf->b_count--)),计数器减一。没有对该缓冲块执行remove操作。由于硬盘读写开销一般比内存大几个数量级,因此该空闲缓冲块若是能够再次被访问到,对提升性能是有益的。

D

进程顺着freelist找到没被占用的,未被上锁的干净的缓冲块后,将其引用计数置为1,然后从哈西队列和空闲块链表中移除该bh,然后根据此新的设备号和块号重新插入空闲表和哈西队列新位置处,最终返回缓冲头指针。

Bh->b_count=1;

Bh->b_dirt=0;

Bh->b_uptodate=0;

Remove_from_queues(bh);

Bh->b_dev=dev;

Bh->b_blocknr=block;

Insert_into_queues(bh);

+2. Rd_load()执行完之后,虚拟盘已经成为可用的块设备,并成为根设备。在向虚拟盘中copy 任何数据之前,虚拟盘中是否有引导快、超级快、i节点位图、逻辑块位图、i节点、逻辑块?

虚拟盘中没有引导快、超级快、i节点位图、逻辑块位图、i节点、逻辑块。在rd_load()函数中的memcpy(cp, bh->b_data,BLOCK_SIZE)执行以前,对虚拟盘的操作仅限于为虚拟盘分配2M的内存空间,并将虚拟盘的所有内存区域初始化为0.所以虚拟盘中并没有数据,仅是一段被’\0’填充的内存空间。

(代码路径:kernel/blk_dev/ramdisk.c rd_load:)

Rd_start = (char *)mem_start;

Rd_length = length;

Cp = rd_start;

For (i=0; i

*cp++=’\0\;

+3. 在虚拟盘被设置为根设备之前,操作系统的根设备是软盘,请说明设置软盘为根设备的技术路线。

首先,将软盘的第一个山区设置为可引导扇区:

(代码路径:boot/bootsect.s)boot_flag: .word 0xAA55

在主Makefile文件中设置ROOT_DEV=/dev/hd6。并且在bootsect.s中的508和509处设置ROOT_DEV=0x306;在tools/build中根据Makefile中的ROOT_DEV设置MAJOR_TOOT 和MINOR_ROOT,并将其填充在偏移量为508和509处:

(代码路径:Makefile) tools/build boot/bootsect boot/setup tools/system

$(ROOT_DEV) > Image

随后被移至0x90000+508(即0x901FC)处,最终在main.c中设置为ORIG_ROOT_DEV并将其赋给ROOT_DEV变量:

(代码路径:init/main.c)

62 #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)

113 ROOT_DEV = ORIG_ROOT_DEV;

+4. Linux0.11是怎么将根设备从软盘更换为虚拟盘,并加载了根文件系统?

rd_load函数从软盘读取文件系统并将其复制到虚拟盘中并通过设置ROOT_DEV为0x0101将根设备从软盘更换为虚拟盘,然后调用mount_root函数加载跟文件系统,过程如下:初始化file_table和super_block,初始化super_block并读取根i节点,然后统计空闲逻辑块数及空闲i节点数:

(代码路径:kernel/blk_drv/ramdisk.c:rd_load) ROOT_DEV=0x0101;

主设备好是1,代表内存,即将内存虚拟盘设置为根目录。

+5在Linux操作系统中大量的使用了中断、异常类的处理,为什么,有什么好处?

CPU是主机中关键的组成部分,进程在主机中的运算肯定离不开CPU,而CPU在参与运算过程中免不了进行“异常处理”,这些异常处理都需要具体的服务程序来执行。这种32位中断服务体系是为适应一种被动响应中断信号而建立的。这样CPU就可以把全部精力都放在为用户程序服务上,对于随时可能产生而又不可能时时都产生的中断信号,不用刻意去考虑,这就提高了操作系统的综合效率。以“被动模式”代替“主动轮询”模式来处理终端问题是现在操作系统之所以称之为“现代”的一个重要标志。

操作系统课程设计

课程设计报告 2015~2016学年第一学期 操作系统综合实践课程设计 实习类别课程设计 学生姓名李旋 专业软件工程 学号130521105 指导教师崔广才、祝勇 学院计算机科学技术学院 二〇一六年一月

- 1 -

- 2 -

一、概述 一个目录文件是由目录项组成的。每个目录项包含16B,一个辅存磁盘块(512B)包含32个目录项。在目录项中,第1、2字节为相应文件的外存i节点号,是该文件的内部标识;后14B为文件名,是该文件的外部标识。所以,文件目录项记录了文件内、外部标识的对照关系。根据文件名可以找到辅存i节点号,由此便得到该文件的所有者、存取权、文件数据的地址健在等信息。UNIX 的存储介质以512B为单位划分为块,从0开始直到最大容量并顺序加以编号就成了一个文件卷,也叫文件系统。UNIX中的文件系统磁盘存储区分配图如下: 本次课程设计是要实现一个简单的模拟Linux文件系统。我们在内存中开辟一个虚拟磁盘空间(20MB)作为文件存储器,并将该虚拟文件系统保存到磁盘上(以一个文件的形式),以便下次可以再将它恢复到内存的虚拟磁盘空间中。文件存储空间的管理可采用位示图方法。 二、设计的基本概念和原理 2.1 设计任务 多用户、多级目录结构文件系统的设计与实现。可以实现下列几条命令login 用户登录 logout 退出当前用户 dir 列文件目录 creat 创建文件 delete 删除文件 open 打开文件 close 关闭文件 - 3 -

read 读文件 write 写文件 mkdir 创建目录 ch 改变文件目录 rd 删除目录树 format 格式化文件系统 Exit 退出文件系统 2.2设计要求 1) 多用户:usr1,usr2,usr3,……,usr8 (1-8个用户) 2) 多级目录:可有多级子目录; 3) 具有login (用户登录)4) 系统初始化(建文件卷、提供登录模块) 5) 文件的创建:create (用命令行来实现)6) 文件的打开:open 7) 文件的读:read8) 文件的写:write 9) 文件关闭:close10) 删除文件:delete 11) 创建目录(建立子目录):mkdir12) 改变当前目录:cd 13) 列出文件目录:dir14) 退出:logout 新增加的功能: 15) 删除目录树:rd 16) 格式化文件系统:format 2.3算法的总体思想 - 4 -

操作系统课程设计报告书

题目1 连续动态内存管理模拟实现 1.1 题目的主要研究内容及预期达到的目标 (1)针对操作系统中内存管理相关理论进行设计,编写程序并进行测试,该程序管理一块虚拟内存。重点分析三种连续动态内存分配算法,即首次适应算法、循环首次适应算法和最佳适应算法。 (2)实现内存分配和回收功能。 1.2 题目研究的工作基础或实验条件 (1)硬件环境:PC机 (2)软件环境:Windows XP,Visual C++ 6.0 1.3 设计思想 首次适应算法的实现:从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法的目的在于减少查找时间。为适应这种算法,空闲分区表中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高址空间保留大的空闲区。 循环首次适应算法的实现:在分配内存空间时,不再每次从表头开始查找,而是从上次找到空闲区的下一个空闲开始查找,直到找到第一个能满足要求的的空闲区为止,并从中划出一块与请求大小相等的内存空间分配给作业。该算法能使内存中的空闲区分布得较均匀。 最佳适应算法的实现:从全部空闲区中找到能满足作业要求的、且最小的空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表中的空闲分区要按从小到大进行排序,从表头开始查找第一个满足要求的自由分配。 1.4 流程图 内存分配流程图,如图1-1所示。

图1-1 内存分配流程图内存回收流程图,如1-2所示。

图1-2 内存回收流程图 1.5 主要程序代码 (1)分配内存 void allocate(char z,float l) { int i,k; float ad; k=-1; for(i=0;i= l && free_table[i].flag == 1) if(k==-1 || free_table[i].length

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

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语句,也没有看到循环语句,是什么原因导致反复执行?请说明理由,并给出代码证据。 答:大师兄!!

操作系统课程设计报告

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级: 13软件工程1班 提交时间: 2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。

二、环境条件 系统: WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景 计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。

(4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。 2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下:钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<

操作系统课程设计报告

上海电力学院 计算机操作系统原理 课程设计报告 题目名称:编写程序模拟虚拟存储器管理 姓名:杜志豪.学号: 班级: 2012053班 . 同组姓名:孙嘉轶 课程设计时间:—— 评语: 成绩: 目录 一、设计内容及要求 (4) 1. 1 设计题目 (4) 1.2 使用算法分析: (4)

1. FIFO算法(先进先出淘汰算法) (4) 1. LRU算法(最久未使用淘汰算法) (5) 1. OPT算法(最佳淘汰算法) (5) 分工情况 (5) 二、详细设计 (6) 原理概述 (6) 主要数据结构(主要代码) (6) 算法流程图 (9) 主流程图 (9) Optimal算法流程图 (10) FIFO算法流程图 (10) LRU算法流程图 (11) .1源程序文件名 (11) . 2执行文件名 (11) 三、实验结果与分析 (11) Optimal页面置换算法结果与分析 (11) FIFO页面置换算法结果与分析 (16) LRU页面置换算法结果与分析 (20) 四、设计创新点 (24) 五、设计与总结 (27)

六、代码附录 (27) 课程设计题目 一、设计内容及要求 编写程序模拟虚拟存储器管理。假设以M页的进程分配了N

块内存(N

操作系统课程试验

第3章处理机管理 7.1实验内容 处理机管理是操作系统中非常重要的部分。为深入理解进程管理部分的功能,设计几个调度算法,模拟实现处理机的调度。 7.2实验目的 在多道程序或多任务系统中,系统同时处于就绪状态的进程有若干个。也就是说能运行的进程数远远大于处理机个数。为了使系统中的各进程能有条不紊地运行,必须选择某种调度策略,以选择一进程占用处理机。要求学生设计一个模拟单处理机调度的算法,以巩固和加深处理机调度的概念。 7.3实验题目 7.3.1设计一个按先来先服务调度的算法 提示 (1)假设系统中有5个进程,每个进程由一个进程控制块(PCB)来标识。进程控制块内容如图7-1所示。 进程名即进程标识。 链接指针:按照进程到达系统的时间将处于就绪状态的进程连接成一个就绪队列。指针指出下一个到达进程的进程控制块首地址。最后一个进程的链指针为NULL。 估计运行时间:可由设计者指定一个时间值。 达到时间:进程创建时的系统时间或由用户指定。调度时,总是选择到达时间最早的进程。 进程状态:为简单起见,这里假定进程有两种状态:就绪和完成。并假定进程一创建就处于就绪状态,用R表示。当一个进程运行结束时,就将其置成完成状态,用C表示。 (2)设置一个队首指针head,用来指出最先进入系统的进程。各就绪进程通过链接指针连在一起。 (3)处理机调度时总是选择队首指针指向的进程投入运行。由于本实验是模拟实验,所以对被选中进程并不实际启动运行,而只是执行: 估计运行时间减1 用这个操作来模拟进程的一次运行,而且省去进程的现场保护和现场恢复工作。 (4)在所设计的程序中应有显示或打印语句,能显示或打印正运行进程的进程名,已运行是、还剩时间,就绪队列中的进程等。所有进程运行完成是,给出各进程的周转时间和平均周转时间。 先来先服务(FCFS)调度算法 /*源程序1.cpp,采用先来先无法法在Visual C++ 6.0下调试运行*/ /*数据结构定义及符号说明*/ #include #include

操作系统实验报告 附思考题

课程设计(综合实验)报告( 2015 -- 2016 年度第 1 学期) 名称:操作系统综合实验 题目:oslab综合实验 院系:计算机系 班级: 学号: 学生姓名: 指导教师: 设计周数:分散进行 成绩: 日期:2015 年10 月29 日

实验1 实验环境的使用 一、综合实验的目的与要求 熟悉操作系统集成实验环境OS Lab 的基本使用方法。 练习编译、调试EOS 操作系统内核以及EOS 应用程序。 二、实验正文 1.启动 OS Lab 2.1 执行项目 Windows 控制台窗口内容显示 2.2 调试项目 2.2.1 使用断点中断执行 2.2.2 单步调试 2.2.2 .3单步调试结果显示: 练习使用“逐语句”功能和“跳出”功能 2.2.3 查看变量的值 快速监视 添加监视 2.2.4 调用堆栈 调用堆栈显示内容 进入Func 函数 双击 main 函数所在的行表示此函数是当前调用堆栈中的活动函数。 3 新建EOS 内核项目 4 EOS 应用程序项目的生成和调试 4.1 新建EOS 应用程序项目 4.2 调试项目 添加断点后单步调试结果显示 4.3 查看软盘镜像文件中的内容 4.4修改EOS 应用程序项目名称 5 退出OS Lab 6 保存EOS 内核项目 三、综合实验总结或结论 思考与练习: 1.在哪些情况下应该使用“逐过程”调试,在哪些情况下应该使用“逐语句”调试。

答:逐语句为每执行一行语句,如果碰到函数调用它就会进入到函数里面。而逐过程碰到函数时不进入函数,把函数调用当成一条语句去执行。 2. 生成EOS SDK 文件夹的目的和作用。明白文件夹的组织结构和各个文件的来源和作用。查看EOS 应用程序包含了SDK 文件夹中的哪些头文件,是如何包含的? (1)EOS SDK为应用程序调用系统API提供服务,可作为用户编程中使用的工具包集合。(2)其主要包括INC头文件LIB文件夹、导入库文件和BIN文件夹、动态链接库、可执行程序、二进制文件。 (3)包含的头文件有:eos.h负责导出API函数,eosdef.h声明负责导出函数类型的定 义,error.h负责导出错误码。 (4)EOS应用程序在项目的头文件中只是包含了eos.h文件,在eos.h文件中又包含了eosdef.h和error.h文件。 实验 2 操作系统的启动 一、综合实验的目的与要求 跟踪调试 EOS 在 PC 机上从加电复位到成功启动全过程,了解操作系统的启动过程。 查看 EOS 启动后的状态和行为,理解操作系统启动后的工作方式。 二、实验正文 1. 准备实验 新建一个 EOS Kernel 项目。打开boot.asm 和loader.asm 两个汇编文件。生成项目。找到loader.bin 文件,记录下此文件的大小 1566 字节。 2 调试 EOS 操作系统的启动过程 2.1 使用 Bochs 做为远程目标机 找到“远程目标机”属性,将此属性值修改为“BochsDebug” 2.2 调试 BIOS 程序 2.2.1在 Console 窗口中输入调试命令 sreg 后按回车,其中 CS 寄存器信息行中的 “ s=0xf000”表示 CS 寄存器的值为 0xf000。 2.2.2 输入调试命令 r 后按回车,显示当前 CPU 中各个通用寄存器的值。其中 “ rip:0x00000000:0000fff0”表示 IP 寄存器的值为 0xfff0。 2.2.3输入调试命令 xp /1024b 0x0000,查看开始的 1024 个字节的物理内存。在 Console 中输出的这1K 物理内存的值都为 0,说明 BIOS 中断向量表还没有被加载到此处。 2.2.4输入调试命令 xp /512b 0x7c00,查看软盘引导扇区应该被加载到的内存位置。输出的内存值都为 0,说明软盘引导扇区还没有被加载到此处。

操作系统课程教学大纲

GDOU-B-11-213 《操作系统》课程教学大纲 课程简介 课程简介: 本课程主要讲述操作系统的原理,使学生不仅能够从系统内部了解操作系统的工作原理,而且可以学到软件设计的思想方法和技术方法。主要内容 包括:操作系统的概论;操作系统的作业管理;操作系统的文件管理原理; 操作系统的进程概念、进程调度和控制、进程互斥和同步等;操作系统的各 种存储管理方式以及存储保护和共享;操作系统的设备管理一般原理。其次 在实验环节介绍实例操作系统的若干实现技术,如:Windows操作系统、Linux 操作系统等。 课程大纲 一、课程的性质与任务: 本课程计算机学科的软件工程专业中是一门专业方向课,也可以面向计算机类的其它专业。其任务是讲授操作系统的原理,从系统内部了解操作系统的工作原理以级软件设计的思想方法和技术方法;同时介绍实例操作系统的若干实现技术。 二、课程的目的与基本要求: 通过本课程的教学使学生能够从操作系统内部获知操作系统的工作原理,理解操作系统几大管理模块的分工和管理思想,学习设计系统软件的思想方法,通过实验环节掌握操作系统实例的若干实现技术,如:Windows操作系统、Linux操作系统等。 三、面向专业: 软件工程、计算机类 四、先修课程: 计算系统基础,C/C++语言程序设计,计算机组成结构,数据结构。 五、本课程与其它课程的联系:

本课程以计算系统基础,C/C++语言程序设计,计算机组成结构,数据结构等为先修课程,在学习本课程之前要求学生掌握先修课程的知识,在学习本课程的过程中能将数据结构、计算机组成结构等课程的知识融入到本课程之中。 六、教学内容安排、要求、学时分配及作业: 第一章:操作系统概论(2学时) 第一节:操作系统的地位及作用 操作系统的地位(A);操作系统的作用(A)。 第二节:操作系统的功能 单道系统与多道系统(B);操作系统的功能(A)。 第三节:操作系统的分类 批处理操作系统(B);分时操作系统(B);实时操作系统(B)。 第二章:作业管理(2学时) 第一节:作业的组织 作业与作业步(B);作业的分类(B);作业的状态(B);作业控制块(B)。 第二节:操作系统的用户接口 程序级接口(A);作业控制级接口(A)。 第三节:作业调度 作业调度程序的功能(B);作业调度策略(B);作业调度算法(B)。 第四节:作业控制 脱机控制方式(A);联机控制方式(A)。 第三章:文件管理(8学时) 第一节:文件与文件系统(1学时) 文件(B);文件的种类(B);文件系统及其功能(A)。 第二节:文件的组织结构(1学时) 文件的逻辑结构(A);文件的物理结构(A)。 第三节:文件目录结构(1学时) 文件说明(B);文件目录的结构(A);当前目录和目录文件(B)。 第四节:文件存取与操作(1学时) 文件的存取方法(A);文件存储设备(C);活动文件(B);文件操作(A)。 第五节:文件存储空间的管理(2学时) 空闲块表(A);空闲区表(A);空闲块链(A);位示图(A)。 第六节:文件的共享和保护(2学时)

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告学院:计算机学院 专业班级:13软件工程1班 提交时间:2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。 二、环境条件 系统:WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景

计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。 (4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。 2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下: 钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<

《操作系统》课程教案

《操作系统》课程教案 一、课程定位 操作系统课程是计算机应用技术专业基础课程,属于必修课程。在课程设置上起着承上启下的作用,其特点是概念多、抽象和涉及面广。主要任务是:使学生掌握计算机操作系统的基本原理及组成;计算机操作系统的概念和相关新概念、名词及术语;了解计算机操作系统的发展特点、设计技巧和方法;对常用计算机操作系统会进行基本的操作使用。 按照新专业人才培养方案,该课程开设在第三学期。本课程的先导课程为《计算机组成原理》,《微机原理》,《数据结构》和《高级语言程序设计》;后续课程为《数据库系统原理》、《计算机网络》。 二、课程总目标 通过本课程的学习,使学生理解操作系统基本原理,并在此基础上培养学生实际动手编程能力。 (一)知识目标 1.理解操作系统的概念、操作系统的发展历史、类型、特征以及结构设计。 2.掌握进程和线程。 3.掌握死锁的预防、避免、检测和恢复。 4.掌握作业调度、进程调度、调度准则、调度算法、线程调度等。 5.掌握存储管理中的分区法、分页技术、分段技术、段页式技术等。 6. 掌握文件系统的功能和结构、目录结构和目录查询、文件和目录操作。 7. 掌握输入/输出管理、用户接口服务、嵌入式操作系统、分布式操作系统。

(二)素质目标 1.熟练使用计算机操作系统。 2.能够解决一些简单的应用问题。 3.了解计算机操作系统设计技巧。 (三)职业能力培养目标 1.初步具备辩证思维的能力。 2.具有热爱科学,实事求是的学风和创新意识,创新精神。 三、课程设计 (一)设计理念 以职业能力培养为导向,进行课程开发与设计。按照人才培养目标要求来确定课程的内容、教学组织、教学方法和手段,注重培养学生分析问题、解决问题的能力、计算机思维能力、自学能力和从业能力。 (二)设计思路 1.以“够用、适用、实用”为目标设计课程教学内容。 2.考虑后序课程需要,突出重点,强化专业应用。 3.注重课堂教学互动,教师为主导,学生为主体,引导学生积极思维,培养学生的学习能力。 4.注重培养学生分析问题、解决问题的能力和自学能力。

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级:13软件工程1班 提交时间:2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。 二、环境条件

系统:WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景 计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。 (4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。

2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下:钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<

操作系统-课程设计

课程设计说明书(操作系统) 题目:进程调度 院系:计算机科学与工程学院 专业班级:信息安全13-2 学号:20133029xx 学生姓名:xx 指导教师:xx 2015年12月15日

安徽理工大学课程设计(论文)任务书计算机科学与工程学院

安徽理工大学课程设计(论文)成绩评定表

摘要 现代计算机系统中,进程是资源分配和独立运行的基本单位,是操作系统的核心概念。因而,进程就成为理解操作系统如何实现系统管理的最基本,也是最重要的概念。进程调度是进程管理过程的主要组成部分,是必然要发生的事件。 在现代操作系统中,进程的并发机制在绝大多数时候,会产生不断变化的进程就绪队列和阻塞队列。处于执行态的进程无论是正常或非正常终止、或转换为阻塞状态,都会引发从就绪队列中,由进程调度选择一个进程进占CPU。 进程调度的核心是进程调度的算法.在本课程设计中,用良好清晰的界面向用户展示了进程调度中的时间片轮转调度算法。在最终实现的成果中,用户可指定需要模拟的进程数,CPU时间片和进程的最大执行时间,并且选择需要演示的算法,界面将会动态的显示进程调度过程及各个队列的变化。通过此进程调度模拟系统,用户可以对时间片轮转调度算法有进一步以及直观的了解。 关键词:进程,调度,PCB,时间片轮转

目录 1.设计目的 (6) 2.设计思路 (6) 3.设计过程 (8) 3.1流程图 (8) 3.2算法 (8) 3.3数据结构 (10) 3.4源代码 (10) 4.实验结果及分析 (20) 4.1 使用说明 (20) 4.2程序演示 (20) 5.实验总结 (24) 6.参考文献 (24)

操作系统(一个小型操作系统的设计与实现)课程设计

南通大学计算机科学与技术学院操作系统课程设计报告 专业: 学生姓名: 学号: 时间:

操作系统模拟算法课程设计报告 设计要求 将本学期三次的实验集成实现: A.处理机管理; B.存储器管理; C.虚拟存储器的缺页调度。 设计流程图 主流程图 开始的图形界面 处理机管理存储器管理缺页调度 先来先服务时 间 片 轮 转 首 次 适 应 法 最 佳 适 应 法 先 进 先 出 L R U 算 法

A.处理机调度 1)先来先服务FCFS N Y 先来先服务算法流程 开始 初始化进程控制块,让进程控制块按进程到达先后顺序让进程排队 调度数组中首个进程,并让数组中的下一位移到首位 计算并打印进程的完成时刻、周转时间、带权周转时间 其中:周转时间 = 完成时间 - 到达时间 带权周转时间=周转时间/服务时间 更改计时器的当前时间,即下一刻进程的开始时间 当前时间=前一进程的完成时间+其服务时间 数组为空 结束

2)时间片轮转法 开始 输入进程总数 指针所指的进程是 否结束 输入各进程信息 输出为就绪状态的进程的信息 更改正在运行的进程的已运行时间 跳过已结束的程序 结束 N 指向下一个进程 Y 如果存在下一个进程的话 Y N 输出此时为就绪状态的进程的信息 时间片轮转算法流程图

B.存储器管理(可变式分区管理) 1)首次适应法 分配流程图 申请xkb内存 由链头找到第一个空闲区 分区大小≥xkb? 大于 分区大小=分区大小-xkb,修改下一个空闲区的后向指针内容为(后向指针)+xkb;修改上一个空闲区的前向指针为(前向指针)+xkb 将该空闲区从链中摘除:修改下一个空闲区的后向地址=该空闲区后向地址,修改上一个空闲区的前向指针为该空闲区的前向指针 等于 小于延链查找下 一个空闲区 到链尾 了? 作业等待 返回是 否 登记已分配表 返回分配给进程的内存首地址 开始

操作系统课程设计

操作系统课程设计 Prepared on 22 November 2020

湖南科技大学计算机科学与工程学院 操作系统课程设计报告 学号: ******** 姓名:* * 班级: *** 指导老师: *** 完成时间: ****.**.** 目录 实验一 Windows进程管理 实验二 Linux进程管理 实验三互斥与同步 实验四银行家算法的模拟与实现 实验五内存管理 实验六磁盘调度 实验七进程间通信 实验一 Windows进程管理 一、实验目的 1)学会使用 VC 编写基本的 Win32 Consol Application(控制台应用程序)。 2)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解 Windows 进程的“一生”。

3)通过阅读和分析实验程序,学习创建进程、观察进程、终止进程以及父子进程同步的基本程序设计方法。 二、实验内容和步骤 (1)编写基本的 Win32 Consol Application 步骤1:登录进入 Windows 系统,启动 VC++ 。 步骤2:在“FILE”菜单中单击“NEW”子菜单,在“projects”选项卡中选择 “Win32 ConsolApplication”,然后在“Project name”处输入工程名,在“Location” 处输入工程目录。创建一个新的控制台应用程序工程。 步骤3:在“FILE”菜单中单击“NEW”子菜单,在“Files”选项卡中选择“C++ Source File”,然后在“File” 处输入 C/C++源程序的文件名。 步骤4:将清单 1-1 所示的程序清单复制到新创建的 C/C++源程序中。编译成可执行文件。 步骤5:在“开始”菜单中单击“程序”-“附件”-“命令提示符”命令,进入Windows“命令提示符”窗口,然后进入工程目录中的 debug 子目录,执行编译好的可 (2)创建进程 本实验显示了创建子进程的基本框架。该程序只是再一次地启动自身,显示它的系统进程 ID和它在进程列表中的位置。 步骤1:创建一个“Win32 Consol Application”工程,然后拷贝清单 1-2 中的程序编译成可执行文件。 步骤2:在“命令提示符”窗口运行步骤 1 中生成的可执行文件,列出运行结果。按下ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。 步骤3:在“命令提示符”窗口加入参数重新运行生成的可执行文件,列出运行结果。按下ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。 (3)父子进程的简单通信及终止进程

操作系统课程设计报告

操作系统课程设计实验报告 实验名称:进程控制 姓名/学号: 一、实验目的 学习、理解和掌握Linux与windows的进行控制系统调用的功能,熟悉主要的几个系统调用命令的格式和如何利用系统调用命令进行编程。通过学习,理解如何创建一个进程、改变进程执行的程序、进程和线程终止以及父子进程的同步等,从而提高对进程和线程控制系统调用的编程能力。 二、实验内容 设计并实现Unix的“time”命令。“mytime”命令通过命令行参数接受要运行的程序,创建一个独立的进程来运行该程序,并记录程序运行的时间。 三、实验环境 CPU: Inter ×2 2.10GHz RAM: 3.00GB Windows 7 旗舰版 Linux Ubuntu 10.04 编译: VS2010 四、程序设计与实现 4.1进程控制系统的调用 4.1.1 windows进程控制调用程序中使用的数据结构及主要符号说明 SYSTEMTIME starttime,endtime; //进程开始时间和结束时间 PROCESS_INFORMATION pi //该结构返回有关新进程及 //其主线程的信息 STARTUPINFO si //该结构用于指定新进程的主窗口特性4.1.2 linux进程控制调用程序中使用的数据结构及主要符号说明 struct timeval starttime,endtime //进程开始时间和结束时间 pid_t pid //进程标志符

4.2 程序流程图 图1 windows进程控制调用图2 linux进程控制调用程序运行流程图程序运行流程图 五、实验结果和分析 5.1 windows实验结果和分析

操作系统课程设计报告

课程设计报告 设计题目:多用户、多级目录结构文件系统的设计与 实现 班级: 组长学号: 组长姓名: 指导教师: 设计时间:2015年7月

设计分工 组长学号及姓名: 分工:构建系统框架,实现磁盘i节点调入内存,以及内存i节点的申请分配与回收,新建文件和目录,文件的读写 组员1学号及姓名: 分工:实现成组链接法分配与回收,实现用户登陆和注销,实现格式化初始化函数,参与系统界面的设计 组员2学号及姓名: 分工: 组员3学号及姓名: 分工: 组员4学号及姓名: 分工:

摘要 文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。文件系统由三部分组成:文件系统的接口,对对象操纵和管理的软件集合,对象及属性。从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。 关键词:操作系统,文件系统

摘要 (3) 1概述 (5) 2课程设计任务与要求 (7) 2.1设计任务 (7) 2.2设计要求 (7) 3算法及数据结构 (8) 3.1算法的总体流程 (8) 3.2超级块 (10) 3.2.1功能 (10) 3.2.2数据结构 (10) 3.2.3算法 (11) 3.3磁盘i节点与内存i节点 (12) 3.3.1功能 (12) 3.3.2数据结构 (13) 3.3.3算法 (14) 3.4文件夹操作 (15) 3.4.1功能 (15) 3.4.2数据结构 (15) 3.4.3算法 (16) 3.5文件的操作 (17) 3.5.1功能 (17) 3.5.2数据结构 (17) 3.5.3算法 (18) 4程序设计与实现 (19) 4.1程序流程图 (19) 4.2程序说明 (20) 4.3实验结果 (26) 5结论 (27) 6参考文献 (28) 7收获、体会和建议 (29)

《操作系统》课程简介.doc

《操作系统》课程简介 一、课程简介 操作系统(Operating System)是当代计算机软件系统的核心,是计算机系统的基础和支撑,它管理和控制着计算机系统中的所有软、硬件资源,可以说操作系统是计算机系统的灵魂。操作系统课程是计算机专业学生必须学习和掌握的基础课程,是进行系统软件开发的理论基础,也是计算机专业的一门理论性和实践性并重的核心主干课程。 二、课程性质 本课程是一门技术性、实践性很强的课程,又是理论与实践紧密结合的课程,既注重操作系统基础理论,又着眼培养学生解决实际问题能力。本课程将学习操作系统的基本原理、基本方法及其实现技术,包括处理器管理、存储管理、文件管理、设备管理以及进程的互斥、同步、通信与死锁等内容。使学生了解当今几个主流操作系统,了解操作系统的设计方法和并发程序的设计,具备较强的软件设计能力和较严密的思维能力。 三、教学目的 1、使学生全面地了解和掌握现代计算机操作系统的基本原理,从资源管理的角度领会操作系统的功能和实现技术。 2、使学生建立起以操作系统为中心的对计算机系统整体性和系统级的认识。 3、使学生系统科学地受到分析问题和解决问题的训练,提高运用理论知识开发实际操作系统的基本能力。

《操作系统》教学大纲第1章:引论 (一)知识要点 1、计算机硬件结构 2、操作系统介绍 3、操作系统的发展历程 4、操作系统的类型 5、操作系统的特征 6、操作系统结构设计 (二)能力重点 1、操作系统的定义、分类 2、操作系统的主要功能 3、操作系统的基本特征 第2章:进程和线程 (一)知识要点 1、进程的概念 2、进程的状态和组成 3、进程管理 4、线程的概念 5、进程的同步和通信 6、经典进程同步问题 7、进程通信 (二)能力重点 1、进程的定义、进程的状态 2、进程的创建、撤销、阻塞、唤醒等原语 3、线程和进程的区别,线程的特征 4、经典进程同步问题的解决方法

文件加密系统课程设计

仲恺农业工程学院课程设计 文件加密 姓名孙浩斌 院(系)信息科学与技术学院 专业年级计算机132 学号 指导教师罗慧慧 职称学生 起止时间2015-6-15至2015-6-24 仲恺农业工程学院教务处制 目录

一.课程设计目的和要求 设计目的 有时我们有些资料不希望别人看到,最常用的方法就是加密。对给定的相关文件进行加密可以对文件进行保护,可以防止某些重要信息不被别人所知道甚至窃取。对文件起到保护作用,可以方便用户使用某些只有自己能知道的信息,能够安全保护文件的相关内容几信息不被外流。随着信息社会的到来,人们在享受信息资源所带来的巨大的利益的同时,也面临着信息安全的严峻考验。信息安全已经成为世界性的现实问题,信息安全问题已威胁到国家的政治、经济、军事、文化、意识形态等领域,同时,信息安全问题也是人们能否保护自己的个人隐私的关键。信息安全是社会稳定安全的必要前提条件。通过课程设计,使学生了解高级程序设计语言的结构,逐渐培养学生的编程能力、用计算机解决实际问题的能力,掌握基本的程序设计过程和技巧,掌握基本的分析问题和利用计算机求解问题的能力,具备初步的高级语言程序设计能力。为后续各门计算机课程的学习和毕业设计打下坚实基础。 程序设计的主要任务是要求学生遵循软件开发过程的基本规范,运用结构化程序设计的方法,按照课程设计的题目要求,分析、设计、编写、调试和测试程序及编写设计报告。

本课程设计的目标: 1. 巩固《高级语言程序设计》课程学习的内容和加深学生对基本知识的理解和掌握。 2. 掌握编程和程序调试的基本技能。 3. 掌握软件设计的方法。 4. 提高运用程序设计解决实际问题的能力。 5. 培养独立思考、综合运用所学有关相应知识的能力。 6. 强化上机动手编程能力,闯过理论与实践相结合的难关! 设计要求 1. 分析课程设计题目的要求,根据所要求的程序功能,画出程序的流程图。 2.对系统功能模块进行分析,写出详细设计说明文档。 3.对程序源代码进行调试与测试,使其能正确运行。 4.设计完成的软件要便于操作和使用。 5.设计完成后提交课程设计报告。 设计意义 至今,密码技术是取得信息安全性最有效的一种方法, 密码技术是信息安全的核心技术。通过数据加密,人们可以有效地保证通信线路上的内容不被泄露,而且还可以检验传送信息的完整性。进一步,密码技术可以应用于数字签名、身份认证和信息鉴定,这些应用对于资源存取控制以及其它安全措施是必须而且有效的。相对于防病毒软件和防火墙软件来说,基于密码技术密码类产品、认证类产品份额相对较小,但随着金融、电信、政府等行业信息化建设对于网络安全整体解决方案需求的增加,将会有较大的增长。

相关主题
文本预览
相关文档 最新文档