《操作系统实验》指导书
三、设计方案
本系统提供的参考程序在C++环境中开发,下面介绍系统的设计方案。
3.1 采用FAT文件格式
文件在磁盘上的组织采用FAT文件格式,为了设计程序方便,本系统的FAT表用整型数组FAT[K]表示(K为总盘块数,本系统中假定K=5000,即共有5000个盘块),而实际的操作系统,FAT表是存储在磁盘中的,当系统启动时装入内存。FAT[0]中存储空闲盘块数。 磁盘空间用字符数组Disk[K][SIZE] (其中SIZE为每个盘块的字节数,即盘块的容量)表示。本系统设定磁盘块容量为64。
3.2 目录项(FCB)结构
本模拟系统的文件目录项(FCB)结构如下:
文件名 (11字节) struct FCB {
char FileName[11]; char Fattrib; short int Addr; short int Fsize; };
属性 (1字节) 首块号 (2字节) 文件长度 (2字节) //每个目录项16个字节
//文件名最多10个字符且以'\\0'结尾 //文件属性 //文件首块号 //文件长度
? 为简单,本系统不考虑文件扩展名,文件名为1~10个字符,以结尾标记'\\0'存储(实
际操作系统目录项中文件名一般没有结尾标记),命令中输入的文件名若超过10个则截取前10个字符。
? 文件属性为1个字节,其二进制位对应的属性如下图所示。
D7 0 D6 0 D5 0 D4 0/1 D3 0 D2 0/1 D1 0/1 D0 0/1 1111表表表表 示示示示 系目隐只统 录 藏 读
? 文件的首块号Addr=0代表空文件(此时文件长度Fsize=0)。文件名(目录名)的第一
个字符的ASCII码为0E5H或00H,代表空目录项。其中0E5H是目录项被删除后的标志,00H代表该目录项从未使用过。
? 每个目录项占用16个字节,因系统中假设磁盘块大小SIZE=64,因此,每个盘块可
存储4个目录项。
? 除根目录外,每个目录中的第一个目录项存储父目录的FCB(该目录项的名字为
“..”),其地址是父目录的首块号,它的作用是相当于指向父目录的指针,用于实现从该目录退回父目录。目录项“..”是在创建目录时,由系统自动建立的,它不能被rd命令删除。
3
《操作系统实验》指导书
3.3 根目录
本系统假设根目录存储在1~30号盘块中,即存储在Disk[1]~Disk[30]的盘快中。因每个盘块可存储4个目录项,故本系统根目录中的文件目录项及子目录项最多共计120个。从31号盘块开始为文件区,用于存储文件及子目录。
本系统初始化时,图1所示的目录树的磁盘分配情况如图2所示。
Disk[1] —— bin,usr,auto,dev Disk[31]:.. Disk[33]:.. Disk[32]:..,user,lib,bin Disk[30] Disk[35]:.. Disk[36]:.. Disk[34]:..,li,sun,ma Disk[37]:.. Disk[38]:.. Disk[39]:.. 图2 初始目录树的磁盘空间分配
根目录
3.4 主要函数
系统参考程序的主要函数如下: main() 主函数
AttribComd() attrib命令处理函数 CdComd() cd命令处理函数 CloseComd() close命令处理函数 CopyComd() copy命令处理函数 CreateComd() Create命令处理函数 DelComd() del命令处理函数 DirComd() dir命令处理函数 MdComd() md命令处理函数 OpenComd() open命令处理函数 RdComd() rd命令处理函数 ReadComd() read命令处理函数 RenComd() ren命令处理函数 TypeComd() type命令处理函数 UndelComd() undel命令处理函数 WriteComd() write命令处理函数 ParseCommand() 分析、分解命令行 ExecComd() 执行命令
FindPath() 查找指定目录路径的首块号 FindFCB() 查找指定文件(或目录)的首块号
ProcessPath() 将路径名分离成目录路径与文件名两部分
4
《操作系统实验》指导书
3.5 用户已打开文件表(UOF)
设置一张“用户已打开文件表”(UOF),用于记录用户当前正在使用文件的情况。本系统允许用户最多同时打开或建立S个文件,故用户已打开文件表UOF共有S个登记栏。 用户请求打开或建立一个文件时,相应的文件操作把有关该文件的信息登记到UOF中。 UOF表项的结构如下:
struct UOF //定义用户打开文件表的结构 {
char fname[PATH_LEN]; //文件全路径名
char attr; //文件属性,1=只可读;0=可读写 short int faddr; //文件的首块号 short int fsize; //文件大小(字节数)
FCB *fp; //指向该文件的目录项指针
short int state; //状态:0=空表项;1=新建;2=打开
short int readp; //读指针,指向某个要读的字符位置,0=空文件 short int writep; //写读指针,指向某个要写读的字符位置 };
本程序中,用户打开文件表用数组UOF uof[S]表示,其中S=32,即最多允许同时打开32个文件。读指针和写指针用于指出对文件进行存取的当前位置。fp指向该UOF登记项对应的文件的目录项。系统启动时, UOF常驻内存,退出系统时,UOF不需要保存。
3.6 程序中有关变量的说明
1. 当前目录curpath数据结构
struct CurPath {
short int fblock; //当前目录的首块号 char cpath[PATH_LEN]; //当前目录路径字符串 };
当前目录用全局变量curpath存储:CurPath curpath; 根目录的路径字符串cpath是“/”,首块号为1。 2. 删除文件恢复表udtab数据结构
struct UnDel { //恢复被删除文件信息表的数据结构
char gpath[PATH_LEN]; //被删除文件的全路径名(不含文件名) char ufname[FILENAME_LEN];//被删除文件名
short ufaddr; //被删除文件名的首块号
short fb; //存储被删除文件块号的第一个块号(链表头指针) //首块号也存于fb所指的盘块中 };
与实际系统不同,为简化程序设计,本系统的被删除文件恢复表用(全局变量)数组udtab存储,定义为:UnDel udtab[DM];程序中DM值为40,即最多保存40个被删除文件的信息(若删除文件数超过40个时,总是保持最新的40个被删除文件信息)。一个被删除文件恢复后,其在udtab表中的信息将被删除。退出系统时该表可存于文件UdTab.dat中。 3. 全局变量ffbp和Udelp
short Udelp; 它是udtab表的第一个空表项的下标,系统初始化时为0。当Udelp=DM时,表示表已满,需清除最早的表项(后续表项依次前移)。系统退出存盘时,其值保存到0号
5
《操作系统实验》指导书
盘块Disk[0]中,以便下次启动系统使用。
short ffbp; 它是分配盘块时FAT表的起始指针(下标),这样使得分配盘块类似于分区存储管理的“循环首次适应”分配算法,这有利于被删除文件的恢复。系统退出存盘时,其值也保存到0号盘块Disk[0]中。 4. 全局数组comd[8][PATH_LEN]
char comd[8][PATH_LEN]; 它在分析命令时使用,其中comd[0]存放命令字符串,comd[1],...,comd[7]用于存放命令参数。 5. 全局数组temppath[PATH_LEN]
char temppath[PATH_LEN]; 用于临时存储文件的路径名(绝对路径名而非相对路径名)。例如,设当前目录为/usr,执行命令open user/boy时,系统将文件boy的全路径名(即绝对路径名) \/usr/user/boy\,存放在temppath中,在登记UOF表项时,再将temppath存储到表项的fname域中。其他一些命令处理过程中也会用到temppath。
3.7 主要函数的流程图
1. 主函数main()的流程图
主函数main()的流程图如图3所示。
开始 初始化 输入命令行 是exit吗? 否 调用函数ParseCommand( ) 分解命令行 调用执行命令函数ExecComd( ) 执行输入的命令 是 要保存数据吗? 是 保存相关数据 结束 否 采用条件编译实现: 初始化目录树、FAT、Disk、UOF等 或者从文件读入FAT、Disk等数据 图3 主函数流程图
2. create命令流程图
创建新文件的命令格式如下:
create <文件名>[ <文件属性>]
命令中的“文件属性”规定了文件的使用权限,分为“只读”、“隐藏”、“系统”等,分别用“r”、“h”、“s”的形式表示,程序内部分别用1、2、4表示(参见3.2节的介绍),它们可以组合使用,例如“rh”表示“只读”且“隐藏”属性的文件,其属性值为3,又如“rhs”表示“只读”且“隐藏”且“系统”属性的文件,其属性值为7。若命令中无可选项“文件属性”,则创建的文件是属性值为0的普通文件,即不是只读文件,也不是隐藏文件,也不是系统文件。
create命令中的“文件名”允许是绝对路径名或相对路径名,例如命令 create /usr/user/boy
表示在根目录的usr子目录中的user子目录中建立文件boy,该文件为普通文件。又如 create bin/mail rh
6
《操作系统实验》指导书
表示在当前目录中的bin子目录中建立文件mail,该文件为“只读”且“隐藏”属性的文件。执行create命令时,当路径不存在或有同名文件,则分别给出错误信息。 create命令处理函数CreateComd()的简化流程图如图4所示。
开 始 查找“文件名”中的路径, 并将该路径存于temppath中。 否 显示:路径错误 返回 该目录中有 该文件? 否 在该目录中找到空登记栏登记该文件名的目录项;在UOF中登记该文件,状态=建立,读指针=0(空文件),? 显示“文件创建成功” 显示:同名文件 不能建立 是 该路径存在吗? 是 查temppath中最后一目录 返回 图4 “创建文件”流程图
3. cd命令流程图
命令形式:cd [<目录名>]。命令功能:改变当前目录,即把指定目录变为当前目录(工
作目录)。指定目录不存在时,给出错误信息。若命令中无目录名,则显示当前目录路径名。cd命令的处理函数为CdComd(),其简单流程图如图5所示。
开始 命令格式正确吗? 是 否 命令中有参数吗? 是 显示当前目录 指定路径正确吗? 是 将查找过程得到的全路径名以及指定目录的首块号保存到当前目录变量中 返回 图5 cd命令函数流程图 否 显示错误信息 否 7