实验名称:proc文件系统的实现
实验日期:2021.7.9
班级:软嵌192
姓名:贾梦娇
学号:1930110798
一、实验目的
二、实验环境
本操作系统实验的硬件环境是IA-32(x86)架构的PC机(在实验楼的环境中就是右边的窗口)。
主要软件环境是Bochs + gcc +编辑器/ IDE +操作系统+ Linux 0.11源代码。
三、实验内容
在 Linux 0.11 上实现 procfs(proc 文件系统)内的 psinfo 结点。当读取此结点的内容时,可得到系统当前所有进程的状态信息。
四、实验过程及数据记录
1、 procfs 简介
环境准备:
cd ~/oslab
tar -zxvf hit-oslab-linux-20110823.tar.gz -C /home/shiyanlou
copy
cat /proc/meminfo
copy
2、 基本思路
Linux 是通过文件系统接口实现 procfs,并在启动时自动将其 mount 到 /proc 目录上。
此目录下的所有内容都是随着系统的运行自动建立、删除和更新的,而且它们完全存在于内存中,不占用任何外存空间。
3、 增加新文件类型
在 include/sys/stat.h 文件中定义了几种文件类型和相应的测试宏:
4、 让 mknod() 支持新的文件类型
让mknod()支持新的文件类型,修改/fs/namei.c文件中的sys_mknod()函数的代码,在其中增加关于proc文件系统的判断:
进程proc文件初始化,修改linux-0.11/init/main.c,建立/proc目录:
_syscall2(int,mkdir,const char*,name,mode_t,mode)
_syscall3(int,mknod,const char*,filename,mode_t,mode,dev_t,dev)
copy
建立/proc目录下的各个结点:
编译、运行 0.11 内核后,用 ll /proc 可以看到:
5、 让 proc 文件可读
在/fs/read_write.c中添加声明extern:
在sys_read()添加proc文件:
6、 proc 文件的处理函数
包含 linux/kernel.h 头文件后,就可以使用 malloc() 和 free() 函数。它们是可以被核心态代码调用的,唯一的限制是一次申请的内存大小不能超过一个页面。
7、 实现 sprintf() 函数
Linux 0.11 没有 sprintf(),可以参考 printf() 自己实现一个。
#include <stdarg.h>
//……
int sprintf(char *buf, const char *fmt, ...)
{
va_list args; int i;
va_start(args, fmt);
i=vsprintf(buf, fmt, args);
va_end(args);
return i;
}
copy
8、 cat 命令的实现
cat 是 Linux 下的一个常用命令,功能是将文件的内容打印到标准输出。
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
char buf[513] = {'\0'};
int nread;
int fd = open(argv[1], O_RDONLY, 0);
while(nread = read(fd, buf, 512))
{
buf[nread] = '\0';
puts(buf);
}
return 0;
}
copy
9、 psinfo 的内容
进程的信息就来源于内核全局结构数组 struct task_struct * task[NR_TASKS] 中,具体读取细节可参照 sched.c 中的函数 schedule()。
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if (*p)
(*p)->counter = ((*p)->counter >> 1)+...;
copy
10、 hdinfo 的内容
硬盘总共有多少块,多少块空闲,有多少 inode 等信息都放在 super 块中,super 块可以通过 get_super() 函数获得。
struct super_block * sb;
sb = get_super(inode->i_dev);
struct buffer_head * bh;
total_blocks = sb->s_nzones;
for(i=0; is_zmap_blocks; i++)
{
bh = sb->s_zmap[i];
p=(char *)bh->b_data;
}
copy
五、实验结果分析
一次 read() 未必能读出所有的数据,需要继续 read(),直到把数据读空为止。而数次 read() 之间,进程的状态可能会发生变化。
六、实验心得
根据提示一步步的修改文件,最终才能成功运行,run成功额时候有成就感,下次我会做的更好。
学习时间 132分钟
操作时间 30分钟
按键次数 229次
实验次数 6次
报告字数 3188字
是否完成 完成