README
介绍
本项目为 2024年全国大学生计算机系统能力大赛 操作系统设计赛 东北区域赛 功能赛道 proj363题-在Linux0.11内核中实现proc文件系统 参赛源码,基于Linux0.11源码实现proc文件系统,本文最后部分有视频演示,视频位于根目录下doc目录中,或百度网盘: 通过网盘分享的文件:video.mp4 链接: https://pan.baidu.com/s/1eo3ei2LZ1r_v3w5DLbfBow?pwd=1111 提取码: 1111
题目要求
- 实现一个简单的proc文件系统,为proc文件系统添加一个psinfo节点。在Linux终端中执行命令cat /proc/psinfo,将内核空间中的进程信息写入用户空间,然后在终端中打印输出 Linux 0.11操作系统所有进程的信息。每行显示一个进程的信息,包括:进程ID(pid)、父进程ID(ppid)、剩余时间片数量(counter)、进程状态(state)、起始时间(start_time)。
提示:proc 文件系统的初始化工作应该在根文件系统被挂载之后开始,包括两个步骤:建立/proc目录和建立/proc 目录下的各个结点。因为在根文件系统加载后,初始化过程已经进入用户态,就不能调用sys_mkdir和sys_mknod函数建立目录和节点了,而必须调用mkdir和mknod系统调用函数来建立目录和结点。所以,必须实现mkdir和mknod两个系统调用函数的用户态接口。
- 为proc文件系统添加一个meminfo节点,在Linux终端中执行命令cat /proc/meminfo,将内核空间中的物理内存信息写入用户空间,然后在终端中可以打印输出 Linux 0.11的物理内存信息,每行一条信息,包括:物理内存分页数量、空闲页的数量、已使用页的数量。
- 为proc文件系统添加一个mmap节点,在Linux终端中执行命令cat /proc/mmap 可以打印输出Linux 0.11的二级页表映射的部分信息,每行一条信息,信息包括:页目录中前5个页目录项的值(使用十六进制表示),第二个页目录项映射的页表的前10个页表项的值(使用十六进制表示),前10个页表项映射的物理页对应的线性地址的值(使用十六进制表示)。
- 为proc文件系统添加一个tickinfo节点,在终端中执行命令cat /proc/tickinfo 可以打印输出Linux 0.11系统自启动以来的时钟滴答值(jiffies)。
- 为proc文件系统添加一个kmsg节点,在终端中执行命令cat /proc/kmsg可以打印输出内核启动过程中前5个进程的进程调度日志信息。为此,还需要参赛选手先设计一个进程调度日志记录功能,在内核启动的过程中将前5个进程的调度日志保存在内存中,每当一个进程的状态发生转换时就记录一条日志,记录的日志信息包括:进程ID,进程的新状态,时钟滴答值。其中,进程的新状态使用以下类别表示:New表示进程刚创建,Ready表示进程进入就绪态,Running表示进程进入运行态,Wait表示进程进入阻塞态,Exit表示进程退出。
实现思路
proc文件系统,它是一个虚拟文件系统,在Linux启动时就被挂接(mount)到了/proc目录上。proc通过虚拟文件和虚拟目录的方式提供访问系统参数的机会,所以有人称它为“了解系统信息的一个窗口”。这些虚拟的文件和目录并没有真实的存在于磁盘上,而是在内存中形成了一对Linux内核数据的直观表示,并且随着操作系统的运行自动建立、删除和更新。虽然是虚拟的,但它们都可以通过标准的文件系统调用来访问(包括read、write函数等) 。
proc目录下的节点都是特殊的proc文件,需要在/include/sys/stat.h中添加PROC文件类型。proc文件系统在Linux启动时就被挂接(mount)到了/proc目录上,所以需要在系统初始化时就创建proc文件系统,在/init/main.c的init()函数中使用系统调用创建proc目录和相应节点。cat命令会使用sys_read系统调用,可以在sys_read函数中判断打开的文件类型来决定后续操作。然后新建procfs.c文件处理读各节点的操作。
psinfo
psinfo节点需要输出进程信息,可以遍历task任务数组获取相关信息。
meminfo
meminfo节点需要输出物理内存信息,可以使用内存映射字节图mem_map获取相关信息。
mmap
mmap节点需要输出二级页表信息,可以使用内存页目录数组pg_dir获取相关信息。
tickinfo
tickinfo节点需要输出时钟滴答值,可以使用jiffies值。
kmsg
kmsg节点需要输出进程调度信息,需要先创建一个数据结构记录进程调度信息,然后在每次发生进程调度时记录进程调度信息。进程调度主要使用shedule函数进行,所以可以修改schedule函数记录进程调度信息。需要注意的是进程0的创建与其他进程不同,它不由fork函数创建,它的创建不会被schedule函数记录,所以需要在其创建的地方手动记录进我们的进程调度信息数据结构。
主要修改文件
fs/namei.c
fs/procfs.c
fs/read_write.c
include/sys/stat.h
init/main.c
kernal/sched.c
mm/memory.c
功能演示