# 特殊文件

#### 串口文件UartFileNode

​		将串口操作，即标准输入输出抽象成文件，提供给用户进程。实现方法很简单，直接继承FileNode，重写虚函数为串口操作就行。

​		串口文件在文件系统初始化时会默认添加到/Dev/STDIO。进程初始化的时候也会默认将0号和1号文件设为指向串口的FileHandle，分别表示stdin和stdout。



#### 管道文件PipeFileNode

​		管道文件用于进程间通讯，管道是放在内存中的一片区域，以环形队列的形式存在，可以用文件的形式进行操作。由于管道的读写当空或满时需要阻塞，因此引入信号量，构建生产者消费者模型进行设计。

##### 主要成员和说明如下：

###### 内部保护成员：

* FileNode：继承的FileNode类
* Semaphore Lock：用于作为互斥锁使用的信号量
* Semaphore SemR：控制读者阻塞的信号量
* Semaphore SemW：控制写者阻塞的信号量
* Sint32 WriterCount：写者的数量，当写着数量为0时，必定不可能再有新数据，因此会唤醒所有读者，提前返回
* char *buffer：管道数据缓冲区
* Uint64 BufferSize：管道数据缓冲区大小
* Uint64 PosR：读位置指针
* Uint64 PosW：写位置指针

###### 主要成员函数：

* Read：读管道
* Write：写管道
* Ref：引用，如果是以可写的方式打开，会增加写者计数
* Unref：取消引用，如果是可写的Handle，会减少写者计数，如果计数达到0，会唤醒所有读者进程
* ~PipeFileNode：析构管道并释放资源
* PipeFileNode：构造管道并分配相应资源



#### 内存文件MemoryFileNode

​		内存文件与文件映射内存区域相反，是将内存中的一片区域当作文件来使用，实现方式较为简单，直接继承FileNode类并将Read和Write虚函数设计成读写内存区域即可。



#### 文件映射内存区域MemapFileRegion

​		文件映射内存是将一个文件（或其一部分）映射到进程地址空间中的某个区间，然后进程读写内存区域就能实现读写文件的效果，我们的实现方法是从VirtualMemoryRegion继承出MemapFileRegion类，这个类既可以作为VMR来使用，同时内部记录了一个指针，表示所对应的文件，当创建时会将文件读入到内存中，销毁时会将内存中的数据写回文件。当然，用户可以主动调用一些方法来要求与文件同步

##### 主要成员和说明如下：

###### 内部保护成员：

* VirtualMemoryRegion：继承的VirtualMemoryRegion类
* FileNode *File：所映射的文件的指针
* Uint64 Start：映射到内存中的起始地址，此处额外记录的是因为VMR会对Start和End进行4KB对齐，与原始参数有差异
* Uint64 Length：映射区域的长度
* Uint64 Offset：在文件中映射区域到文件头的偏移量

###### 主要成员函数：

* Save：保存当前内存数据到文件
* Load：从文件载入数据到内存中
* ~MemapFileRegion：析构函数
* MemapFileRegion：构造函数

MemapFileRegion还有一些可以优化的地方，比如检测页表的脏标志位来决定是否要写入、利用缺页中断实现延迟载入文件等，不过由于时间原因，暂时没有实现。



---------------------------------

By：qianpinyi

2022.06.05