mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
Patch procf (#90)
* 1234 * 123 * 合并master * procfs * 1 * procfs展示进程基本信息 * modified code * 恢复权限 * 恢复权限 #恢复权限 * modify permission * 删除run.sh * 解决第一次编译时磁盘镜像权限错误的问题 * 恢复.vscode/c_cpp_properties.json * 删除process.c中错误的do_fork * remake procfs * 修改一些变量名 * 修改类型 * modified * data_puts缓冲区溢出后return Co-authored-by: longjin <longjin@RinGoTek.cn>
This commit is contained in:
parent
ad23fcddf8
commit
27a97abd24
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@ -148,13 +148,18 @@
|
|||||||
"timer.h": "c",
|
"timer.h": "c",
|
||||||
"hid.h": "c",
|
"hid.h": "c",
|
||||||
"cfs.h": "c",
|
"cfs.h": "c",
|
||||||
|
"proc.h": "c",
|
||||||
|
"compiler.h": "c",
|
||||||
|
"hpet.h": "c",
|
||||||
|
"numa.h": "c",
|
||||||
|
"procfs.h": "c",
|
||||||
"err.h": "c",
|
"err.h": "c",
|
||||||
"rtc.h": "c",
|
"rtc.h": "c",
|
||||||
"list.h": "c",
|
"list.h": "c",
|
||||||
"compiler.h": "c",
|
|
||||||
"completion.h": "c",
|
"completion.h": "c",
|
||||||
"fat32.h": "c",
|
"fat32.h": "c",
|
||||||
"irqflags.h": "c"
|
"irqflags.h": "c",
|
||||||
|
"dirent.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "Enabled",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": "",
|
"esbonio.sphinx.confDir": "",
|
||||||
|
@ -253,14 +253,17 @@ static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size)
|
|||||||
* @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运
|
* @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
asm volatile("rep \n\t"
|
// todo:编译有bug
|
||||||
"movsq \n\t"
|
// asm volatile("rep \n\t"
|
||||||
"movq %3, %0 \n\t"
|
// "movsq \n\t"
|
||||||
"rep \n\t"
|
// "movq %3, %0 \n\t"
|
||||||
"movsb \n\t"
|
// "rep \n\t"
|
||||||
: "=&c"(size), "=&D"(tmp0), "=&S"(tmp1)
|
// "movsb \n\t"
|
||||||
: "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src)
|
// : "=&c"(size), "=&D"(tmp0), "=&S"(tmp1)
|
||||||
: "memory");
|
// : "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src)
|
||||||
|
// : "memory");
|
||||||
|
memcpy(dst,src,size);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <common/stddef.h>
|
#include <common/stddef.h>
|
||||||
|
|
||||||
#include <asm/asm.h>
|
#include <asm/asm.h>
|
||||||
|
#include <common/compiler.h>
|
||||||
|
|
||||||
//链表数据结构
|
//链表数据结构
|
||||||
struct List
|
struct List
|
||||||
|
@ -76,3 +76,12 @@ static inline int memcmp(const void *s1, const void *s2, size_t len)
|
|||||||
|
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 拼接两个字符串(将src接到dest末尾)
|
||||||
|
*
|
||||||
|
* @param dest 目标串
|
||||||
|
* @param src 源串
|
||||||
|
* @return char*
|
||||||
|
*/
|
||||||
|
char *strcat(char *dest, const char *src);
|
@ -3,7 +3,7 @@ CFLAGS += -I .
|
|||||||
|
|
||||||
|
|
||||||
kernel_fs_objs:= $(shell find ./*.c)
|
kernel_fs_objs:= $(shell find ./*.c)
|
||||||
kernel_fs_subdirs:= devfs VFS fat32 rootfs
|
kernel_fs_subdirs:= devfs VFS fat32 rootfs procfs
|
||||||
|
|
||||||
ECHO:
|
ECHO:
|
||||||
@echo "$@"
|
@echo "$@"
|
||||||
|
@ -173,7 +173,7 @@ struct vfs_dir_entry_t *vfs_path_walk(const char *path, uint64_t flags)
|
|||||||
|
|
||||||
memcpy(dentry->name, (void *)tmp_path, tmp_path_len);
|
memcpy(dentry->name, (void *)tmp_path, tmp_path_len);
|
||||||
dentry->name[tmp_path_len] = '\0';
|
dentry->name[tmp_path_len] = '\0';
|
||||||
// kdebug("tmp_path_len=%d, dentry->name= %s", tmp_path_len, dentry->name);
|
// kdebug("tmp_path_len=%d, dentry->name=%s", tmp_path_len, dentry->name);
|
||||||
dentry->name_length = tmp_path_len;
|
dentry->name_length = tmp_path_len;
|
||||||
|
|
||||||
if (parent->dir_inode->inode_ops->lookup(parent->dir_inode, dentry) == NULL)
|
if (parent->dir_inode->inode_ops->lookup(parent->dir_inode, dentry) == NULL)
|
||||||
@ -370,11 +370,16 @@ uint64_t sys_mkdir(struct pt_regs *regs)
|
|||||||
*
|
*
|
||||||
* @param filename 文件路径
|
* @param filename 文件路径
|
||||||
* @param flags 标志位
|
* @param flags 标志位
|
||||||
|
* @param from_user 是否由用户态调用,1为是,0为否
|
||||||
* @return uint64_t 错误码
|
* @return uint64_t 错误码
|
||||||
*/
|
*/
|
||||||
uint64_t do_open(const char *filename, int flags)
|
uint64_t do_open(const char *filename, int flags, bool from_user)
|
||||||
{
|
{
|
||||||
long path_len = strnlen_user(filename, PAGE_4K_SIZE) + 1;
|
long path_len = 0;
|
||||||
|
if (from_user)
|
||||||
|
path_len = strnlen_user(filename, PAGE_4K_SIZE) + 1;
|
||||||
|
else
|
||||||
|
path_len = strnlen(filename, PAGE_4K_SIZE) + 1;
|
||||||
|
|
||||||
if (path_len <= 0) // 地址空间错误
|
if (path_len <= 0) // 地址空间错误
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@ -386,7 +391,11 @@ uint64_t do_open(const char *filename, int flags)
|
|||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
strncpy_from_user(path, filename, path_len);
|
if (from_user)
|
||||||
|
strncpy_from_user(path, filename, path_len);
|
||||||
|
else
|
||||||
|
strncpy(path, filename, path_len);
|
||||||
|
|
||||||
// 去除末尾的 '/'
|
// 去除末尾的 '/'
|
||||||
if (path_len >= 2 && path[path_len - 2] == '/')
|
if (path_len >= 2 && path[path_len - 2] == '/')
|
||||||
{
|
{
|
||||||
@ -527,10 +536,33 @@ uint64_t sys_open(struct pt_regs *regs)
|
|||||||
{
|
{
|
||||||
char *filename = (char *)(regs->r8);
|
char *filename = (char *)(regs->r8);
|
||||||
int flags = (int)(regs->r9);
|
int flags = (int)(regs->r9);
|
||||||
|
return do_open(filename, flags, true);
|
||||||
return do_open(filename, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 关闭文件
|
||||||
|
*
|
||||||
|
* @param fd_num 文件描述符
|
||||||
|
* @return uint64_t 错误码
|
||||||
|
*/
|
||||||
|
uint64_t vfs_close(int fd_num)
|
||||||
|
{
|
||||||
|
// 校验文件描述符范围
|
||||||
|
if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM)
|
||||||
|
return -EBADF;
|
||||||
|
// 文件描述符不存在
|
||||||
|
if (current_pcb->fds[fd_num] == NULL)
|
||||||
|
return -EBADF;
|
||||||
|
struct vfs_file_t *file_ptr = current_pcb->fds[fd_num];
|
||||||
|
uint64_t ret;
|
||||||
|
// If there is a valid close function
|
||||||
|
if (file_ptr->file_ops && file_ptr->file_ops->close)
|
||||||
|
ret = file_ptr->file_ops->close(file_ptr->dEntry->dir_inode, file_ptr);
|
||||||
|
|
||||||
|
kfree(file_ptr);
|
||||||
|
current_pcb->fds[fd_num] = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief 动态分配dentry以及路径字符串名称
|
* @brief 动态分配dentry以及路径字符串名称
|
||||||
*
|
*
|
||||||
|
@ -164,7 +164,7 @@ struct vfs_inode_operations_t
|
|||||||
* @param inode 要被取消关联关系的目录项的【父目录项】
|
* @param inode 要被取消关联关系的目录项的【父目录项】
|
||||||
* @param dentry 要被取消关联关系的子目录项
|
* @param dentry 要被取消关联关系的子目录项
|
||||||
*/
|
*/
|
||||||
long (*unlink)(struct vfs_index_node_t * inode, struct vfs_dir_entry_t * dentry);
|
long (*unlink)(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dentry);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vfs_dir_entry_operations_t
|
struct vfs_dir_entry_operations_t
|
||||||
@ -249,14 +249,15 @@ struct vfs_dir_entry_t *vfs_alloc_dentry(const int name_size);
|
|||||||
*/
|
*/
|
||||||
struct vfs_index_node_t *vfs_alloc_inode();
|
struct vfs_index_node_t *vfs_alloc_inode();
|
||||||
|
|
||||||
|
uint64_t do_open(const char *filename, int flags, bool from_user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 打开文件
|
* @brief 关闭文件
|
||||||
*
|
*
|
||||||
* @param filename 文件路径
|
* @param fd_num 文件描述符
|
||||||
* @param flags 标志位
|
|
||||||
* @return uint64_t 错误码
|
* @return uint64_t 错误码
|
||||||
*/
|
*/
|
||||||
uint64_t do_open(const char *filename, int flags);
|
uint64_t vfs_close(int fd_num);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 创建文件夹
|
* @brief 创建文件夹
|
||||||
|
17
kernel/src/filesystem/procfs/Makefile
Normal file
17
kernel/src/filesystem/procfs/Makefile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
CFLAGS += -I .
|
||||||
|
|
||||||
|
|
||||||
|
kernel_fs_procfs_objs:= $(shell find ./*.c)
|
||||||
|
|
||||||
|
|
||||||
|
ECHO:
|
||||||
|
@echo "$@"
|
||||||
|
|
||||||
|
|
||||||
|
$(kernel_fs_procfs_objs): ECHO
|
||||||
|
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||||
|
|
||||||
|
|
||||||
|
all: $(kernel_fs_procfs_objs)
|
||||||
|
|
497
kernel/src/filesystem/procfs/procfs.c
Normal file
497
kernel/src/filesystem/procfs/procfs.c
Normal file
@ -0,0 +1,497 @@
|
|||||||
|
#include "procfs.h"
|
||||||
|
|
||||||
|
//定义文件类型
|
||||||
|
#define PROC_STATUS 1
|
||||||
|
|
||||||
|
//定义buffer大小
|
||||||
|
#define FDATA_RBUF_SIZE 1024
|
||||||
|
|
||||||
|
struct vfs_super_block_operations_t procfs_sb_ops;
|
||||||
|
struct vfs_dir_entry_operations_t procfs_dentry_ops;
|
||||||
|
struct vfs_file_operations_t procfs_file_ops;
|
||||||
|
struct vfs_inode_operations_t procfs_inode_ops;
|
||||||
|
|
||||||
|
struct vfs_superblock_t procfs_sb = {0};
|
||||||
|
struct vfs_dir_entry_t *procfs_root_dentry; // 根结点的dentry
|
||||||
|
static spinlock_t procfs_global_lock; // procfs的全局锁
|
||||||
|
const char __procfs_mount_path[] = "/proc"; // 挂在路径
|
||||||
|
|
||||||
|
static int64_t proc_create_file(const char *path, mode_t type, long pid);
|
||||||
|
static int __check_name_available(const char *name, int namelen, int8_t reserved);
|
||||||
|
static long simple_procfs_read(void *to, int64_t count, long *position, void *from, int64_t available);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 文件的私有信息结构
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct procfs_file_private_data
|
||||||
|
{
|
||||||
|
int readlen;
|
||||||
|
char *rbuffer;
|
||||||
|
int writelen;
|
||||||
|
char *wbuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建procfs的super block
|
||||||
|
*
|
||||||
|
* @param blk 未使用(procfs为伪文件系统,不需要物理设备)
|
||||||
|
* @return struct vfs_superblock_t*
|
||||||
|
*/
|
||||||
|
struct vfs_superblock_t *procfs_read_superblock(struct block_device *blk)
|
||||||
|
{
|
||||||
|
procfs_sb.blk_device = NULL;
|
||||||
|
procfs_sb.root = procfs_root_dentry;
|
||||||
|
procfs_sb.sb_ops = &procfs_sb_ops;
|
||||||
|
procfs_sb.dir_ops = &procfs_dentry_ops;
|
||||||
|
procfs_sb.private_sb_info = NULL;
|
||||||
|
kdebug("procfs read superblock done");
|
||||||
|
return &procfs_sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void procfs_write_superblock(struct vfs_superblock_t *sb)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
static void procfs_put_superblock(struct vfs_superblock_t *sb)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
static void procfs_write_inode(struct vfs_index_node_t *inode)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct vfs_super_block_operations_t procfs_sb_ops = {
|
||||||
|
.write_superblock = &procfs_write_superblock,
|
||||||
|
.put_superblock = &procfs_put_superblock,
|
||||||
|
.write_inode = &procfs_write_inode,
|
||||||
|
};
|
||||||
|
|
||||||
|
static long procfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static long procfs_hash(struct vfs_dir_entry_t *dEntry, char *filename)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static long procfs_release(struct vfs_dir_entry_t *dEntry)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static long procfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
struct vfs_dir_entry_operations_t procfs_dentry_ops = {
|
||||||
|
.compare = &procfs_compare,
|
||||||
|
.hash = &procfs_hash,
|
||||||
|
.release = &procfs_release,
|
||||||
|
.iput = &procfs_iput,
|
||||||
|
};
|
||||||
|
|
||||||
|
void data_puts(struct procfs_file_private_data *fdata, const char *s)
|
||||||
|
{
|
||||||
|
int len = strlen(s);
|
||||||
|
if(fdata->readlen+len > FDATA_RBUF_SIZE)
|
||||||
|
{
|
||||||
|
kerror("out of buffer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strncpy(fdata->rbuffer + fdata->readlen, s, len);
|
||||||
|
fdata->readlen += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long procfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
|
||||||
|
{
|
||||||
|
if (inode->attribute & VFS_IF_DIR)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
struct procfs_inode_info_t *finode = inode->private_inode_info;
|
||||||
|
if (finode == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// kdebug("finode=%#018lx", finode);
|
||||||
|
struct procfs_file_private_data *fdata = kzalloc(sizeof(struct procfs_file_private_data), 0);
|
||||||
|
struct process_control_block *pcb_t = process_find_pcb_by_pid(finode->pid);
|
||||||
|
//判断文件类型
|
||||||
|
int mode = finode->type;
|
||||||
|
fdata->rbuffer = kzalloc(FDATA_RBUF_SIZE, 0);
|
||||||
|
int len = 0;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
data_puts(fdata, "Name:");
|
||||||
|
data_puts(fdata, pcb_t->name);
|
||||||
|
data_puts(fdata, "\nstate:");
|
||||||
|
data_puts(fdata, ltoa(pcb_t->state));
|
||||||
|
data_puts(fdata, "\npid:");
|
||||||
|
data_puts(fdata, ltoa(pcb_t->pid));
|
||||||
|
data_puts(fdata, "\nPpid:");
|
||||||
|
data_puts(fdata, ltoa(pcb_t->parent_pcb->pid));
|
||||||
|
data_puts(fdata, "\ncpu_id:");
|
||||||
|
data_puts(fdata, ltoa(pcb_t->cpu_id));
|
||||||
|
data_puts(fdata, "\npriority:");
|
||||||
|
data_puts(fdata, ltoa(pcb_t->priority));
|
||||||
|
// data_puts(fdata,"\n");
|
||||||
|
|
||||||
|
uint64_t hiwater_vm, text, data;
|
||||||
|
hiwater_vm = pcb_t->mm->vmas->vm_end - pcb_t->mm->vmas->vm_start;
|
||||||
|
text = pcb_t->mm->code_addr_end - pcb_t->mm->code_addr_start;
|
||||||
|
data = pcb_t->mm->data_addr_end - pcb_t->mm->data_addr_start;
|
||||||
|
|
||||||
|
data_puts(fdata, "\nVmPeak:");
|
||||||
|
data_puts(fdata, ltoa(hiwater_vm));
|
||||||
|
data_puts(fdata, " kB");
|
||||||
|
data_puts(fdata, "\nVmData:");
|
||||||
|
data_puts(fdata, ltoa(data));
|
||||||
|
data_puts(fdata, " kB");
|
||||||
|
data_puts(fdata, "\nVmExe:");
|
||||||
|
data_puts(fdata, ltoa(text));
|
||||||
|
data_puts(fdata, " kB\n");
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
inode->file_size = fdata->readlen;
|
||||||
|
file_ptr->private_data = fdata;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static long procfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static long procfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position)
|
||||||
|
{
|
||||||
|
// 获取私有信息
|
||||||
|
struct procfs_file_private_data *priv = (struct procfs_file_private_data *)file_ptr->private_data;
|
||||||
|
// kdebug("priv=%#018lx", priv);
|
||||||
|
if (!priv->rbuffer)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return simple_procfs_read(buf, count, position, priv->rbuffer, priv->readlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查读取并将数据从内核拷贝到用户
|
||||||
|
*
|
||||||
|
* @param to: 要读取的用户空间缓冲区
|
||||||
|
* @param count: 要读取的最大字节数
|
||||||
|
* @param position: 缓冲区中的当前位置
|
||||||
|
* @param from: 要读取的缓冲区
|
||||||
|
* @param available: 读取的缓冲区大小
|
||||||
|
*
|
||||||
|
* @return long 读取字节数
|
||||||
|
*/
|
||||||
|
static long simple_procfs_read(void *to, int64_t count, long *position, void *from, int64_t available)
|
||||||
|
{
|
||||||
|
long pos = *position;
|
||||||
|
// kdebug("pos:%ld",pos);
|
||||||
|
// kdebug("count:%ld",count);
|
||||||
|
// kdebug("available:%ld",available);
|
||||||
|
int64_t ret = 0;
|
||||||
|
|
||||||
|
if (pos < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
if (pos >= available || !count)
|
||||||
|
return 0;
|
||||||
|
if (count > available - pos)
|
||||||
|
count = available - pos;
|
||||||
|
// kdebug("count:%d",count);
|
||||||
|
ret = copy_to_user(to, from + pos, count);
|
||||||
|
|
||||||
|
*position = pos + ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long procfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief 调整文件的访问位置
|
||||||
|
*
|
||||||
|
* @param file_ptr 文件描述符号
|
||||||
|
* @param offset 偏移量
|
||||||
|
* @param whence 调整模式
|
||||||
|
* @return uint64_t 调整结束后的文件访问位置
|
||||||
|
*/
|
||||||
|
static long procfs_lseek(struct vfs_file_t *file_ptr, long offset, long whence)
|
||||||
|
{
|
||||||
|
struct vfs_index_node_t *inode = file_ptr->dEntry->dir_inode;
|
||||||
|
|
||||||
|
long pos = 0;
|
||||||
|
switch (whence)
|
||||||
|
{
|
||||||
|
case SEEK_SET: // 相对于文件头
|
||||||
|
pos = offset;
|
||||||
|
break;
|
||||||
|
case SEEK_CUR: // 相对于当前位置
|
||||||
|
pos = file_ptr->position + offset;
|
||||||
|
break;
|
||||||
|
case SEEK_END: // 相对于文件末尾
|
||||||
|
pos = file_ptr->dEntry->dir_inode->file_size + offset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos < 0 || pos > file_ptr->dEntry->dir_inode->file_size)
|
||||||
|
return -EOVERFLOW;
|
||||||
|
file_ptr->position = pos;
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
static long procfs_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 读取该目录下的目录项
|
||||||
|
*
|
||||||
|
* @param file_ptr 文件结构体的指针
|
||||||
|
* @param dirent 返回的dirent
|
||||||
|
* @param filler 填充dirent的函数
|
||||||
|
*
|
||||||
|
* @return long 错误码
|
||||||
|
*/
|
||||||
|
static long procfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler)
|
||||||
|
{
|
||||||
|
struct vfs_dir_entry_t *dentry = file_ptr->dEntry;
|
||||||
|
struct List *list = &dentry->subdirs_list;
|
||||||
|
// 先切换到position处
|
||||||
|
for (int i = 0; i <= file_ptr->position; ++i)
|
||||||
|
{
|
||||||
|
list = list_next(list);
|
||||||
|
if (list == &dentry->subdirs_list) // 找完了
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 若存在目录项,则增加偏移量
|
||||||
|
++file_ptr->position;
|
||||||
|
// 获取目标dentry(由于是子目录项,因此是child_node_list)
|
||||||
|
struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list);
|
||||||
|
|
||||||
|
char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
|
||||||
|
strncpy(name, target_dent->name, target_dent->name_length);
|
||||||
|
uint32_t dentry_type;
|
||||||
|
if (target_dent->dir_inode->attribute & VFS_IF_DIR)
|
||||||
|
dentry_type = VFS_IF_DIR;
|
||||||
|
|
||||||
|
return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1);
|
||||||
|
failed:;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vfs_file_operations_t procfs_file_ops = {
|
||||||
|
.open = &procfs_open,
|
||||||
|
.close = &procfs_close,
|
||||||
|
.read = &procfs_read,
|
||||||
|
.write = &procfs_write,
|
||||||
|
.lseek = &procfs_lseek,
|
||||||
|
.ioctl = &procfs_ioctl,
|
||||||
|
.readdir = &procfs_readdir,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查文件名是否合法
|
||||||
|
*
|
||||||
|
* @param name 文件名
|
||||||
|
* @param namelen 文件名长度
|
||||||
|
* @param reserved 保留字段
|
||||||
|
* @return int 合法:0, 其他:错误码
|
||||||
|
*/
|
||||||
|
static int __check_name_available(const char *name, int namelen, int8_t reserved)
|
||||||
|
{
|
||||||
|
if (namelen > 255 || namelen <= 0)
|
||||||
|
return -ENAMETOOLONG;
|
||||||
|
// 首个字符不能是空格或者'.'
|
||||||
|
if (name[0] == 0x20 || name[0] == '.')
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 在procfs中创建文件
|
||||||
|
*
|
||||||
|
* @param parent_inode 父目录的inode
|
||||||
|
* @param dest_dEntry 目标dentry
|
||||||
|
* @param mode 创建模式
|
||||||
|
* @return long 错误码
|
||||||
|
*/
|
||||||
|
static long procfs_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode)
|
||||||
|
{
|
||||||
|
int64_t retval = 0;
|
||||||
|
|
||||||
|
//检验名称和法性
|
||||||
|
retval = __check_name_available(dest_dEntry->name, dest_dEntry->name_length, 0);
|
||||||
|
if (retval != 0)
|
||||||
|
return retval;
|
||||||
|
if (dest_dEntry->dir_inode != NULL)
|
||||||
|
return -EEXIST;
|
||||||
|
|
||||||
|
struct vfs_index_node_t *inode = vfs_alloc_inode();
|
||||||
|
dest_dEntry->dir_inode = inode;
|
||||||
|
dest_dEntry->dir_ops = &procfs_dentry_ops;
|
||||||
|
|
||||||
|
inode->attribute = VFS_IF_FILE;
|
||||||
|
inode->file_ops = &procfs_file_ops;
|
||||||
|
inode->file_size = 0;
|
||||||
|
inode->sb = parent_inode->sb;
|
||||||
|
inode->inode_ops = &procfs_inode_ops;
|
||||||
|
// kdebug("finode:%#018lx",inode->private_inode_info);
|
||||||
|
inode->blocks = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static struct vfs_dir_entry_t *procfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 在procfs中创建文件夹(作用是完善子文件夹的inode信息)
|
||||||
|
*
|
||||||
|
* @param inode 父目录的inode
|
||||||
|
* @param dEntry 目标dentry
|
||||||
|
* @param mode 创建模式
|
||||||
|
* @return long 错误码
|
||||||
|
*/
|
||||||
|
static long procfs_mkdir(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dEntry, int mode)
|
||||||
|
{
|
||||||
|
int64_t retval = 0;
|
||||||
|
|
||||||
|
//检验名称和法性
|
||||||
|
retval = __check_name_available(dEntry->name, dEntry->name_length, 0);
|
||||||
|
if (retval != 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
struct vfs_index_node_t *inode = vfs_alloc_inode();
|
||||||
|
dEntry->dir_inode = inode;
|
||||||
|
dEntry->dir_ops = &procfs_dentry_ops;
|
||||||
|
|
||||||
|
//结点信息初始化
|
||||||
|
struct procfs_inode_info_t *finode = (struct procfs_inode_info_t *)kzalloc(sizeof(struct procfs_inode_info_t), 0);
|
||||||
|
finode->pid = 0;
|
||||||
|
finode->type = 0;
|
||||||
|
|
||||||
|
inode->attribute = VFS_IF_DIR;
|
||||||
|
inode->file_ops = &procfs_file_ops;
|
||||||
|
inode->file_size = 0;
|
||||||
|
inode->sb = parent_inode->sb;
|
||||||
|
inode->inode_ops = &procfs_inode_ops;
|
||||||
|
inode->private_inode_info = (void *)finode;
|
||||||
|
// kdebug("inode->private_inode_info=%#018lx", inode->private_inode_info);
|
||||||
|
inode->blocks = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
struct vfs_inode_operations_t procfs_inode_ops = {
|
||||||
|
.create = &procfs_create,
|
||||||
|
.lookup = &procfs_lookup,
|
||||||
|
.mkdir = &procfs_mkdir,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vfs_filesystem_type_t procfs_fs_type = {
|
||||||
|
.name = "procfs",
|
||||||
|
.fs_flags = 0,
|
||||||
|
.read_superblock = procfs_read_superblock,
|
||||||
|
.next = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __always_inline void __procfs_init_root_inode()
|
||||||
|
{
|
||||||
|
procfs_root_dentry->dir_inode = vfs_alloc_inode();
|
||||||
|
procfs_root_dentry->dir_inode->file_ops = &procfs_file_ops;
|
||||||
|
procfs_root_dentry->dir_inode->inode_ops = &procfs_inode_ops;
|
||||||
|
|
||||||
|
procfs_root_dentry->dir_inode->private_inode_info = NULL;
|
||||||
|
procfs_root_dentry->dir_inode->sb = &procfs_sb;
|
||||||
|
procfs_root_dentry->dir_inode->attribute = VFS_IF_DIR;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief 初始化procfs的根dentry
|
||||||
|
*/
|
||||||
|
static __always_inline void __procfs_init_root_dentry()
|
||||||
|
{
|
||||||
|
procfs_root_dentry = vfs_alloc_dentry(0);
|
||||||
|
procfs_root_dentry->dir_ops = &procfs_dentry_ops;
|
||||||
|
|
||||||
|
__procfs_init_root_inode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建进程对应文件夹
|
||||||
|
*
|
||||||
|
* @param pid 进程号
|
||||||
|
* @return int64_t 错误码
|
||||||
|
*/
|
||||||
|
int64_t procfs_register_pid(long pid)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
//创建文件夹
|
||||||
|
char tmp[70] = {0};
|
||||||
|
int len = strlen(ltoa(pid));
|
||||||
|
// kdebug("len:%d",len);
|
||||||
|
strcpy(tmp, "/proc/");
|
||||||
|
strcpy(tmp + 6, ltoa(pid));
|
||||||
|
// kdebug("tmp:%s",tmp);
|
||||||
|
retval = vfs_mkdir(tmp, 0, false);
|
||||||
|
|
||||||
|
// kdebug("aaaaaaaaaaaaaaa");
|
||||||
|
//创建各相关文件
|
||||||
|
strcpy(tmp + 6 + len, "/status");
|
||||||
|
// kdebug("tmp:%s",tmp);
|
||||||
|
retval = proc_create_file(tmp, PROC_STATUS, pid);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建文件
|
||||||
|
*
|
||||||
|
* @param path 文件夹路径
|
||||||
|
* @param type 文件类型
|
||||||
|
* @param pid pid
|
||||||
|
* @return int64_t 错误码
|
||||||
|
*/
|
||||||
|
static int64_t proc_create_file(const char *path, mode_t type, long pid)
|
||||||
|
{
|
||||||
|
kdebug("procfs: Creating: %s", path);
|
||||||
|
int ret = do_open(path, O_CREAT, false);
|
||||||
|
// kdebug("ret:%d", ret);
|
||||||
|
struct vfs_dir_entry_t *dentry = vfs_path_walk(path, 0);
|
||||||
|
// kdebug("dentry=%#018lx", dentry);
|
||||||
|
|
||||||
|
//结点信息配置
|
||||||
|
struct procfs_inode_info_t *finode = (struct procfs_inode_info_t *)kzalloc(sizeof(struct procfs_inode_info_t), 0);
|
||||||
|
finode->pid = pid;
|
||||||
|
// kdebug("pid:%d",finode->pid);
|
||||||
|
finode->type = type;
|
||||||
|
dentry->dir_inode->private_inode_info = (void *)finode;
|
||||||
|
ret = vfs_close(ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化procfs
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void procfs_init()
|
||||||
|
{
|
||||||
|
__procfs_init_root_dentry();
|
||||||
|
vfs_register_filesystem(&procfs_fs_type);
|
||||||
|
spin_init(&procfs_global_lock);
|
||||||
|
vfs_mount_fs(__procfs_mount_path, "procfs", NULL);
|
||||||
|
}
|
43
kernel/src/filesystem/procfs/procfs.h
Normal file
43
kernel/src/filesystem/procfs/procfs.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <common/list.h>
|
||||||
|
#include <common/lockref.h>
|
||||||
|
#include <common/spinlock.h>
|
||||||
|
#include <common/stdio.h>
|
||||||
|
#include <common/stdlib.h>
|
||||||
|
#include <common/string.h>
|
||||||
|
#include <filesystem/VFS/VFS.h>
|
||||||
|
#include <process/process.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化procfs
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void procfs_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief proc文件系统的超级块信息结构体
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct procfs_sb_info_t
|
||||||
|
{
|
||||||
|
struct lockref lockref; //该lockref包含自旋锁以及引用计数
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief procfs文件系统的结点私有信息
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct procfs_inode_info_t
|
||||||
|
{
|
||||||
|
long pid;
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建进程对应文件
|
||||||
|
*
|
||||||
|
* @param pid 进程号
|
||||||
|
* @return int64_t 错误码
|
||||||
|
*/
|
||||||
|
int64_t procfs_register_pid(long pid);
|
@ -160,6 +160,10 @@ void rootfs_init()
|
|||||||
// 创建/dev等目录的dentry(以便文件系统的mount)
|
// 创建/dev等目录的dentry(以便文件系统的mount)
|
||||||
if (rootfs_add_dir("dev") != 0)
|
if (rootfs_add_dir("dev") != 0)
|
||||||
kerror("create dir 'dev' in rootfs failed");
|
kerror("create dir 'dev' in rootfs failed");
|
||||||
|
|
||||||
|
// 创建/procfs目录的dentry
|
||||||
|
if (rootfs_add_dir("proc") != 0)
|
||||||
|
kerror("create dir 'proc' in rootfs failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,3 +107,15 @@ long strnlen_user(const char *src, unsigned long maxlen)
|
|||||||
return size <= maxlen ? size : maxlen;
|
return size <= maxlen ? size : maxlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 拼接两个字符串(将src接到dest末尾)
|
||||||
|
*
|
||||||
|
* @param dest 目标串
|
||||||
|
* @param src 源串
|
||||||
|
* @return char*
|
||||||
|
*/
|
||||||
|
char *strcat(char *dest, const char *src)
|
||||||
|
{
|
||||||
|
strcpy(dest + strlen(dest), src);
|
||||||
|
return dest;
|
||||||
|
}
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <filesystem/VFS/VFS.h>
|
#include <filesystem/VFS/VFS.h>
|
||||||
#include <filesystem/devfs/devfs.h>
|
#include <filesystem/devfs/devfs.h>
|
||||||
|
#include <filesystem/procfs/procfs.h>
|
||||||
#include <filesystem/fat32/fat32.h>
|
#include <filesystem/fat32/fat32.h>
|
||||||
|
|
||||||
#include "driver/acpi/acpi.h"
|
#include "driver/acpi/acpi.h"
|
||||||
@ -142,6 +143,8 @@ void system_initialize()
|
|||||||
|
|
||||||
vfs_init();
|
vfs_init();
|
||||||
devfs_init();
|
devfs_init();
|
||||||
|
procfs_init();
|
||||||
|
|
||||||
cpu_init();
|
cpu_init();
|
||||||
ps2_keyboard_init();
|
ps2_keyboard_init();
|
||||||
tty_init();
|
tty_init();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <common/err.h>
|
#include <common/err.h>
|
||||||
#include <common/kthread.h>
|
#include <common/kthread.h>
|
||||||
#include <common/spinlock.h>
|
#include <common/spinlock.h>
|
||||||
|
#include <filesystem/procfs/procfs.h>
|
||||||
|
|
||||||
extern spinlock_t process_global_pid_write_lock;
|
extern spinlock_t process_global_pid_write_lock;
|
||||||
extern long process_global_pid;
|
extern long process_global_pid;
|
||||||
@ -135,6 +136,9 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
// 唤醒进程
|
// 唤醒进程
|
||||||
process_wakeup(tsk);
|
process_wakeup(tsk);
|
||||||
|
|
||||||
|
//创建对应procfs文件
|
||||||
|
procfs_register_pid(tsk->pid);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
copy_thread_failed:;
|
copy_thread_failed:;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <filesystem/devfs/devfs.h>
|
#include <filesystem/devfs/devfs.h>
|
||||||
#include <filesystem/fat32/fat32.h>
|
#include <filesystem/fat32/fat32.h>
|
||||||
#include <filesystem/rootfs/rootfs.h>
|
#include <filesystem/rootfs/rootfs.h>
|
||||||
|
#include <filesystem/procfs/procfs.h>
|
||||||
#include <ktest/ktest.h>
|
#include <ktest/ktest.h>
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
#include <sched/sched.h>
|
#include <sched/sched.h>
|
||||||
|
@ -135,21 +135,7 @@ uint64_t sys_close(struct pt_regs *regs)
|
|||||||
int fd_num = (int)regs->r8;
|
int fd_num = (int)regs->r8;
|
||||||
|
|
||||||
// kdebug("sys close: fd=%d", fd_num);
|
// kdebug("sys close: fd=%d", fd_num);
|
||||||
// 校验文件描述符范围
|
return vfs_close(fd_num);
|
||||||
if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM)
|
|
||||||
return -EBADF;
|
|
||||||
// 文件描述符不存在
|
|
||||||
if (current_pcb->fds[fd_num] == NULL)
|
|
||||||
return -EBADF;
|
|
||||||
struct vfs_file_t *file_ptr = current_pcb->fds[fd_num];
|
|
||||||
uint64_t ret;
|
|
||||||
// If there is a valid close function
|
|
||||||
if (file_ptr->file_ops && file_ptr->file_ops->close)
|
|
||||||
ret = file_ptr->file_ops->close(file_ptr->dEntry->dir_inode, file_ptr);
|
|
||||||
|
|
||||||
kfree(file_ptr);
|
|
||||||
current_pcb->fds[fd_num] = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,4 +22,5 @@ sudo losetup -d ${LOOP_DEVICE}
|
|||||||
|
|
||||||
echo "Successfully created disk image."
|
echo "Successfully created disk image."
|
||||||
mkdir -p ../bin
|
mkdir -p ../bin
|
||||||
|
chmod 777 disk.img
|
||||||
mv ./disk.img ../bin/
|
mv ./disk.img ../bin/
|
||||||
|
@ -23,7 +23,7 @@ bins[0]=${kernel}
|
|||||||
for file in ${bins[*]};do
|
for file in ${bins[*]};do
|
||||||
if [ ! -x $file ]; then
|
if [ ! -x $file ]; then
|
||||||
echo "$file 不存在!"
|
echo "$file 不存在!"
|
||||||
exit
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ fi
|
|||||||
# 判断是否存在硬盘镜像文件,如果不存在,就创建一个(docker模式下,由于镜像中缺少qemu-img不会创建)
|
# 判断是否存在硬盘镜像文件,如果不存在,就创建一个(docker模式下,由于镜像中缺少qemu-img不会创建)
|
||||||
if [ ! -f "${root_folder}/bin/disk.img" ]; then
|
if [ ! -f "${root_folder}/bin/disk.img" ]; then
|
||||||
echo "创建硬盘镜像文件..."
|
echo "创建硬盘镜像文件..."
|
||||||
sudo bash ./create_hdd_image.sh
|
sudo bash ./create_hdd_image.sh || exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p ${root_folder}/bin/disk_mount
|
mkdir -p ${root_folder}/bin/disk_mount
|
||||||
@ -53,6 +53,7 @@ cp ${kernel} ${root_folder}/bin/disk_mount/boot
|
|||||||
# 拷贝用户程序到磁盘镜像
|
# 拷贝用户程序到磁盘镜像
|
||||||
mkdir -p ${root_folder}/bin/disk_mount/bin
|
mkdir -p ${root_folder}/bin/disk_mount/bin
|
||||||
mkdir -p ${root_folder}/bin/disk_mount/dev
|
mkdir -p ${root_folder}/bin/disk_mount/dev
|
||||||
|
mkdir -p ${root_folder}/bin/disk_mount/proc
|
||||||
|
|
||||||
cp -r ${root_folder}/bin/user/* ${root_folder}/bin/disk_mount/bin
|
cp -r ${root_folder}/bin/user/* ${root_folder}/bin/disk_mount/bin
|
||||||
touch ${root_folder}/bin/disk_mount/dev/keyboard.dev
|
touch ${root_folder}/bin/disk_mount/dev/keyboard.dev
|
||||||
|
@ -312,7 +312,6 @@ int shell_cmd_cat(int argc, char **argv)
|
|||||||
file_size -= l;
|
file_size -= l;
|
||||||
printf("%s", buf);
|
printf("%s", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
free(buf);
|
free(buf);
|
||||||
free(file_path);
|
free(file_path);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user