OS

OS lab5

Posted by Steel Shadow on May 26, 2023

思考题

  1. 如果通过 kseg0 读写设备,那么对于设备的写入会缓存到 Cache 中。这是一种错误的行为,在实际编写代码的时候这么做会引发不可预知的问题。请思考:这么做这会引发什么问题?对于不同种类的设备(如我们提到的串口设备和 IDE 磁盘)的操作会有差异吗?可以从缓存的性质和缓存更新的策略来考虑。

    在串口设备中,是通过物理内存实时响应的。若在串口设备中使用缓存,则只有在响应缓存页被替换时,物理内存才更新,导致串口设备读取的数据过期。

    在 IDE 磁盘中,我认为没有问题。 如果 IDE 磁盘不会在操作系统无介入的情况下自行调整存储状态,静态磁盘应该是可以使用缓存加速读写的。

  2. 查找代码中的相关定义,试回答
    • 一个磁盘块中最多能存储多少个文件控制块?
      4KB / 256B = 16
    • 一个目录下最多能有多少个文件?
      16 * (10 + 4KB / 4B - 10) = 16 K
    • 我们的文件系统支持的单个文件最大为多大?
      4KB / 4B * 4KB = 4MB
  3. 请思考,在满足磁盘块缓存的设计的前提下,我们实验使用的内核支持的最大磁盘大小是多少?

    DISKMAX * 1B = 1GB

  4. 在本实验中,fs/serv.h、user/include/fs.h 等文件中出现了许多宏定义,试列举你认为较为重要的宏定义,同时进行解释,并描述其主要应用之处。

     #define BY2SECT 512      /* 磁盘区大小 */
     #define SECT2BLK (BY2BLK / BY2SECT) /* 磁盘块包含的物理磁盘区数 */
    
        
     #define DISKMAP 0x10000000 // 磁盘缓存的虚拟地址
     #define BY2BLK BY2PG //磁盘块大小=页面大小
     #define BY2FILE 256 // 文件控制块大小
    
  5. 在 Lab4“系统调用与 fork”的实验中我们实现了极为重要的 fork 函数。那么 fork 前后的父子进程是否会共享文件描述符和定位指针呢?请在完成上述练习的基础上编写一个程序进行验证。

    serv.c 中,PTE_LIBRARY 共享了 Fd 所在页面。

    1
    2
    3
    4
    5
    
     void serve_map(u_int envid, struct Fsreq_map* rq){
         ...
         //PTE_LIBRARY 共享 Fd 所在页面
         ipc_send(envid, 0, blk, PTE_D | PTE_LIBRARY);
     }
    
  6. 请解释 File, Fd, Filefd 结构体及其各个域的作用。比如各个结构体会在哪些过程中被使用,是否对应磁盘上的物理实体还是单纯的内存数据等。说明形式自定,要求简洁明了,可大致勾勒出文件系统数据结构与物理实体的对应关系与设计框架。

    File

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
     struct File { //物理实体
         char f_name[MAXNAMELEN]; // filename
         uint32_t f_size;  // file size in bytes
         uint32_t f_type;  // file type
         uint32_t f_direct[NDIRECT]; //直接内容
         uint32_t f_indirect; // 间接指针
         struct File *f_dir; // 所在目录指针
         char f_pad[BY2FILE - MAXNAMELEN - (3 + NDIRECT) * 4 - sizeof(void *)];
         } __attribute__((aligned(4), packed));
    
     struct Fd { //内存数据
         u_int fd_dev_id; //设备id
         u_int fd_offset; // 读写的偏移量
         u_int fd_omode; //⽂件打开的读写模式
    };
     struct Filefd { //两者结合
         struct Fd f_fd;
         u_int f_fileid;
         struct File f_file;
     };
    
  7. 图5.7中有多种不同形式的箭头,请解释这些不同箭头的差别,并思考我们 的操作系统是如何实现对应类型的进程间通信的。

    ENV_CREATE(user_env) ENV_CREATE(fs_serv) 在内核态完成,直接创建用户进程。
    fs_serv 进程在初始化 fs_init() 后,和其他需要使用文件系统的用户进程使用 ipc_* 通信。

实验难点

本次实验需要理解文件系统结构,用户使用 fd.c 接口,使用文件描述符读写文件,fsipc.c 与文件系统服务进程使用 ipc_* 交互,文件系统服务进程实现磁盘缓存,并使用驱动程序操作磁盘。

实验体会

文件系统较为复杂,我们的 lab 只涉及了其中很小一部分,对于用户进程与服务进程的了解不够透彻。限于实验篇幅,内容十分精简。