操作系统之建立proc文件系统实验

实验目的

在linux-0.11内核中添加proc文件系统

实验过程

编写文件

// oslab/linux-0.11/fs/namei.c
@ -441,7 +441,7 @@ int sys_mknod(const char * filename, int mode, int dev)
 		return -ENOSPC;
 	}
 	inode->i_mode = mode;
-	if (S_ISBLK(mode) || S_ISCHR(mode))
+	if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISPROC(mode))
 		inode->i_zone[0] = dev;
 	inode->i_mtime = inode->i_atime = CURRENT_TIME;
 	inode->i_dirt = 1;
//oslab/linux-0.11/include/sys/stat.h
@@ -27,6 +27,10 @@ struct stat {
 #define S_ISGID  0002000
 #define S_ISVTX  0001000
 
+/* add proc */
+#define S_IFPROC 0050000
+#define S_ISPROC(m)	(((m) & S_IFMT) == S_IFPROC)
+
 #define S_ISREG(m)	(((m) & S_IFMT) == S_IFREG)
 #define S_ISDIR(m)	(((m) & S_IFMT) == S_IFDIR)
 #define S_ISCHR(m)	(((m) & S_IFMT) == S_IFCHR)
// oslab/linux-0.11/init/main.c
@@ -3,7 +3,6 @@
  *
  *  (C) 1991  Linus Torvalds
  */
-
 #define __LIBRARY__
 #include <unistd.h>
 #include <time.h>
@@ -36,6 +35,7 @@ static inline _syscall0(int,sync)
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 
 #include <linux/fs.h>
 
@@ -147,7 +147,7 @@ void main(void)		/* This really IS void, no error here. */
  */
 	for(;;) pause();
 }
-
+stat
 static int printf(const char *fmt, ...)
 {
 	va_list args;
@@ -164,7 +164,8 @@ static char * envp_rc[] = { "HOME=/", NULL };
 
 static char * argv[] = { "-/bin/sh",NULL };
 static char * envp[] = { "HOME=/usr/root", NULL };
-
+// extern int mkdir(const char *_path, mode_t mode);
+// extern int mknod(const char * filename, mode_t mode, dev_t dev);
 void init(void)
 {
 	int pid,i;
@@ -176,6 +177,12 @@ void init(void)
 	printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,
 		NR_BUFFERS*BLOCK_SIZE);
 	printf("Free mem: %d bytes\n\r",memory_end-main_memory_start);
+	
+	/* create the proc dir */
+	mkdir("/proc", 0755);
+	/* create the psinfo inode */
+	mknod("/proc/psinfo", (S_IFPROC | 0444), 0);
+
 	if (!(pid=fork())) {
 		close(0);
 		if (open("/etc/rc",O_RDONLY,0))
// oslab/linux-0.11/fs/read_write.c
@@ -22,6 +22,8 @@ extern int file_read(struct m_inode * inode, struct file * filp,
 extern int file_write(struct m_inode * inode, struct file * filp,
 		char * buf, int count);
 
+extern int proc_read(int dev, off_t * pos, char * buf, int count);
+
 int sys_lseek(unsigned int fd,off_t offset, int origin)
 {
 	struct file * file;
@@ -76,6 +78,13 @@ int sys_read(unsigned int fd,char * buf,int count)
 			return 0;
 		return file_read(inode,file,buf,count);
 	}
+	
+	// read the proc inode
+	if (S_ISPROC(inode->i_mode))
+	{
+		return proc_read(inode->i_zone[0], &file->f_pos, buf, count);
+	}
+
 	printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);
 	return -EINVAL;
 }
/*
 * =====================================================================================
 *
 *       Filename:  proc.c
 *
 *    Description:  achieve the function of reading the proc inode.  
 *
 *        Version:  1.0
 *        Created:  2019年04月16日 22时24分53秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (duan zhonghuan), 
 *   Organization:  
 *
 * =====================================================================================
 */
#include <sys/types.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <stdarg.h>
#include <asm/segment.h>

#define PS_DEV    (0)
#define HD_DEV    (1)

extern int vsprintf(char *buf, const char *fmt, va_list args);

static 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;
}

char* psinfo = 0;
char *hdinfo = 0;

static int update_psinfo(off_t * pos, char * buf, int count)
{
	struct task_struct **p = 0;
	int offset = 0;
	int i = 0;
	static int flag = 0;
	if (psinfo == 0)
	{
		psinfo = malloc(512);
	}
	offset = sprintf(psinfo + offset, "pid state father counter start_time\n");
	for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
	{
		if (*p == 0)
	   	{
			continue;
		}
		if (offset > 512 - 20)
		{
			break;
		}
		offset += sprintf(psinfo + offset, "%ld %ld %ld %ld %ld \n",
			   	(*p)->pid, (*p)->state, (*p)->father,
			   	(*p)->counter, (*p)->start_time); 
	}
	// copy the data to user space
	for (i = 0; i < offset; i++)
	{
		put_fs_byte(psinfo[i], buf+i);
	}
	if (flag == 0)
	{
		flag = 1;
		return offset;
	}
	flag = 0;
	free(psinfo);
	psinfo = 0;
	return 0;
}

int proc_read(int dev, off_t * pos, char * buf, int count)
{
	// read current ps info
	if (dev == PS_DEV)
	{
		return update_psinfo(pos, buf, count);
	}
	
	int offset = 0;
	int i = 0;
	static int flag = 0;
	// read current hd info
	if (dev == HD_DEV)
	{
		if (flag == 1)
		{
			flag = 0;
			return 0;
		}
		struct super_block *s = 0;
		s = get_super(dev);
		hdinfo = malloc(512);
		offset += sprintf(hdinfo + offset, "s_ninodes:         %d;\n", s->s_ninodes);
		offset += sprintf(hdinfo + offset, "s_nzones:          %d;\n", s->s_nzones);
		offset += sprintf(hdinfo + offset, "s_imap_blocks:     %d;\n", s->s_imap_blocks);
		offset += sprintf(hdinfo + offset, "s_zmap_blocks:     %d;\n", s->s_zmap_blocks);
		
		// copy the data to user space
		for (i = 0; i < offset; i++)
		{
			put_fs_byte(hdinfo[i], buf+i);
		}
		free(hdinfo);
		hdinfo = 0;
		flag = 1;
		return offset;
	}

	return 0;
}

实验结果

在这里插入图片描述

总结

这里只是验证添加proc文件系统,,里面的bug很多,需要日后完善。

猜你喜欢

转载自blog.csdn.net/m0_38099380/article/details/89368549