实验目的
在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很多,需要日后完善。