OS_lab5_实验报告
1. 思考题
使用kseg0去读写设备,会导致读取的数据可能不正确。因为kseg0段使用cache来访存,当CPU访问一个物理地址时,会先检查该地址所在块是否在cache中,如果在那么直接从cache中进行读或写,如果不在那么申请一块并从内存中读取该块的内容到cache中,并重新访问。这样做之所以可行是因为对cache中的块的数据进行操作等效于对内存直接操作。但是如果外设对内存的操作不会引起cache的变化,如果外设对内存中的数据进行了修改,那么cache中对应块没有随之修改,这就会导致cache中的块的数据和内存中块数据不一致,导致CPU访问的时候读取到了错误的数据。同理CPU的写入也会先写进cache,之后再回写到内存中,这样会导致外设有可能读不到CPU写入的数据。
一个磁盘块的大小是4KB,也就是4096字节;而一个文件控制块FCB的大小固定为256字节,因此一个磁盘块中最多能存储16个文件控制块。一个目录最多拥有1024个磁盘块,因此最多能有16384个文件。我们文件系统支持单个文件最多拥有1024个磁盘块,也就是4MB。
缓冲区的范围是 [DISKMAP, DISKMAP + DISKMAX],因此其大小为 DISKMAX = 0x40000000,也就是 1GB
fs/serv.h 中的宏定义如下:
其中较为重要的宏定义有:
PTE_DIRTY,磁盘块的脏位,标志磁盘块是否被写过。
SECT_SIZE,512Bytes,一个扇区的大小。
DISKMAP, DISKMAX,文件系统服务进程中磁盘块的起始虚拟地址和最大大小。
user/include/fs.h中宏定义如下:
其中较为重要的宏定义有:
MAXNAMELEN,文件名的最大长度。
MAXPATHLEN,文件结构的最长路径。
NDIRECT,文件控制块中直接记录磁盘块的数量。
NINDIRECT,文件控制块中间接记录磁盘块的数量。
MAXFILESIZE,文件的最大大小。
FILE_STRUCT_SIZE,文件控制块的大小。
struct File,文件控制块结构体的定义。
fork 之后,父子进程会共享文件描述符和定位指针。
1 |
|
三个结构体的定义如下图:
f_name:文件名
f_size:文件大小
f_type:文件类型(文件或目录)
f_direct:文件直接对应的磁盘块号
f_indirect:文件简介对应的磁盘块号
f_dir:文件所在目录的文件控制块
f_pad:填充
该结构体会在存储文件信息的时候用到,在查找文件结构、访存文件信息的时候会用到,是磁盘上的物理实体。
fd_dev_id:访问的外设的编号,对应磁盘、控制台、管道。
fd_offset:在访存文件数据的时候,从多少偏移的位置开始访存。
fd_omode:openmode,文件的打开方式。
该结构体是一个内存中的数据,不是磁盘中的实体,记录文件的打开信息。
f_fd:struct Fd 类型的对象,可以通过强制类型转换来解释内存中的内容。
f_fileid:文件的id,用于查找Open数组。
f_file:struct File 类型的对象,存储访问文件的文件控制块。
该结构体也是一个内存中的数据,不是磁盘中的实体,跟 struct Fd 共享存储空间。
实线黑三角箭头是同步消息,消息发出者需要在消息发出后等待接收者的回信,之后才继续运行。实线折线是异步消息,消息发出后发出者无需等待,可以直接继续运行。
虚线是返回消息,用来唤醒等待的同步消息发出线程。
操作系统通过进程间通信 IPC 机制来实现通信。消息接收者如果没有收到发送者的消息,会一直让出CPU控制权,直到收到消息。
2.难点分析
Lab5 的难点主要在于理解文件系统的体系结构 + 理解MOS操作系统中如何实现文件系统。
文件系统的体系结构主要在于文件控制块和磁盘的存储方式。首先是文件控制块,其内部包含了关于文件的诸多信息,包括文件名、文件大小、文件内容所存储到的磁盘块编号。通过一个文件的文件控制块,可以遍历文件的各种信息,从而完成对文件的访存。其次是磁盘的存储方式,磁盘由磁道、磁头、扇区组成,一般来说一个扇区的大小是512B,对于磁盘来说访存的最小单位是扇区。访问外设可以通过MMIO,也就是内存映射的方式来实现。对于CPU来说,可以通过访问特定内存地址来达到读取外设寄存器的效果。先对外设地址设定参数,之后等待外设准备就绪后就可以读取或写入特定内存地址,从而可以读取或者写入磁盘。但是直接操作扇区并不方便,为了便于管理和隐去接口细节,操作系统规定了磁盘块这一概念,一个磁盘块由相邻的几块扇区组成,大小一般是4KB,操作系统以磁盘块为最小操作单元来访存外设。
MOS中首先编写了设备驱动程序,用来访存外设寄存器,并实现了读取或者写入磁盘块的函数,这样就可以操作一整个磁盘块。之后MOS操作系统中使用一个文件系统服务进程来相应用户程序的请求,二者通过IPC机制来通信。具体过程为,用户进程调用顶层接口,例如 open,read,write,remove等,这些顶层接口的实现用会调用fsipc_open,fsipc_map,fsipc_remove等,这些不同的函数最终都会调用fsipc,并传入请求的类型,fsipc中通过ipc_send和ipc_recv来与文件系统服务进程通信,文件系统系统服务进程通过ipc传入的参数来判断请求类型,并调用相应的file_open,file_read,file_remove等操作,这些操作中又会调用底层的serve_open,serve_remove等函数,最后由这些函数和内存、磁盘交互。
同时文件系统服务进程还采用了缓冲区来提高访存外设的速度。在用户open一个文件的时候,文件系统服务进程就会把该文件的所有磁盘块读取到缓冲区,并为之创建文件描述符,里面含有文件控制块和相关信息,然后在用户进程的对应虚存空间中映射文件磁盘块的页面,之后在用户read或者write的时候,就可以通过共享页面来访问内存中的磁盘信息。
3. 实验体会
本单元的理论和实践同样都很重要,需要细细体会,反复阅读,这样才能细致的掌握文件系统的细节信息,了解文件的组织、访存方法,了解用户进程访问文件的过程和操作系统的工作。
4. 原创声明
本实验报告均为原创。