“操作系统实验”实验报告

proc文件系统的实现

实验名称:proc文件系统的实现

实验日期:2021年7月7日

班级:软件工程(嵌入式培养)191

姓名:华沁蓥

学号:1809041042

一、实验目的

1.掌握虚拟文件系统的实现原理;

2.实践文件、目录、文件系统等概念。

二、实验环境

硬件环境:IA-32(x86) 架构的 PC 机

软件环境:x86 模拟器 Bochs 、 GCC 编译器 、GDB 调试器 、Ubuntu (GNU/Linux)

三、实验内容

在 Linux 0.11 上实现 procfs(proc 文件系统)内的 psinfo 结点。当读取此结点的内容时,可得到系统当前所有进程的状态信息。例如,用 cat 命令显示 /proc/psinfo 的内容,可得到:

$ cat /proc/psinfo
pid    state    father    counter    start_time
0    1    -1    0    0
1    1    0    28    1
4    1    1    1    73
3    1    1    27    63
6    0    4    12    817
copy
$ cat /proc/hdinfo
total_blocks:    62000;
free_blocks:    39037;
used_blocks:    22963;
...
copy

procfs 及其结点要在内核启动时自动创建。

相关功能实现在 fs/proc.c 文件内。

四、实验过程及数据记录

准备环境

  • 解压

    cd ~/oslab
    tar -zxvf hit-oslab-linux-20110823.tar.gz -C /home/shiyanlou
    ls -al
    
    copy

    图片描述

  • 增加新文件类型,修改/include/sys/stat.h

    #define S_IFPROC 0030000
    #define S_ISPROC(m) (((m)&S_IFMT)==S_IFPROC)
    
    copy

    图片描述

  • 让mknod()支持新的文件类型,修改/fs/namei.c文件中的sys_mknod()函数代码,增加关于proc文件系统的判断

    if(S_ISBLK(mode) || S_ISCHR(mode) ||S_ISPROC(mode))
    
    copy

    图片描述

  • 进程proc文件初始化,修改/init/main.c

    _syscall2(int,mkdir,const char*,name,mode_t,mode)
    _syscall3(int,mknod,const char*,filename,mode_t,mode,dev_t,dev)
    
    copy

    图片描述

  • 建立/proc目录下的各个结点

    mkdir("/proc",0755);
    mknod("/proc/psinfo",S_IFPROC|0444,0);
    mknod("/proc/hdinfo",S_IFPROC|0444,1);
    mknod("/proc/inodeinfo",S_IFPROC|0444,2);
    
    copy

    图片描述

  • 编译内核

    cd /home/shiyanlou/oslab/
    cd ./linux-0.11/
    make all
    
    copy

    图片描述

  • 运行Bochs 输入 ll /proc

    # ll /proc
    
    copy
  • 试着读文件

    # cat /proc/psinfo
    
    copy

    图片描述

  • psinfo被正确open()了。接下来需要修改sys_read().首先在/fs/read_write.c中添加声明

    extern int proc_read(int dev,char *but,int count,unsigned long *pos);
    
    copy

    图片描述

  • 在proc_read()添加proc文件

    if (S_ISPROC(inode->i_mode))
    return proc_read(inode->i_zone[0],buf,count,&file->f_pos);
    
    copy

    图片描述

  • 创建/fs/proc.c文件实现上述的proc_read()函数,用于读取proc文件内容 图片描述 图片描述图片描述图片描述图片描述图片描述图片描述

  • 修改/fs/Makefile 图片描述 图片描述

  • 编译内核

    cd /home/shiyanlou/oslab/
    cd ./linux-0.11/
    make all
    
    copy

    图片描述

  • ../run运行内核,输出cat命令,即可查看psinfo(当前系统进程状态信息)和hdinfo(硬盘信息)的信息

    ////cat /proc/psinfo
    
    copy
    cat /proc/hdinfo
    
    copy

    图片描述 图片描述

五、实验结果分析

如果要求你在 psinfo 之外再实现另一个结点,具体内容自选,那么你会实现一个给出什么信息的结点?为什么?

答:我会给出CPU的当前信息。因为CPU的信息也是一个重要的计算机参数,用户得到这个参数,就可以知道比如当前进程总数、CPU寄存器的状态等等信息,方便用户了解系统的信息。而Linux0.11中没有方便查看这个参数的命令,所以加上这个参数会比较有价值。

一次 read() 未必能读出所有的数据,需要继续 read(),直到把数据读空为止。而数次 read() 之间,进程的状态可能会发生变化。你认为后几次 read() 传给用户的数据,应该是变化后的,还是变化前的? + 如果是变化后的,那么用户得到的数据衔接部分是否会有混乱?如何防止混乱? + 如果是变化前的,那么该在什么样的情况下更新 psinfo 的内容?

答:几次传给用户的数据是变化后的,因为如果每次读不完,那么下次会重新调用文件处理函数,向内核态的缓冲区重新写一遍进程的当前信息,靠文件指针约束某一次从那里开始给用户put,这样的话当前进程信息有变化时,是把新的进程信息继续给用户的。

用户得到的数据衔接部分可能会有混乱。因为进程信息的许多数据类型都不是一个字节(比如int一般是4个字节,long更多),而我是一个字节一个字节的向用户态put,那么当系统的进程数比较多的时候,可能会遇到恰好在某个多字节数据的中间终止本次put操作,下次接着从这里继续put,这样的话就会导致用户态中的文件内容的某个数据的前面的某些字节 是上次读出来的,而后面的字节是新读出来的,这样就不会有混乱了。

办法:设置一个数组保存循环时每次的向内核缓冲区里面写进去的字节数,这样put给用户时,每次按着对应的字节数put进去,也即每次都是put给用户完整的一个进程的信息,再相应的移动文件指针即可避免混乱。

六、实验心得

通过本次实验进一步掌握了虚拟文件系统的实现原理以及实践文件、目录、文件系统等概念。完成了本学期的九个实验,结合理论知识,对操作系统有了更为深刻的认识和理解,希望通过以后的实践运用,将知识技能掌握地更加牢固。

最新评论
暂无评论~