模拟操作系统课程设计文档格式.docx
《模拟操作系统课程设计文档格式.docx》由会员分享,可在线阅读,更多相关《模拟操作系统课程设计文档格式.docx(54页珍藏版)》请在冰豆网上搜索。
X=?
;
给i赋值一位数
X++;
i加1
X--;
i减1
第一个?
为A,B,C中某个设备,第二个?
为一位数,表示使用设备的时间
end;
表示文件结束
2.1.2文件的物理结构
文件的物理结构采用索引文件,每个文件分配一个索引块(用来存放索引的盘块)把分配给该文件的所有盘块号都记录在该索引块中,按照这种分派方式存储的文件就是索引文件。
由于索引块就是一个存放许多盘块号的盘块,因此,为使系统能找到文件存放的地址,文件目录项记录该文件索引块的盘块号和文件长度。
为一个大文件分配磁盘空间时,如果所分配除去盘块的盘块号,已经装满一索引块时,便需再为该文件分配另一个索引块,用于将以后继续分配给该文件的盘块号记录其中,以此类推。
同时,应为这些索引块再建立一级索引,即系统再分配一索引块,作为一级索引块的索引块,将第一块、第二块、第三块、……索引块的盘块号写入此索引块中,这样便形成了二级索引的分配方式,如果文件非常大的时候,还可以用三级、四级索引分配方式。
本系统实现二级索引,如图2-1所示:
图2-1文件索引分配方式
2.1.3目录结构
目录结构采用树型目录结构。
目录项内容(16个字节):
目录名、文件名:
6个字节;
扩展名:
3个字节(可执行文件扩展名为exe,目录没有扩展名);
目录、文件属性:
1字节;
文件长度:
2字节(目录没有长度,字节数)。
地址:
直接地址项1个,一级索引项1个,二级索引1项,每项1个字节;
预留1字节
根目录:
根目录位置固定,占用磁盘2块,大小固定,共16项,占用模拟磁盘第1、2块;
子目录;
位置不固定,大小不固定
目录结构如图2-2所示:
图2-2目录结构示意图
2.1.4磁盘模拟
磁盘的分配采用混合索引结构的分配方式。
系统采用成组链接法记录磁盘空间的使用情况。
空闲块每组登记10个空闲块,专用块占用第0块。
索引块中每个盘块号占用4字节,登记32块。
如图2-3是空闲块成组链接示意图:
图2-3空闲块成组链接示意图
2.1.5用户接口
用户接口提供用户命令接口,具体实现以下命令:
1.创建文件:
create文件名
2.拷贝文件:
copy源文件名目标文件名(拷贝文件可同名拷贝,也可更名拷贝)
3.删除文件:
delete文件名
4.移动文件:
move源文件名目标文件名(磁盘内和磁盘间文件移动不同,磁盘内的移动实际只是目录的改变,并不需要真的移动文件;
磁盘间的文件移动实际上是先拷贝文件到目标磁盘,然后再删除源文件。
)
5.显示文件:
type文件名(仅仅是显示文件内容)
6.编辑文件:
edit文件名(此命令完成对文件的编辑,只读文件不可以修改。
7.改变文件属性:
change文件名属性(将文件在只读和非只读、隐藏和非隐藏之间转换。
8.磁盘格式化命令:
format
9.建立目录:
makdir目录名(建立目录,若有同名目录存在,则建立失败。
10.删除空目录:
rdir目录名(只能删除空目录,非空目录不能删除)
11.删除目录:
deldir目录名(既可以删除空目录,又可以删除非空目录,对与非空目录,首先要删除其下文件和目录,然后才能删除其本身。
2.2存储管理
存储管理部分主要实现主存空间的分配和回收、存储保护。
模拟系统中,内存部分分为两部分,一部分是系统区,这里只存放进程控制块,一部分是用户区,这里主要是对用户区的管理。
系统区包括pcb区域、主存空间分配表。
存储管理采用可移动的可变分区存储管理方式。
采用数组来模拟主存的用户区,每个数组元素占用一个字节。
实验中主存大小为512个字节
主存的模拟:
采用数组来模拟主存的用户区,每个数组元素占用一个字节,主存大小为512个字节,每个主存块16个字节
数据结构:
本次实验采用页式管理策略对主存进行分配和回收策略,采用位示图记录主存使用情况
主存分配策略:
当有程序要存放入主存时,查看空闲块总数是否够用,如果够用,先分配一块用来存放页表,然后查位示图中为“0”的位,根据查到的位所在的字号和位号可计算出对应的块号,同时在该位填上占用标志“1”,并填写页表;
不够用,分配失败。
块号=字号*字长+位号
主存回收策略:
根据页表归还存储空间时,可以根据归还块的块号推算出在位示图中的位置:
字号=[块号/位示图中字长]
位号=块号mod位示图中字长
然后把这一位的“1”清成“0”,表示该块成为空闲块了,最后回收页表所占用空间。
屏幕显示:
主存使用情况示意图,哪些主存已经分配,哪些主存未分配,以不同的颜色表示(例如,红色表示已分配,蓝色表示未分配)。
正在运行的进程对应指令存放的位置以特殊颜色显示。
2.3进程管理
进程管理主要包括进程调度,进程的创建和撤销、进程的阻塞和唤醒,中断作用的实现。
2.3.1主要寄存器的模拟
用全局变量模拟重要寄存器,如cpu重要寄存器,程序状态寄存器PSW、指令寄存器IR,程序计数器PC,数据缓冲寄存器DR等。
2.3.2中断的模拟
中断的发现应该是硬件的工作,这里在函数CPU中加检测PSW的方式来模拟。
在CPU()函数中,每执行一条指令之前,先检查PSW,判断有无中断,若有进行中断处理,然后再运行解释指令。
CPU函数应该不断循环执行的。
2.3.3模拟中断的种类和中断处理方式:
程序结束(执行指令end形成的中断,软中断):
将结果写入文件out,其中包括文件路径名和x的值,调用进程撤销原语撤销进程,然后进行进程调度;
I/O中断(设备完成输入输出):
将输入输出完成的进程唤醒,将等待该设备的一个进程同时唤醒。
2.3.4时钟模拟
系统中的绝对时钟和相对时钟用全局变量模拟。
系统时钟用来记录开机以后的时间。
这里的系统时钟并不是计算机的真正的时钟,这里所说的时间只是一个单位,例如使用vb中的时钟控件实现,每触发一次timer事件,绝对时钟增1,表示增加一个时间单位,绝对时钟减1,表示时间片消耗一个。
2.3.5进程控制块
进程控制块内容包括进程标识符、主要寄存器内容、进程状态、阻塞原因等等。
本模拟系统最多容纳10个进程块。
pcb区域用数组模拟。
进程控制块根据内容的不同组成不同的队列,空白进程控制块链、就绪队列和阻塞队列,正在运行的进程只有一个,系统初始时只有空白进程控制块链。
2.3.6进程调度
采用抢占式优先级调度算法。
进程调度函数的主要工作是:
将正在运行的进程保存在该进程对应进程控制块中;
从就绪队列中选择一个进程;
将这个进程中进程控制块中记录的各寄存器内容恢复到CPU各个寄存器内。
2.3.7进程控制
建立四个函数模拟进程创建、撤销、阻塞和唤醒四个原语。
进程创建create
进程创建的主要工作是:
第一步,申请空白进程控制块;
第二步,申请主存空间,申请成功,装入主存;
第三步,初始化进程控制块;
第四步,将进程链入就绪队列,根据情况决定是否转向进程调度。
进程撤销destory
进程撤销的主要工作是:
第一步,回收进程所占内存资源;
第二步,回收进程控制块;
第三步,在屏幕上显示进程执行结果,进程撤销
进程阻塞block
进程阻塞的主要工作是:
第一步,保存运行进程的CPU现场;
第二步,修改进程状态;
第三步,将进程链入对应的阻塞队列,然后转向进程调度。
2.3.8进程的创建:
2.3.9进程的撤销:
2.3.10进程的阻塞:
2.3.11进程的唤醒
进程唤醒的主要工作是
第一步,将进程由阻塞队列中摘下;
第二步,修改进程状态为就绪;
第三步,链入就绪队列,根据情况决定是否转向进程调度。
2.3.12屏幕显示
屏幕显示要求包括:
显示系统时钟;
显示正在运行的进程的进程名、运行的指令、中间结果、相对时钟寄存器内容;
显示就绪队列中进程名;
显示阻塞队列中进程名。
2.3.13硬件工作的模拟
硬件工作的模拟包括中央处理器的模拟、主要寄存器的模拟、中断的模拟和时钟的模拟四方面。
①中央处理器的模拟。
用函数CPU()(该函数不能有参数)模拟中央处理器。
该函数主要负责解释“可执行文件”中的命令。
如:
给x赋值x=?
;
x自加x++;
x自减x--;
申请设备和时间;
程序结束end;
CPU只能解释指令寄存器IR中的指令。
一个进程的运行时要根据进程执行的位置,将对应的指令存放到指令寄存器中。
②主要寄存器的模拟用全局变量模拟重要寄存器,如cpu重要寄存器,程序状态寄存器PSW、指令寄存器IR,程序计数器PC,数据缓冲寄存器DR等。
③中断的模拟。
模拟中断的种类有如下几种:
程序结束、时间片到、I/O中断。
时钟中断:
进程时间片用完,转为就绪,重新进程调度。
④时钟的模拟。
这里的系统时钟并不是计算机的真正的时钟,这里所说的时间只是一个单位,例如使用vb中的时钟控件实现,每触发一次timer事件,绝对时钟增1,表示增加一个时间单位,绝对时钟减1。
2.4设备管理
设备管理主要包括设备的分配和回收。
模拟系统中有A、B、C三种独占型设备,A设备3个,B设备2个,C设备1个。
设备分配:
采用先来先服务策略。
设备回收:
回收设备后,要注意唤醒等待设备的进程。
每个设备是否被使用,哪个进程在使用该设备,哪些进程在等待使用该设备。
三系统实现
3.1程序主页面
程序主页面如图3-1所示:
图3-1程序主页面
3.2全局变量
publicconstintn=10,m=10;
publicstaticFree_table[]free_table=newFree_table[n];
//空闲分区表
publicstaticUsed_table[]used_table=newUsed_table[m];
//已分分区表
publicstaticUsed_table[]buffer=newUsed_table[n];
publicstaticchar[]mm=newchar[512];
//模拟内存
privateList<
Label>
mems=newList<
();
//内存
TextBox>
readys=newList<
//就绪队列
waitsn=newList<
//阻塞名字
waitsr=newList<
//阻塞原因
publicstaticcharuseeq='
U'
publicstaticstringa0,a1,a2,a3,a4,a5;
publicstaticintrunning=1;
publicstaticintalready=2;
publicstaticintblocking=3;
publicstaticintPC,PSW,DR,TIME,TIME2;
publicstaticcharAX,BX,CX,DX;
publicstaticchar[]IR=newchar[4];
publicstaticPCB[]pcb=newPCB[10];
publicstaticqueueready=newqueue();
publicstaticqueuewait=newqueue();
//阻塞队列
publicstaticqueueempty=newqueue();
//空闲PCB队列
publicstaticintrun;
publicstaticEQ[]eq=newEQ[6];
//设备数组
publicint[]ETIME=newint[6];
//各个设备的时间
publicstaticinttime=0;
//表示系统时间
publicconstintminisize=2;
//-------------------文件-----------------------------
memc=newList<
publicFile_Functionc=newFile_Function(0);
publicstaticintaaa=0;
publicstaticintbbb=0;
3.3文件管理
3.3.1创建目录:
建立目录首先要找到建立目录的位置(父目录),然后查找该目录是否存在,如果父目录不存在,不能建立,如果存在,查找是否存在同名目录,存在,不能建立,不存在,则查找一个空目录项,,为该目录项申请一个盘块,并填写目录内容,初始目录有我的电脑和我的电脑下的磁盘C两个目录。
目录创建过程如图3-2所示:
图3-2创建一个目录的流程图
创建一个目录的命令如图3-3所示:
图3-3创建一个目录的命令
3.3.2删除空目录:
删除空目录首先要找到该目录,如果目录不存在,删除失败;
如果存在,但是,是非空目录,显示不能删除,操作失败;
若是空目录,将目录在树形目录和磁盘中删除,如图3-4所示:
图3-4删除空目录的流程图
删除一个空目录的命令如图3-5所示:
图3-5删除一个空目录的命令
3.3.3删除目录
删除目录是在删除空目录的基础上增加了删除非空目录的功能。
首先检查要删除的目录是否为空,若为空,调用删除空目录的函数,将其删除;
若不为空,深度优先遍历以该目录为根节点的子树,将其孩子节点依次都删除,最后调用删除空目录的函数,将该目录删除,就完成了删除目录的工作。
3.3.4文件的创建与删除
文件的创建与删除,是建立在目录的创建与删除基础之上的。
只需要调用建立和删除目录函数,建立或删除文件目录。
然后,将该文件插入到打开文件表中就完成了一个文件的建立,删除则对应回收操作。
文件的建立流程如图3-6所示:
图3-6新建文件流程图
新建一个文件的命令如图3-7所示:
图3-7新建一个文件的命令
文件的删除流程如图3-8所示:
图3-8删除文件流程图
删除一个文件的命令如图3-9所示:
图3-9删除一个文件的命令
3.3.5文件的存储
建立文件和目录后,要求可以在磁盘上长期的保存。
实现文件的长期存储,是通过在自己电脑的外存上,动态建立文件来实现的,在每次模拟的磁盘有内容的改变的时候,将内容写到外存的文件一次,当系统再次重新启动的时候,将外存中的文件内容读到模拟磁盘的数组中,就实现了简单的文件的长期存储,具体代码如下:
publicFile_Function(inttag)
{
//
//TODO:
在此处添加构造函数逻辑
//建立一个文件或文本文档来模拟磁盘,初始化时如果文件为空,则磁盘第一二块存储FAT表,第三块存储根目录,若文件不为空,则不修改文本。
path=@"
E:
\流星操作系统\流星操作系统\disk.txt"
//建立C盘
if(!
File.Exists(path))
FileStreamfs=newFileStream(path,FileMode.CreateNew);
fs.Seek(0,SeekOrigin.Begin);
fs.Write(disk,0,8192);
for(inti=0;
i<
3;
i++)
FAT[i]=255;
for(inti=3;
128;
FAT[i]=0;
fs.Write(FAT,0,128);
fs.Close();
}
else//从磁盘中提取数据写入FAT表中
FileStreamfs=newFileStream(path,FileMode.Open,FileAccess.Read);
fs.Read(FAT,0,128);
3.3.6磁盘模拟
根据成组连接法,将磁盘的空闲块进行链接,空闲块的分配和回收都是针对专用块来操作的,没分配一块后,把空闲块数减1,但要把一组中的第一个空闲块分配除去之前应该把登记在该块中的下一组的块号及块数保存到专用快中(原专用块中的信息已经无用,因为它指示的一组空闲块都已被分配)。
当归还一块时,只要把归还块的块号登记到专用块的当前组中且将空闲块数加1,如果当前组已经满10块,则把专用块中的内容写到归还的那块中,该归还块作为新组的第一块。
空闲块的分配和回收都是针对专用块来操作的,没分配一块后,把空闲块数减1,但要把一组中的第一个空闲块分配除去之前应该把登记在该块中的下一组的块号及块数保存到专用快中(原专用块中的信息已经无用,因为它指示的一组空闲块都已被分配),如图3-10所示:
图3-10分配一个盘快示意图
当归还一块时,只要把归还块的块号登记到专用块的当前组中且将空闲块数加1,如果当前组已经满10块,则把专用块中的内容写到归还的那块中,该归还块作为新组的第一块,如图3-11所示:
图3-11归还一个盘快示意图
磁盘使用情况用文件分配表来记录:
磁盘有多少块,该表就有多少项,某文件的一个磁盘块号为i,则这个文件的下一个磁盘块的块号记录在表的第i项。
如图3-12是空闲块位示图法示意图:
图3-12空闲块FAT示意图
磁盘的状态在每次分配和回收磁盘块的函数过程中实现,每分配一个空闲块,将相应label由蓝色改为棕色,表示该磁盘块已经被占用;
每回收一块磁盘块的时候,将相应label由棕色改为蓝色,表示该磁盘块空闲。
如图3-13所示:
图3-13磁盘的状态显示
3.4用户接口
用户接口包括命令接口和图形接口两种,命令接口要求用户输入规定格式的文字命令,系统判断输入是否正确采取相关操作。
图形借口相比于命令接口比较方便,用户不必输入命令,直接选择菜单项进行操作。
用户接口如图3-14所示:
图3-14用户接口页面
命令接口流程图如图3-15所示:
图3-15命令接口流程图
图形接口流程如图3-16所示:
图3-16图形接口流程图
3.5进程管理
进程管理页面如图3-17所示:
图3-17进程管理页面
3.5.1分配内存空间函数:
publicintallocate(intt,intxk,stringstr)
{//采用最优分配算法进行分配,作业名是J,作业大小是xk
inti,k,j,a,b;
intad;
k=-1;
for(i=0;
n;
{//寻找空间大于xk的最小空闲区登记项k
if(free_table[i].length>
=xk&
free_table[i].flag==1)
if(k==-1||free_table[i].length<
free_table[k].length)
k=i;
if(k==-1)//未找到可用空闲区,返回错误信息
return-1;
//找到可用空闲区,开始分配,若空闲区大小与要求分配的空间差小于minisize大小,则空闲区全部分配出去,
//若空闲区大小与要求的空间差大