实验目的
- 掌握虚拟文件系统的实现原理
- 实践文件、目录、文件系统等概念
实验内容
在Linux0.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
2 1 1 1 73
4 1 1 27 63
6 0 4 12 817
procfs及其结点要在内核启动时创建。相关功能实现在fs/proc.c文件当中。
实验过程
-
在
include/sys/stat.h
中增加一种文件类型,实验手册里面有写。..... //定义一种新的文件类型 #define S_IFPROC 0060000 ..... //定义测试宏 #define S_ISPROC(m) (((m)&S_IFMT) == S_IFPROC) ....
-
psinfo结点通过
fs/namei.c
文件中的mknod()
系统调用(用户态调用)建立,由于我们添加了新的文件类型,需要在该文件下增加对新文件类型的支持使得在第三步能通过mknod()
函数创建psinfo
文件,我们可以直接修改该系统调用的内核实现sys_mknod()
。.... inode->i_mode = mode; if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISPROC(mode)) inode->i_zone[0] = dev; .....
-
接下来就是建立
/proc
目录以及在该目录下面 创建psinfo
文件。创建目录我们在终端一般使用
mkdir
命令, 在内核态使用sys_mkdir
函数。创建文件我们在第二步已经在
mknod()
函数添加了对新文件类型的支持,在内核态使用sys_mknod()
函数我们可以在系统启动时就建立那些
proc
文件系统(注意这些文件系统是挂载在根文件系统 下面的,我们自定义的proc
文件系统在系统中的位置是根文件系统/proc
)Linux对文件系统的初始化是在根文件系统挂载之后才开始的。对根文件系统是在init/main.c
文件下面的init()
函数中完成的。void init(void) { int pid,i; //挂载文件系统 setup((void *) &drive_info); (void) open("/dev/tty0",O_RDWR,0); .... }
现在只要在挂载根文件系统之后就可以创建我们的目录以及文件了,但是有个地方需要注意:此时我们处在用户态,因此我们不能直接使用内核态才能使用的
sys_mkdir()
以及sys_mknod()
,如果我们需要调用内核态的函数,我们需要先实现用户态的API接口然后通过中断进入内核态调用相应的函数(这是我们在实现操作系统实验二----系统调用中已经学到的知识)。static inline _syscall0(int,fork) static inline _syscall0(int,pause) static inline _syscall1(int,setup,void *,BIOS) static inline _syscall0(int,sync) //用户态API实现 _syscall2(int,mkdir,const char*,name,mode_t,mode) _syscall3(int,mknod,const char*,filename,mode_t,mode,dev_t,dev) void init(void) { ..... setup((void *) &