版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、课程设计(综合实验)报告( 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
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 Lab6 保存EOS 内核项目 三、综合实验总结或结论思考与练习: 在哪些情况下应该使用“逐过程”调试,在哪些情况下应该使用“逐语句”调试。答:逐
3、语句为每执行一行语句,如果碰到函数调用它就会进入到函数里面。而逐过程碰到函数时不进入函数,把函数调用当成一条语句去执行。2. 生成EOS SDK 文件夹的目的和作用。明白文件夹的组织结构和各个文件的来源和作用。查看EOS 应用程序包含了SDK 文件夹中的哪些头文件,是如何包含的?(1)EOSSDK为应用程序调用系统API提供服务,可作为用户编程中使用的工具包集合。(2)其主要包括INC头文件LIB文件夹、导入库文件和BIN文件夹、动态链接库、可执行程序、二进制文件。(3)包含的头文件有:eos.h负责导出API函数,eosdef.h声明负责导出函数类型的定义,error.h负责导出错误码。 (
4、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 做为远程目标机
5、找到“远程目标机”属性,将此属性值修改为“BochsDebug”2.2 调试 BIOS 程序2.2.1在 Console 窗口中输入调试命令 sreg 后按回车,其中 CS 寄存器信息行中的“ s=0 xf000”表示 CS 寄存器的值为 0 xf000。2.2.2 输入调试命令 r 后按回车,显示当前 CPU 中各个通用寄存器的值。其中“ rip:0 x00000000:0000fff0”表示 IP 寄存器的值为 0 xfff0。2.2.3输入调试命令 xp /1024b 0 x0000,查看开始的 1024 个字节的物理内存。在 Console 中输出的这1K 物理内存的值都为 0,说明
6、BIOS 中断向量表还没有被加载到此处。2.2.4输入调试命令 xp /512b 0 x7c00,查看软盘引导扇区应该被加载到的内存位置。输出的内存值都为 0,说明软盘引导扇区还没有被加载到此处。可以验证 BIOS 第一条指令所在逻辑地址中的段地址和 CS 寄存器值是一致的,偏移地址和 IP 寄存器值是一致的。由于内存还没有被使用,所以其中的值都为 0。2.3 调试软盘引导扇区程序2.3.1. 输入调试命令 vb 0 x0000:0 x7c00,添加断点2.3.2. 输入调试命令 c 继续执行2.3.3. 输入调试命令 sreg 验证 CS 寄存器( 0 x0000)的值。2.3.4. 输入调
7、试命令 r 验证 IP 寄存器( 0 x7c00)的值。2.3.5输入调试命令 xp /1024b 0 x0000 验证此时 BIOS 中断向量表已经被载入。2.3.6.输入调试命令 xp /512b 0 x7c00 显示软盘引导扇区程序的所有字节码。2.3.7输入调试命令 xp /512b 0 x0600 验证图 3-2 中第一个用户可用区域是空白的。2.3.8输入调试命令 xp /512b 0 x7e00 验证图 3-2 中第二个用户可用区域是空白的。2.3.9 自己设计两个查看内存的调试命令,验证这两个用户可用区域的高地址端是空白的。(1) xp /512b 0 x7f00 (2) xp
8、 /512b0 x0700 2.3.10输入调试命令 xp /512b 0 xa0000 验证图 3-2 中上位内存已经被系统占用。2.3.11自己设计一个查看内存的调试命令,验证上位内存的高地址端已经被系统占用。xp /512b 0 xb0000 2.3.12 输入调试命令 xp /8b 0 x1000 查看内存 0 x1000 处的数据,验证此块内存的前三个字节和 loader.lst文件中的第一条指令的字节码是相同的。2.3.13根据之前记录的 loader.bin 文件的大小,自己设计一个查看内存的调试命令loader.bin文件的大小为1566个字节,转换为十六进制的61E,所以程序
9、最后八个字节在物理内存的0 x1616到0 x161D的位置,所以调试命令为xp/8b 0 x1616。经检验, loader.bin程序结束位置字节码与反汇编命令相同。注:查看loader.bin文件的大小应在“属性”对话框中看。2.4 调试加载程序使用查看虚拟内存的调试命令 x /1wx 0 x80001117 查看内存中保存的 32 位函数入口地址,在Console 窗口中会输出:0 x0000000080001117 : 0 x800*2.5 调试内核在“监视”窗口中可以看到KiSystemStartup 函数地址为void (PVOID) 0 x800* KiSystemStartu
10、p2.6 EOS 启动后的状态和行为三、综合实验总结或结论为什么 EOS 操作系统从软盘启动时要使用 boot.bin 和 loader.bin 两个程序?使用一个可以吗? 它们各自的主要功能是什么? 如果将 loader.bin 的功能移动到 boot.bin 文件中,则 boot.bin 文件的大小是否仍然能保持小于 512 字节?答:在IDE环境启动执行EOS操作系统时,会将boot.bin,loader.bin,kernal.dll三个二进制写入软件镜像文件中,然后让虚拟机来执行软盘中的EOS操作系统,使用其中一个是不能运行的。 2.为什么软盘引导扇区程序选择将 loader.bin加
11、载到第一个可用区域的 0 x1000 处呢?这样做有什么好处?这样做会对 loader.bin 文件的大小有哪些限制。答:用户只用两个可用区域,加载位置非此即彼。第一个可用用户区是低地址区,且空间大小比较小,适合容纳小文件,所以我们选择将占用空loder.bin加载到第一用户区。优点:低地址开始,便于搜索查找小文件占用小空间,节约资源。限制:loder.bin文件必须小于 1c00k。实验 3 进程的创建一、 综合实验的目的与要求练习使用 EOS API 函数 CreateProcess 创建一个进程,掌握创建进程的方法,理解进程和程序的区别。调试跟踪 CreateProcess 函数的执行过
12、程,了解进程的创建过程,理解进程是资源分配的单位。二、实验正文1 准备实验2 练习使用控制台命令创建 EOS 应用程序的进程 Hello.exe 应用程序输出结果3 练习通过编程的方式让应用程序创建另一个应用程序的进程可知子进程结束后,父进程继续执行4 调试 CreateProcess 函数在“反汇编”窗口的左侧显示的虚拟地址中看到所有指令的虚拟地址都大于 0 x80000000,说明内核( kernel.dll) 处于高 2G 的虚拟地址空间中。查看 main 函数的指令所在的虚拟地址都是小于 0 x80000000,说明应用程序( eosapp.exe)处于低 2G 的虚拟地址空间中。5
13、调试 PsCreateProcess 函数进程执行的结果:绘制一幅进程创建过程的流程图。6 练习通过编程的方式创建应用程序的多个进程多个进程并发执行的结果:有结果显示可知有两个进程在执行三、综合实验总结或结论1. 在源代码文件 NewTwoProc.c 提供的源代码基础上进行修改,要求使用 hello.exe 同时创建 10 个进程。修改结果如下图所示: 部分修改代码如下图所示:(“”部分为相似的4-9进程代码) if (CreateProcess(A:Hello.exe, NULL, 0, &StartupInfo, &ProcInfoOne)& CreateProcess(A:Hello.
14、exe, NULL, 0, &StartupInfo, &ProcInfoTwo)& CreateProcess(A:Hello.exe, NULL, 0, &StartupInfo, &ProcInfo3) & CreateProcess(A:Hello.exe, NULL, 0, &StartupInfo, &ProcInfo10) WaitForSingleObject(ProcInfoOne.ProcessHandle, INFINITE);WaitForSingleObject(ProcInfoTwo.ProcessHandle, INFINITE);WaitForSingleObj
15、ect(ProcInfo3.ProcessHandle, INFINITE);WaitForSingleObject(ProcInfo10.ProcessHandle, INFINITE);GetExitCodeProcess(ProcInfoOne.ProcessHandle, &ulExitCode); GetExitCodeProcess(ProcInfo3.ProcessHandle, &ulExitCode);printf(nThe process 3 exit with %d.n, ulExitCode); GetExitCodeProcess(ProcInfo10.Process
16、Handle, &ulExitCode);printf(nThe process 10 exit with %d.n, ulExitCode);CloseHandle(ProcInfoOne.ProcessHandle); CloseHandle(ProcInfoTwo.ThreadHandle);CloseHandle(ProcInfo3.ProcessHandle);CloseHandle(ProcInfo3.ThreadHandle); CloseHandle(ProcInfo10.ProcessHandle);CloseHandle(ProcInfo10.ThreadHandle);在
17、 PsCreateProcess 函 数 中 调 用 了 PspCreateProcessEnvironment 函 数 后 又 先 后 调 用 了PspLoadProcessImage 和 PspCreateThread 函数, 学习这些函数的主要功能。能够交换这些函数被调用的顺序吗?答:PspCreateProcessEnvironment创建了进程控制块,地址空间和分配了句柄表,PspLoadProcessImage将进程的可执行映象加载的到了进程的地址空间中,PspCreateThread 创建了进程的主线程。这三个函数知道自己从哪里开始执行,执行哪些指令,因此不能交换它们的顺序。 实
18、验 4 线程的状态和转换一、 综合实验的目的与要求调试线程在各种状态间的转换过程,熟悉线程的状态和转换。通过为线程增加挂起状态,加深对线程状态的理解。二、实验正文1 准备实验2 调试线程状态的转换过程2.1 线程由阻塞状态进入就绪状态“ *Thread”State 域的值为 3( Waiting), 双向链表项 StateListEntry的 Next 和 Prev 指针的值都不为 0, 说明这个线程还处于阻塞状态,并在某个同步对象的等待队列中; StartAddr 域的值为IopConsoleDispatchThread,说明这个线程就是控制台派遣线程。在“调用堆栈”窗口中双击 PspUnw
19、aitThread 函数对应的堆栈项, 按F10调试,此时 State 域的值为 0( Zero), 双向链表项 StateListEntry 的 Next 和 Prev 指针的值都为 0, 说明这个线程已经处于游离状态。按 F5 继续执行, 在 PspReadyThread 函数中的断点处中断。按 F10 单步调试直到此函数的最后。此时 State 域的值为 1( Ready),双向链表项 StateListEntry 的 Next 和 Prev 指针的值都不为 0,说明这个线程已经处于就绪状态,并已经被放入优先级为 24 的就绪队列中。 2.2 线程由运行状态进入就绪状态2.3 线程由就绪
20、状态进入运行状态2.4 线程由运行状态进入阻塞状态3 为线程增加挂起状态三、综合实验总结或结论1. 思考一下,在本实验中,当 loop 线程处于运行状态时, EOS 中还有哪些线程,它们分别处于什么状态。可以使用控制台命令 pt 查看线程的状态。答:有一个优先级为0的空闲线程处于就绪状态,8个优先级为24的控制台线程处于阻塞状态,1个优先级的24的控制台派遣线程处于阻塞状态 。2. 当 loop 线程在控制台 1 中执行,并且在控制台 2 中执行 suspend 命令时,为什么控制台 1 中的 loop线程处于就绪状态而不是运行状态?答:在控制台 2 中执行 suspend 命令时,优先级为2
21、4的控制台2线程抢占处理器,即控制台2线程处于运行状态,因此此时loop处于就绪状态。3. 总结一下在图 5-3 中显示的转换过程,哪些需要使用线程控制块中的上下文,哪些不需要使用, 并说明原因。答:就绪运行,运行就绪,运行阻塞需要使用TCB因为这些过程有线程调进或调出处理机的过程,新建就绪,阻塞就绪不需要使用TCB上下文,因为没有占用处理机资源。 4. 请读者找出这些转换过程的原语操作(关中断和开中断) 是在哪些代码中完成的。答:IntState=KeEnableInterrupts(FALSE);/关中断 KeEnableInterrupts(IntState);/开中断实验 5 进程的同
22、步综合实验的目的与要求使用 EOS 的信号量, 编程解决生产者消费者问题,理解进程同步的意义。调试跟踪 EOS 信号量的工作过程,理解进程同步的原理。修改 EOS 的信号量算法,使之支持等待超时唤醒功能,加深理解进程同步的原理。实验正文1 准备实验2 使用 EOS 的信号量解决生产者消费者问题3 调试 EOS 信号量的工作过程3.1 创建信号量PsInitializeSemaphore 函数中用来初始化信号量结构体成员的值,应该和传入 CreateSemaphore 函数的参数值是一致的。单步调试 PsInitializeSemaphore 函数执行的过程,函数的调用层次:先再3.2 等待、释
23、放信号量3.2.1 等待信号量(不阻塞)完成 PsWaitForSemaphore 函数中所有操作。 Empty的计数减少了 1(由 10 变为了 9)3.2.2 释放信号量(不唤醒)完成 PsReleaseSemaphore 函数中的所有操作。 Full计数增加了 1(由 0 变为了 1)。3.2.3 等待信号量(阻塞)在“调用堆栈”窗口中双击 Producer 函数所在的堆栈帧,绿色箭头指向等待 Empty 信号量的代码行,查看 Producer 函数中变量 i 的值为 14,表示生产者线程正在尝试生产 14 号产品。在“调用堆栈”窗口中双击 PsWaitForSemaphore 函数的堆
24、栈帧,查看 Empty 信号量计数( Semaphore-Count)的值为- 释放信号量(唤醒)Consumer 函数中变量 i 的值为 4,说明已经消费了 4 号产品。查看 PsReleaseSemaphore 函数中 Empty 信号量计数( Semaphore-Count)的值为-1,和生产者线程被阻塞时的值是一致的。单步调试 PsReleaseSemaphore 函数,Empty计数的值已经由-1增加为了04 修改 EOS 的信号量算法(1)修改 PsWaitForSemaphore 函数:if(Semaphore-Count0) Semaphore-Count-; f
25、lag=STATUS_SUCCESS; else flag=PspWait(&Semaphore-WaitListHead,Milliseconds); KeEnableInterrupts(IntState); returnflag;(2)修改PsReleaseSemaphore函数:while(!ListIsEmpty(&Semaphore-WaitListHead)&(ReleaseCount)PspWakeThread(&Semaphore-WaitListHead,STATUS_SUCCESS);PspThreadSchedule();ReleaseCount-;Semaphore-
26、Count=Semaphore-Count+ReleaseCount;Status=STATUS_SUCCESS;KeEnableInterrupts(IntState);returnStatus;测试结果:根据文档中的测试方法可看到结果中有两个消费者三、综合实验总结或结论思考在 ps/semaphore.c 文件内的 PsWaitForSemaphore 和 PsReleaseSemaphore 函数中,为什么要使用原子操作?答:EOS内核中维护了大量内核数据,正是这些数据描述了EOS操作系统的状态如果有一组相互关联的内核数据共同描述了这个操作系统的某个状态,那么在修改这样一组内核数据时就必
27、须保证一致性。这就要求修改这部分数据的代码在执行过程中不能被打断,这种操作叫做“原语操作”。 根据本实验 3.3.2 节中设置断点和调试的方法,自己设计一个类似的调试方案来验证消费者线程在消费 24 号产品时会被阻塞,直到生产者线程生产了 24 号产品后,消费者线程才被唤醒并继续执行的过程。答: 生产到23号产品后,进程阻塞。实验 6 时间片轮转调度综合实验的目的与要求调试 EOS 的线程调度程序,熟悉基于优先级的抢先式调度。为 EOS 添加时间片轮转调度,了解其它常用的调度算法。二、实验正文1 准备实验2 阅读控制台命令“rr”相关的源代码3 调试线程调度程序3.1 调试当前线程不被抢先的情
28、况查看 ThreadFunction 函数中变量 pThreadParameter-Y 的值应该为 0,说明正在调试的是第 0个新建的线程。按2次 F5 的循环输出的内容: 以二进制格式查看就绪位图的值BitScanReverse 函数会从就绪位图中扫描最高优先级,并保存在变量HighestPriority 中。查看变量 HighestPriority 的值为 8。3.2 调试当前线程被抢先的情况激活虚拟机窗口,可以看到第 0 个新建的线程正在执行。在“监视”窗口中查看就绪位图的值为 1000000000000000100000001,说明此时在优先级为 24的 就 绪 队 列 中 存 在 就
29、 绪 线 程 。 在 “ 监 视 ” 窗 口 中 添 加 表 达 式“ ListGetCount(&PspReadyListHeads24) ”,其值为 1,说明优先级为 24 的就绪队列中只有一个就绪线程。扫描就绪位图后获得的最高优先级的值 HighestPriority 也就应该是 24。显示0 x18=24继续调试优先级24 的线程已经进入了“运行”状态。4 为 EOS 添加时间片轮转调度修改部分代码:VOIDPspRoundRobin(VOID) if(NULL!=PspCurrentThread&Running=PspCurrentThread-State)PspCurrentThr
30、ead-RemainderTicks-; if(0=PspCurrentThread-RemainderTicks) PspCurrentThread-RemainderTicks=TICKS_OF_TIME_SLICE; if(BIT_TEST(PspReadyBitmap,PspCurrentThread-Priority)PspReadyThread(PspCurrentThread);测试:能看到 20 个线程轮流执行的效果5 修改线程时间片的大小执行的效果: 参数=20 参数=100 时间片过大,算法便退化成为先进先出算法。三、综合实验总结或结论1. 结合线程调度执行的时机,说明在
31、ThreadFunction 函数中,为什么可以使用“关中断”和“开中断”方法来保护控制台这种临界资源。结合线程调度的对象说明这样做的原因。答:EOS会设置CPU停止响应外部设备产生的硬中断,也就不会在由硬中断触发线程调度。开中断和关中断使处理机在这段时间屏蔽掉了外界所有中断,使他线程无法占用资源。使用开中断和关中断进程同步不会改变线程状态,可以保证那些没有获得处理器的资源都在就绪队列中。2.为什么不需要将被中断线程转入“就绪”状态?如果此时将被中断线程转入了“就绪”状态又会怎么样?可以结合 PspRoundRobin 函数和 PspSelectNextThread 函数的流程进行思考,并使用
32、抢先和不抢先两种情况进行说明。答:(1)因为其他优先队列的线程等待时间不能过长。(2)若将中断线程转入就绪队列,只有当此线程执行完毕之后,其他队列的线程才有机会进入就绪队列,尤其是当其他就绪队列中的线程关于人机交互的时候,会严重影响用户体验。3. EOS 内核时间片大小取 60ms,在线程比较多时,就可以观察出线程轮流执行的情况,但是在 Windows、Linux 等操作系统启动后,正常情况下都有上百个线程在并发执行,为什么觉察不到它们被轮流执行,并且每个程序都运行的很顺利呢?答:因为时间片选取合适,线程轮流运行,体现了其虚拟性。实验 7 物理存储器与进程逻辑地址空间的管理综合实验的目的与要求
33、通过查看物理存储器的使用情况,并练习分配和回收物理内存,从而掌握物理存储器的管理方法。通过查看进程逻辑地址空间的使用情况,并练习分配和回收虚拟内存, 从而掌握进程逻辑地址空间的管理方法。实验正文1 准备实验2 阅读控制台命令“pm”相关的源代码,并查看其执行的结果3 分配物理页和释放物理页按 F10 单步调试 MiAllocateAnyPages 函数的执行过程,结果如图可知其空闲页为7126,零页链表为0,已用表为1050.按 F10 单步调试 MiFreePages 函数的执行过程,结果如图可知其再分配1页后,空闲页为7125,零页链表为0,已用表为1051,即用空闲页分配,没用零页链表分
34、配。4 阅读控制台命令“vm”相关的源代码,并查看其执行的结果输入命令“ A: LoopApp.exe”后按回车。 此时就使用 EOS 应用程序文件 LoopApp.exe 创建了一个应用程序进程,由于此进程执行了一个死循环,所以此进程不会结束执行,除非关闭虚拟机。5 在系统进程中分配虚拟页和释放虚拟页调试释放虚拟页的过程:BaseAddress 由初始化的变成了和 RegionSize由初始化的变成了。在调用 MmAllocateVirtualMemory 函数时将 RegionSize 参数的值设置为PAGE_SIZE*2+1,观察“输出”窗口中转储的信息,输出文本略。综合实验总结或结论在
35、本实验 3.3 中,如果分配了物理页后,没有回收,会对 EOS 操作系统造成什么样的影响? 目前 EOS操作系统内核函数 MiAllocateAnyPages 能处理所有物理页被分配完毕的情况吗?答:(1)会造成自由页链表和零链表不断减少,甚至为空。所有物理页都分配完毕的现象。(2)不能。 2. 尝试从性能的角度分析内核函数 MiAllocateAnyPages 和 MiAllocateZeroedPages。 尝试从安全性的角度分析分配零页的必要性。答: MiAllocateAnyPages 分配物理页。首先从空闲页链表中分配,如果分配空闲链表不足则再从零页链表分配。MiAllocateZe
36、roedPages首先从零页链表中分配,如果零页不足则从空闲链表分配。 观察本实验 3.4 中使用“ vm” 命令输出的系统进程的虚拟地址描述符,可以看到在 2 号描述符和 3 号描述符之间有两个虚拟页的空隙,尝试结合虚拟页的分配和释放说明产生这个空隙的原因。答:产生空隙是由于虚拟页被释放而造成的。在启动时会有一个初始化线程在初始化完毕之后就退出了,线程的堆栈所占用的虚拟页也就被释放了。 4. 在本实验 3.5 中,调用 MmAllocateVirtualMemory 函数分配虚拟页时只使用了 MEM_RESERVE 标志,没有使用 MEM_COMMIT 标志,尝试说明这两个标志的区别。答:使
37、用MEM_RESERVE标志分配虚拟页时,没有为其映射实际的物理页。使用MEM_COMMIT标志分配虚拟页时,会为其映射实际的物理页。实验 8 分页存储器管理综合实验的目的与要求学习 i386 处理器的二级页表硬件机制,理解分页存储器管理原理。查看 EOS 应用程序进程和系统进程二级页表映射信息,理解页目录和页表的管理方式。编程修改页目录和页表的映射关系,理解分页地址变换原理。实验正文1 准备实验2 查看 EOS 应用程序进程的页目录和页表验证结果与指导教程的二级页表映射信息结果相同。(输出文本略)3 查看应用程序进程和系统进程并发时的页目录和页表 (输出文本略)4 查看应用程序进程并发时的页
38、目录和页表 (输出文本略)5 在二级页表中映射新申请的物理页 (输出文本略)综合实验总结或结论观察之前输出的页目录和页表的映射关系,可以看到页目录的第 0 x300 个 PDE 映射的页框号就是页目录本身,说明页目录被复用为了页表。而恰恰就是这种映射关系决定了 4K 的页目录映射在虚拟地址空间的 0 xC0300000-0 xC0300FFF,4M 的页表映射在 0 xC0000000-0 xC03FFFFF。现在,假设修改了页目录,使其第 0 x100 个 PDE 映射的页框号是页目录本身,此时页目录和页表会映射在 4G 虚拟地址空间的什么位置呢?答:页目录占用1个物理页,页框号是0 x40
39、9.页表占用5个物理页,页框号是0 x41D,0 x401,0 x403,0 x404,0 x402.2. 思考页式存储管理机制的优缺点。答:优点:虚存量大,适合多道程序运行,动态页式管理提供了内外存统一管理的虚存实现方式。内存利用率高,不要求作业连续存放,有效地解决了内存碎片问题。缺点:要进行页面中断缺页中断等处理,系统开销较大,有可能产生”抖动”现象。地址变换机构复杂,一般采用硬件实现,添加了机器成本。 实验 10 磁盘调度算法综合实验的目的与要求通过学习 EOS 实现磁盘调度算法的机制,掌握磁盘调度算法执行的条件和时机。观察 EOS 实现的 FCFS、 SSTF 和 SCAN 磁盘调度算
40、法,了解常用的磁盘调度算法。编写 CSCAN 和 N-Step-SCAN 磁盘调度算法,加深对各种扫描算法的理解。实验正文1 准备实验验证先来先服务( FCFS)磁盘调度算法:目前磁头初始停留在磁道 10,其它被阻塞的线程依次访问磁道 8、21、9、78、0、41、 10、67、12、10。调试结果如下:输出Start Cylinder: 10TID: 31 Cylinder: 8 Offset: 2 -TID: 32 Cylinder: 21 Offset: 13 +TID: 33 Cylinder: 9 Offset: 12 -TID: 34 Cylinder: 78 Offset: 69
41、 +TID: 35 Cylinder: 0 Offset: 78 -TID: 36 Cylinder: 41 Offset: 41 +TID: 37 Cylinder: 10 Offset: 31 -TID: 38 Cylinder: 67 Offset: 57 +TID: 39 Cylinder: 12 Offset: 55 -TID: 40 Cylinder: 10 Offset: 2 -3 验证最短寻道时间优先( SSTF)磁盘调度算法输出结果Start Cylinder: 10TID: 37 Cylinder: 10 Offset: 0 =TID: 40 Cylinder: 10 Of
42、fset: 0 =TID: 33 Cylinder: 9 Offset: 1 -TID: 31 Cylinder: 8 Offset: 1 -TID: 39 Cylinder: 12 Offset: 4 +TID: 32 Cylinder: 21 Offset: 9 +TID: 36 Cylinder: 41 Offset: 20 +TID: 38 Cylinder: 67 Offset: 26 +TID: 34 Cylinder: 78 Offset: 11 +TID: 35 Cylinder: 0 Offset: 78 -即以10 9 8 12 21 41 67 78 0 的顺序寻道4 验
43、证 SSTF 算法造成的线程“饥饿”现象修改函数中的源代码,使磁头初始停留在磁道 10,而让其它线程依次访问磁道 78、21、9、8、11、41、10、67、12、10。输出结果:Start Cylinder: 10TID: 37 Cylinder: 10 Offset: 0 =TID: 40 Cylinder: 10 Offset: 0 =TID: 33 Cylinder: 9 Offset: 1 -TID: 34 Cylinder: 8 Offset: 1 -TID: 35 Cylinder: 11 Offset: 3 +TID: 39 Cylinder: 12 Offset: 1 +TI
44、D: 32 Cylinder: 21 Offset: 9 +TID: 36 Cylinder: 41 Offset: 20 +TID: 38 Cylinder: 67 Offset: 26 +TID: 31 Cylinder: 78 Offset: 11 +即以10 9 8 11 12 21 41 67 78的顺序寻道可以发现,虽然访问 78 号磁道的线程的请求第一个被放入请求队列,但却被推迟到最后才被处理,出现了“饥饿”现象。如果不断有新线程的请求到达并被优先满足,则访问 78 号磁道的线程的“饥饿”情况就会更加严重。5 验证扫描( SCAN)磁盘调度算法输出结果:Start Cylinde
45、r: 10TID: 37 Cylinder: 10 Offset: 0 =TID: 40 Cylinder: 10 Offset: 0 =TID: 39 Cylinder: 12 Offset: 2 +TID: 32 Cylinder: 21 Offset: 9 +TID: 36 Cylinder: 41 Offset: 20 +TID: 38 Cylinder: 67 Offset: 26 +TID: 34 Cylinder: 78 Offset: 11 +TID: 33 Cylinder: 9 Offset: 69 -TID: 31 Cylinder: 8 Offset: 1 -TID:
46、35 Cylinder: 0 Offset: 8 -即以10 12 21 41 67 78 9 8 0的顺序寻道6 改写 SCAN 算法改写代码(部分):PREQUEST pNextRequest=NULL,pNextRequest1=NULL,pNextRequest2 = NULL; for (pListEntry = RequestListHead.Next; pListEntry != &RequestListHead;pListEntry = pListEntry-Next) pRequest = CONTAINING_RECORD(pListEntry, REQUEST, List
47、Entry); Offset = pRequest-Cylinder - CurrentCylinder;if (0 = Offset) pNextRequest = pRequest;goto RETURN; if (Offset 0) if (Offset InsideShortestDistance) InsideShortestDistance = Offset; pNextRequest1 = pRequest; if (Offset 0) if (-Offset Next) pRequest = CONTAINING_RECORD(pListEntry, REQUEST, List
48、Entry); Offset = pRequest-Cylinder - CurrentCylinder; if (Offset=0)pNextRequest = pRequest;goto RETURN; else if (Offset 0 & Offset InsideShortestDistance) InsideShortestDistance = Offset;pNextRequestInside = pRequest;else if (Offset OutsideLongestDistance) OutsideLongestDistance = -Offset; pNextRequ
49、estOutside = pRequest; ScanInside=1;if(pNextRequestInside != NULL) pNextRequest = pNextRequestInside; elsepNextRequest = pNextRequestOutside;RETURN: return pNextRequest; 输出结果:Start Cylinder: 10TID: 37 Cylinder: 10 Offset: 0 =TID: 40 Cylinder: 10 Offset: 0 =TID: 39 Cylinder: 12 Offset: 2 +TID: 32 Cyl
50、inder: 21 Offset: 9 +TID: 36 Cylinder: 41 Offset: 20 +TID: 38 Cylinder: 67 Offset: 26 +TID: 34 Cylinder: 78 Offset: 11 +TID: 35 Cylinder: 0 Offset: 78 -TID: 31 Cylinder: 8 Offset: 8 +TID: 33 Cylinder: 9 Offset: 1 +即以10 12 21 41 67 78 0 8 9的顺序寻道8 验证 SSTF、 SCAN 及 CSCAN 算法中的“磁臂粘着”现象输出结果:Start Cylinder:
51、 10TID: 32 Cylinder: 10 Offset: 0 =TID: 33 Cylinder: 10 Offset: 0 =TID: 34 Cylinder: 10 Offset: 0 =TID: 35 Cylinder: 10 Offset: 0 =TID: 36 Cylinder: 10 Offset: 0 =TID: 37 Cylinder: 10 Offset: 0 =TID: 38 Cylinder: 10 Offset: 0 =TID: 39 Cylinder: 10 Offset: 0 =TID: 40 Cylinder: 10 Offset: 0 =TID: 31 C
52、ylinder: 78 Offset: 68 +即以10 10 10 10 10 10 10 10 10 78的顺序寻道使用 SSTF、 SCAN 和 CSCAN 算法调度这组数据,输出结果相同可以发现,虽然访问 78 号磁道的线程的请求第一个被放入请求队列,但却被推迟到最后才被处理,出现了“磁臂粘着”现象。9 编写 N-Step-SCAN 磁盘调度算法改写代码(部分):IopDiskSchedule( VOID ) if(SubQueueRemainLength = 0) SubQueueRemainLength = SUB_QUEUE_LENGTH; for (pListEntry=Req
53、uestListHead.Next;pListEntry!=&RequestListHead & counter0;stEntry = pListEntry-Next) pRequest = CONTAINING_RECORD(pListEntry, REQUEST, ListEntry); Offset = pRequest-Cylinder - CurrentCylinder; if (0 = Offset) pNextRequest = pRequest; return pNextRequest; else if ( Offset 0 & Offset InsideShortestDis
54、tance ) InsideShortestDistance = Offset; INpNextRequest = pRequest; else if ( Offset 0 & -Offset x.cflag!=0功能:函数int86() 用来执行指定的8086软中断。首先把输入指针所指的共用体中的内容拷贝到CPU 的寄存器中,随即产生对应的中断,返回后将CPU寄存器(AX)的内容拷贝到输出指针指向的共用体中。在使用int86() 函数进行BIOS接口的系统调用时,有的中断调用设有若干选择项,这些选择项可以根据调用时AH寄存器中的值来进行访问。注:1.需先定义 union REGS 输入指针名
55、,输出指针名;2.向寄存器传递入口信息输入指针名.x.寄存器名=要赋的值(入口信息);3.调用int86后得接受出口信息变量名=输出指针名.x.寄存器名4.REGS的定义(在dos.h中):struct WORDREGSunsigned int ax, bx, cx, dx, si, di, cflag, flags;struct BYTEREGSunsigned char al, ah, bl, bh, cl, ch, dl, dh;union REGSstruct WORDREGS x;struct BYTEREGS h;头文件:dos.h函数81。int86x()执行中断函数 (通用80
56、86软中断接口函数)头文件:dos.h原形:int int86x(int intno,union REGS *inregs,union REGS *outregs,struct SREGS * segregs)调用方式:int86x(中断号,&输入指针名,&输出指针名,&段寄存器指针名);注1:需先定义 union REGS 输入指针名,输出指针名;union REGS 示意图 structstructWORDREGSBYTEREGS al 1 byte ax 2 bytes ah bl bx bh cl cx ch dl dx dh union regs si di cflag flags
57、x两个结构变量h共享同一存储域其中字段flags对应于标志寄存器。字段cflag仅对应于进位标志位,函数在调用时不用该字段,只在返回时设置这个字段,因为许多BIOS服务都是通过进位标置为0还是1来表示成功还是失败。注2:需先定义 struct SREGS 段寄存器指针名;结构SREGS定义如下struct SREGS unsigned int es,cs,ss,ds函数只用了该结构中的段寄存器DS和ES。调用时根据它们的值设置DS和ES,同时把DS和ES原来的值保存在这个结构中,返回时再恢复DS和ES为原来的值,这就允许程序使用远指针或大数据编译模式。该函数置全局变量_doserrno等于寄存
58、器AX中的值,其返回值也等于AX中的值。注3:向寄存器传递入口信息输入指针名.x.寄存器名=要赋的值(入口信息);注4:调用int86x后得接受出口信息变量名=输出指针名.x.寄存器名函数82。intdos()通用dos中断接口函数原形:int intdos(inregs,outregs)union REGS *inregs;/调用时的各寄存器的值union REGS *outregs;/返回寄存器的值功能:产生DOS软中断注意:如果需要功能号,则装入AH;如果需要子功能号,则装入AL。头文件:dos.h函数83。intdosx()通用dos中断接口函数原形:int intdosx(inreg
59、s,outregs,segregs)union REGS *inregs;调用时的各寄存器的值union REGS *outregs;返回寄存器的值struct SREGS *seregs;调用时的段寄存器的值(还设置返回时的值)功能:产生DOS软中断头文件:dos.h函数84。intr()执行8086软中断函数(改变软中断接口函数)原形:void intr(int intno,struct REGPACK *preg)调用方式:intr(中断号,&结构变量名)注1:结构REGPACK定义如下struct REGPACKunsigned r_ax,r_bx,r_cx,r_dx;unsigned
60、 r_bp,r_si,r_di,r_ds,r_es,r_flag;注2:使用时先定义一个结构变量struct REGPACK 结构变量名;注3:入口和出口用同一个结构变量来传递寄存器的值。结构变量名.r_ax=要赋的值; intr(中断号,&结构变量名);某变量=结构变量名.r_ax;头文件:dos.h函数85。itoa()把整形数转换为字符串的函数原形:char *itoa(int value,char *string,int radix) 功能:把value的值转换为以NULL结束的字符串,并把结果存在string中。radix是转换的基数值,在2到36之间。分配给string的空间必须可
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑业新质生产力建筑光伏一体化实施
- 新生儿败血症的护理
- 支气管异物护理研究进展
- 病人休息与睡眠护理的成本效益分析
- 生活护理护理课件库
- 新生儿口服水合氯醛后呛奶窒息分析
- 2026年携带涉密合同(1篇)
- 牙齿建模与口腔疾病预防
- 一份完整的投标书名师资料
- 糖尿病与眼部并发症护理
- DL∕T 1918-2018 电力工程接地用铝铜合金技术条件
- 2024年山东省高考化学试卷(真题+答案)
- MOOC 刑事诉讼法-西南政法大学 中国大学慕课答案
- 2024-2029年中国冲调食品行业市场现状分析及竞争格局与投资发展研究报告
- 驻校教官值班制度
- 商品房买卖合同(示范文本)GF-2000-0171
- 对北京卫视的分析报告
- 高考复习《下定义》课件
- 四渡赤水 (2)课件
- GB/T 26725-2023超细碳化钨粉
- 不甘屈辱奋勇抗争
评论
0/150
提交评论