Merge branch 'devfs'

This commit is contained in:
fslongjin 2022-09-10 00:19:10 +08:00
commit 774ebf0763
17 changed files with 415 additions and 76 deletions

9
kernel/common/stdlib.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
/**
* @brief
*
* @param input
* @return const char*
*/
const char* ltoa(long input);

View File

@ -160,7 +160,7 @@ void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code)
{ {
kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
traceback(regs);
current_pcb->state = PROC_STOPPED; current_pcb->state = PROC_STOPPED;
sched(); sched();
} }

View File

@ -16,6 +16,8 @@ extern struct vfs_file_operations_t ps2_keyboard_fops;
static struct vfs_filesystem_type_t vfs_fs = {"filesystem", 0}; static struct vfs_filesystem_type_t vfs_fs = {"filesystem", 0};
struct vfs_superblock_t *vfs_root_sb = NULL; struct vfs_superblock_t *vfs_root_sb = NULL;
struct vfs_dir_entry_t *vfs_alloc_dentry(const int name_size);
/** /**
* @brief * @brief
* *
@ -166,11 +168,7 @@ struct vfs_dir_entry_t *vfs_path_walk(const char *path, uint64_t flags)
// 如果没有找到dentry缓存则申请新的dentry // 如果没有找到dentry缓存则申请新的dentry
if (dentry == NULL) if (dentry == NULL)
{ {
dentry = (struct vfs_dir_entry_t *)kzalloc(sizeof(struct vfs_dir_entry_t), 0); dentry = vfs_alloc_dentry(tmp_path_len+1);
// 为目录项的名称分配内存
dentry->name = (char *)kmalloc(tmp_path_len + 1, 0);
// 貌似这里不需要memset因为空间会被覆盖
// memset(dentry->name, 0, tmp_path_len+1);
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';
@ -186,9 +184,6 @@ struct vfs_dir_entry_t *vfs_path_walk(const char *path, uint64_t flags)
return NULL; return NULL;
} }
// 找到子目录项 // 找到子目录项
// 初始化子目录项的entry
list_init(&dentry->child_node_list);
list_init(&dentry->subdirs_list);
dentry->parent = parent; dentry->parent = parent;
list_add(&parent->subdirs_list, &dentry->child_node_list); list_add(&parent->subdirs_list, &dentry->child_node_list);
@ -214,6 +209,7 @@ struct vfs_dir_entry_t *vfs_path_walk(const char *path, uint64_t flags)
/** /**
* @brief dentry * @brief dentry
* *
* @return dirent的总大小
*/ */
int vfs_fill_dirent(void *buf, ino_t d_ino, char *name, int namelen, unsigned char type, off_t offset) int vfs_fill_dirent(void *buf, ino_t d_ino, char *name, int namelen, unsigned char type, off_t offset)
{ {
@ -241,17 +237,15 @@ int vfs_fill_dirent(void *buf, ino_t d_ino, char *name, int namelen, unsigned ch
/** /**
* @brief * @brief
* *
* @param path(r8) * @param path
* @param mode(r9) * @param mode
* @return uint64_t * @param from_userland
* @return int64_t
*/ */
uint64_t sys_mkdir(struct pt_regs *regs) int64_t vfs_mkdir(const char* path, mode_t mode, bool from_userland)
{ {
const char *path = (const char *)regs->r8;
// kdebug("path = %s", path);
mode_t mode = (mode_t)regs->r9;
uint32_t pathlen; uint32_t pathlen;
if (regs->cs & USER_CS) if (from_userland)
pathlen = strnlen_user(path, PAGE_4K_SIZE - 1); pathlen = strnlen_user(path, PAGE_4K_SIZE - 1);
else else
pathlen = strnlen(path, PAGE_4K_SIZE - 1); pathlen = strnlen(path, PAGE_4K_SIZE - 1);
@ -279,7 +273,7 @@ uint64_t sys_mkdir(struct pt_regs *regs)
memset(buf, 0, pathlen + 1); memset(buf, 0, pathlen + 1);
// 拷贝字符串(不包含要被创建的部分) // 拷贝字符串(不包含要被创建的部分)
if (regs->cs & USER_CS) if (from_userland)
strncpy_from_user(buf, path, last_slash); strncpy_from_user(buf, path, last_slash);
else else
strncpy(buf, path, last_slash); strncpy(buf, path, last_slash);
@ -306,7 +300,8 @@ uint64_t sys_mkdir(struct pt_regs *regs)
struct vfs_dir_entry_t *subdir_dentry = (struct vfs_dir_entry_t *)kmalloc(sizeof(struct vfs_dir_entry_t), 0); struct vfs_dir_entry_t *subdir_dentry = (struct vfs_dir_entry_t *)kmalloc(sizeof(struct vfs_dir_entry_t), 0);
memset((void *)subdir_dentry, 0, sizeof(struct vfs_dir_entry_t)); memset((void *)subdir_dentry, 0, sizeof(struct vfs_dir_entry_t));
list_init(&subdir_dentry->subdirs_list);
list_init(&subdir_dentry->child_node_list);
if (path[pathlen - 1] == '/') if (path[pathlen - 1] == '/')
subdir_dentry->name_length = pathlen - last_slash - 2; subdir_dentry->name_length = pathlen - last_slash - 2;
else else
@ -325,10 +320,29 @@ uint64_t sys_mkdir(struct pt_regs *regs)
subdir_dentry->parent = parent_dir; subdir_dentry->parent = parent_dir;
// kdebug("to mkdir, parent name=%s", parent_dir->name); // kdebug("to mkdir, parent name=%s", parent_dir->name);
int retval = parent_dir->dir_inode->inode_ops->mkdir(parent_dir->dir_inode, subdir_dentry, 0); int retval = parent_dir->dir_inode->inode_ops->mkdir(parent_dir->dir_inode, subdir_dentry, 0);
list_add(&parent_dir->subdirs_list, &subdir_dentry->child_node_list); list_append(&parent_dir->subdirs_list, &subdir_dentry->child_node_list);
// kdebug("retval = %d", retval); // kdebug("retval = %d", retval);
return 0; return 0;
} }
/**
* @brief
*
* @param path(r8)
* @param mode(r9)
* @return uint64_t
*/
uint64_t sys_mkdir(struct pt_regs *regs)
{
const char *path = (const char *)regs->r8;
// kdebug("path = %s", path);
mode_t mode = (mode_t)regs->r9;
if (regs->cs & USER_CS)
return vfs_mkdir(path, mode, true);
else
return vfs_mkdir(path, mode, false);
}
/** /**
* @brief * @brief
@ -502,7 +516,6 @@ uint64_t do_open(const char *filename, int flags)
} }
// 保存文件描述符 // 保存文件描述符
f[fd_num] = file_ptr; f[fd_num] = file_ptr;
return fd_num; return fd_num;
} }

View File

@ -224,3 +224,13 @@ struct vfs_dir_entry_t *vfs_alloc_dentry(const int name_size);
* @return uint64_t * @return uint64_t
*/ */
uint64_t do_open(const char *filename, int flags); uint64_t do_open(const char *filename, int flags);
/**
* @brief
*
* @param path
* @param mode
* @param from_userland
* @return int64_t
*/
int64_t vfs_mkdir(const char* path, mode_t mode, bool from_userland);

View File

@ -30,7 +30,7 @@ int do_mount(struct vfs_dir_entry_t *old_dentry, struct vfs_dir_entry_t *new_den
mp->dentry = old_dentry; mp->dentry = old_dentry;
mp->parent_dentry = old_dentry->parent; mp->parent_dentry = old_dentry->parent;
kdebug("&new_dentry->name=%#018lx, &old_dentry->name=%#018lx", &new_dentry->name, &old_dentry->name); // kdebug("&new_dentry->name=%#018lx, &old_dentry->name=%#018lx", &new_dentry->name, &old_dentry->name);
// 拷贝名称 // 拷贝名称
strncpy(new_dentry->name, old_dentry->name, old_dentry->name_length); strncpy(new_dentry->name, old_dentry->name, old_dentry->name_length);
@ -41,7 +41,22 @@ int do_mount(struct vfs_dir_entry_t *old_dentry, struct vfs_dir_entry_t *new_den
// 将新的dentry的list结点替换掉父dentry的列表中的old_dentry的list结点 // 将新的dentry的list结点替换掉父dentry的列表中的old_dentry的list结点
list_replace(&old_dentry->child_node_list, &new_dentry->child_node_list); list_replace(&old_dentry->child_node_list, &new_dentry->child_node_list);
// 后挂载的dentry在链表的末尾umount恢复的时候需要依赖这个性质
list_append(&mnt_list_head, &mp->mnt_list); list_append(&mnt_list_head, &mp->mnt_list);
return 0; return 0;
} }
/**
* @brief
*
* @param dentry dentry
* @return int
*/
int do_umount(struct vfs_dir_entry_t* dentry)
{
// todo: 实现umount主要是结点的恢复问题
return 0;
}

View File

@ -27,3 +27,11 @@ int mount_init();
* @return int * @return int
*/ */
int do_mount(struct vfs_dir_entry_t *old_dentry, struct vfs_dir_entry_t *new_dentry); int do_mount(struct vfs_dir_entry_t *old_dentry, struct vfs_dir_entry_t *new_dentry);
/**
* @brief
*
* @param dentry dentry
* @return int
*/
int do_umount(struct vfs_dir_entry_t* dentry);

View File

@ -1,6 +1,85 @@
#include "chardev.h" #include "chardev.h"
#include "internal.h"
#include <common/mutex.h>
#include <common/stdlib.h>
#include <common/string.h>
#include <common/printk.h>
int chardev_register() static struct vfs_dir_entry_t *chardev_folder_dentry = NULL;
extern struct vfs_dir_entry_t *devfs_root_dentry;
/**
* @brief
*
*/
static char chardev_name_prefix[CHAR_DEV_STYPE_END + 1][32] = {
[CHAR_DEV_STYPE_START] = "",
[CHAR_DEV_STYPE_PS2_KEYBOARD] = "ps2.kb",
[CHAR_DEV_STYPE_PS2_MOUSE] = "ps2.mse",
[CHAR_DEV_STYPE_USB_MOUSE] = "usb.mse",
[CHAR_DEV_STYPE_USB_KEYBOARD] = "usb.kb",
[CHAR_DEV_STYPE_BLUETOOTH_MOUSE] = "bt.mse",
[CHAR_DEV_STYPE_BLUETOOTH_KEYBOARD] = "bt.kb",
[CHAR_DEV_STYPE_END] = "",
};
/**
* @brief
*
*/
static struct chardev_manage_info_t
{ {
mutex_t lock; // 操作互斥锁
int count;
} chardev_manage_info[CHAR_DEV_STYPE_END + 1];
/**
* @brief devfs中注册字符设备devfs调用
*
* @param private_info inode私有信息
* @param target_dentry dentry的指针
* @return int
*/
int __devfs_chardev_register(struct devfs_private_inode_info_t *private_info, struct vfs_dir_entry_t **target_dentry)
{
// 检测subtype是否合法
if (private_info->sub_type <= CHAR_DEV_STYPE_START || private_info->sub_type >= CHAR_DEV_STYPE_END)
return -EINVAL;
mutex_lock(&chardev_manage_info[private_info->sub_type].lock);
// 拷贝名称
char devname[64] = {0};
strcpy(devname, chardev_name_prefix[private_info->sub_type]);
char *ptr = devname + strlen(chardev_name_prefix[private_info->sub_type]);
sprintk(ptr, "%d", chardev_manage_info[private_info->sub_type].count);
int namelen = strlen(devname);
struct vfs_dir_entry_t *dentry = vfs_alloc_dentry(namelen + 1);
__devfs_fill_dentry(dentry, devname);
__devfs_fill_inode(dentry, __devfs_alloc_inode(), VFS_ATTR_DEVICE, private_info);
// 将dentry挂载到char文件夹下
__devfs_dentry_bind_parent(chardev_folder_dentry, dentry);
++chardev_manage_info[private_info->sub_type].count;
mutex_unlock(&chardev_manage_info[private_info->sub_type].lock);
*target_dentry = dentry;
return 0;
}
/**
* @brief chardev管理机制
*
*/
void __devfs_chardev_init()
{
// 初始化管理信息结构体
for (int i = CHAR_DEV_STYPE_START + 1; i < CHAR_DEV_STYPE_END; ++i)
{
mutex_init(&chardev_manage_info[i].lock);
chardev_manage_info[i].count = 0;
}
vfs_mkdir("/dev/char", 0, false);
// 获取char dev的dentry
chardev_folder_dentry = __devfs_find_dir(devfs_root_dentry, "char");
} }

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <filesystem/VFS/VFS.h> #include "devfs.h"

View File

@ -9,6 +9,11 @@ enum
{ {
DEV_TYPE_UNDEF = 0, DEV_TYPE_UNDEF = 0,
DEV_TYPE_CHAR = 1, DEV_TYPE_CHAR = 1,
DEV_TYPE_USB,
DEV_TYPE_BLOCK,
DEV_TYPE_NET,
DEV_TYPE_BUS,
}; };
/** /**
@ -17,9 +22,14 @@ enum
*/ */
enum enum
{ {
CHAR_DEV_STYPE_PS2 = 1, CHAR_DEV_STYPE_START = 0,
CHAR_DEV_STYPE_USB, CHAR_DEV_STYPE_PS2_KEYBOARD = 1,
CHAR_DEV_STYPE_BLUETOOTH, CHAR_DEV_STYPE_USB_KEYBOARD,
CHAR_DEV_STYPE_PS2_MOUSE,
CHAR_DEV_STYPE_USB_MOUSE,
CHAR_DEV_STYPE_BLUETOOTH_MOUSE,
CHAR_DEV_STYPE_BLUETOOTH_KEYBOARD,
CHAR_DEV_STYPE_END, // 结束标志
}; };
/** /**

View File

@ -1,17 +1,18 @@
#include "devfs.h" #include "devfs.h"
#include "internal.h"
#include <filesystem/VFS/VFS.h> #include <filesystem/VFS/VFS.h>
#include <common/glib.h> #include <common/glib.h>
#include <common/string.h> #include <common/string.h>
#include <mm/slab.h> #include <mm/slab.h>
static struct vfs_super_block_operations_t devfs_sb_ops; struct vfs_super_block_operations_t devfs_sb_ops;
static struct vfs_dir_entry_operations_t devfs_dentry_ops; struct vfs_dir_entry_operations_t devfs_dentry_ops;
static struct vfs_file_operations_t devfs_file_ops; struct vfs_file_operations_t devfs_file_ops;
static struct vfs_inode_operations_t devfs_inode_ops; struct vfs_inode_operations_t devfs_inode_ops;
static struct vfs_dir_entry_t *devfs_root_dentry; // 根结点的dentry
static struct vfs_superblock_t devfs_sb = {0};
struct vfs_dir_entry_t *devfs_root_dentry; // 根结点的dentry
struct vfs_superblock_t devfs_sb = {0};
const char __devfs_mount_path[] = "/dev";
extern struct vfs_file_operations_t ps2_keyboard_fops; extern struct vfs_file_operations_t ps2_keyboard_fops;
/** /**
@ -37,7 +38,7 @@ static void devfs_write_superblock(struct vfs_superblock_t *sb) {}
static void devfs_put_superblock(struct vfs_superblock_t *sb) {} static void devfs_put_superblock(struct vfs_superblock_t *sb) {}
static void devfs_write_inode(struct vfs_index_node_t *inode) {} static void devfs_write_inode(struct vfs_index_node_t *inode) {}
static struct vfs_super_block_operations_t devfs_sb_ops = struct vfs_super_block_operations_t devfs_sb_ops =
{ {
.write_superblock = &devfs_write_superblock, .write_superblock = &devfs_write_superblock,
.put_superblock = &devfs_put_superblock, .put_superblock = &devfs_put_superblock,
@ -52,7 +53,7 @@ static long devfs_release(struct vfs_dir_entry_t *dEntry) {}
static long devfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) {} static long devfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) {}
static struct vfs_dir_entry_operations_t devfs_dentry_ops = struct vfs_dir_entry_operations_t devfs_dentry_ops =
{ {
.compare = &devfs_compare, .compare = &devfs_compare,
.hash = &devfs_hash, .hash = &devfs_hash,
@ -60,7 +61,10 @@ static struct vfs_dir_entry_operations_t devfs_dentry_ops =
.iput = &devfs_iput, .iput = &devfs_iput,
}; };
static long devfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) { return 0; } static long devfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
{
return 0;
}
static long devfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) {} static long devfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) {}
static long devfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {} static long devfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {}
static long devfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {} static long devfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {}
@ -85,7 +89,8 @@ static long devfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir
++file_ptr->position; ++file_ptr->position;
// 获取目标dentry由于是子目录项因此是child_node_list // 获取目标dentry由于是子目录项因此是child_node_list
struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list); struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list);
kdebug("target name=%s, namelen=%d", target_dent->name, target_dent->name_length); // kdebug("target name=%s, namelen=%d", target_dent->name, target_dent->name_length);
char *name = (char *)kzalloc(target_dent->name_length + 1, 0); char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
strncpy(name, target_dent->name, target_dent->name_length); strncpy(name, target_dent->name, target_dent->name_length);
uint32_t dentry_type; uint32_t dentry_type;
@ -99,7 +104,7 @@ failed:;
return 0; return 0;
} }
static struct vfs_file_operations_t devfs_file_ops = struct vfs_file_operations_t devfs_file_ops =
{ {
.open = &devfs_open, .open = &devfs_open,
.close = &devfs_close, .close = &devfs_close,
@ -119,17 +124,43 @@ static struct vfs_file_operations_t devfs_file_ops =
static long devfs_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode) static long devfs_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode)
{ {
} }
static struct vfs_dir_entry_t *devfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry) static struct vfs_dir_entry_t *devfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry)
{ {
kdebug("devfs_lookup: %s", dest_dEntry->name); /*
devfs是伪文件系统dentry缓存
inode来搜索目标目录项
devfs中没有这个文件/
NULL即可
*/
return NULL; return NULL;
} }
static long devfs_mkdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode) {} /**
* @brief devfs中创建文件夹(inode信息)
*
* @param inode inode
* @param dEntry dentry
* @param mode
* @return long
*/
static long devfs_mkdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode)
{
dEntry->dir_inode = (struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0);
dEntry->dir_inode->file_ops = &devfs_file_ops;
dEntry->dir_inode->inode_ops = &devfs_inode_ops;
// todo: 增加private inode info
dEntry->dir_inode->private_inode_info = NULL;
dEntry->dir_inode->sb = &devfs_sb;
dEntry->dir_inode->attribute = VFS_ATTR_DIR;
return 0;
}
static long devfs_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry) {} static long devfs_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry) {}
static long devfs_rename(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry, struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry) {} static long devfs_rename(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry, struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry) {}
static long devfs_getAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {} static long devfs_getAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {}
static long devfs_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {} static long devfs_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {}
static struct vfs_inode_operations_t devfs_inode_ops = { struct vfs_inode_operations_t devfs_inode_ops = {
.create = &devfs_create, .create = &devfs_create,
.lookup = &devfs_lookup, .lookup = &devfs_lookup,
.mkdir = &devfs_mkdir, .mkdir = &devfs_mkdir,
@ -139,7 +170,7 @@ static struct vfs_inode_operations_t devfs_inode_ops = {
.setAttr = &devfs_setAttr, .setAttr = &devfs_setAttr,
}; };
static struct vfs_filesystem_type_t devfs_fs_type = struct vfs_filesystem_type_t devfs_fs_type =
{ {
.name = "DEVFS", .name = "DEVFS",
.fs_flags = 0, .fs_flags = 0,
@ -149,6 +180,7 @@ static struct vfs_filesystem_type_t devfs_fs_type =
static __always_inline void __devfs_init_root_inode() static __always_inline void __devfs_init_root_inode()
{ {
devfs_root_dentry->dir_inode = (struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0);
devfs_root_dentry->dir_inode->file_ops = &devfs_file_ops; devfs_root_dentry->dir_inode->file_ops = &devfs_file_ops;
devfs_root_dentry->dir_inode->inode_ops = &devfs_inode_ops; devfs_root_dentry->dir_inode->inode_ops = &devfs_inode_ops;
@ -166,31 +198,49 @@ static __always_inline void __devfs_init_root_dentry()
list_init(&devfs_root_dentry->child_node_list); list_init(&devfs_root_dentry->child_node_list);
list_init(&devfs_root_dentry->subdirs_list); list_init(&devfs_root_dentry->subdirs_list);
devfs_root_dentry->dir_ops = &devfs_dentry_ops; devfs_root_dentry->dir_ops = &devfs_dentry_ops;
devfs_root_dentry->dir_inode = (struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0);
__devfs_init_root_inode(); __devfs_init_root_inode();
} }
int devfs_register_device() /**
* @brief devfs中注册设备
*
* @param name
* @param device_type
* @param sub_type
* @param file_ops
* @return int
*/
int devfs_register_device(uint16_t device_type, uint16_t sub_type, struct vfs_file_operations_t *file_ops)
{ {
// 暂时只支持键盘文件 int retval = 0;
char name[] = "keyboard.dev"; // 申请private info结构体
struct vfs_dir_entry_t *dentry = vfs_alloc_dentry(sizeof(name)); struct devfs_private_inode_info_t *private_info = (struct devfs_private_inode_info_t *)kzalloc(sizeof(struct devfs_private_inode_info_t), 0);
strcpy(dentry->name, name); private_info->f_ops = file_ops;
dentry->name_length = strlen(name); private_info->type = device_type;
dentry->dir_inode = (struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0); private_info->sub_type = sub_type;
dentry->dir_ops = &devfs_dentry_ops;
dentry->dir_inode->file_ops = &ps2_keyboard_fops; struct vfs_dir_entry_t *dentry = NULL; // 该指针由对应类型设备的注册函数设置
dentry->dir_inode->inode_ops = &devfs_inode_ops;
dentry->dir_inode->private_inode_info = NULL; // todo: switch (device_type)
dentry->dir_inode->sb = &devfs_sb; {
dentry->dir_inode->attribute = VFS_ATTR_DEVICE; case DEV_TYPE_CHAR:
dentry->parent = devfs_root_dentry; retval = __devfs_chardev_register(private_info, &dentry);
list_init(&dentry->child_node_list); break;
list_init(&dentry->subdirs_list);
list_append(&devfs_root_dentry->subdirs_list, &dentry->child_node_list); default:
kdebug("add dev: %s", dentry->name); kerror("Unsupported device type [ %d ].", device_type);
// devfs_create(&devfs_root_dentry->dir_inode, dentry->dir_inode, 0); retval = -ENOTSUP;
goto failed;
break;
}
return retval;
failed:;
kfree(private_info);
return retval;
} }
/** /**
* @brief devfs * @brief devfs
* *
@ -199,7 +249,11 @@ void devfs_init()
{ {
__devfs_init_root_dentry(); __devfs_init_root_dentry();
vfs_register_filesystem(&devfs_fs_type); vfs_register_filesystem(&devfs_fs_type);
vfs_mount_fs("/dev", "DEVFS", NULL); vfs_mount_fs(__devfs_mount_path, "DEVFS", NULL);
devfs_register_device();
__devfs_chardev_init();
// todo: 当rootfs实现后将ps/2键盘的注册改为在驱动程序中进行目前没有rootfs因此还不能在不依赖fat32的情况下挂载设备
devfs_register_device(DEV_TYPE_CHAR, CHAR_DEV_STYPE_PS2_KEYBOARD, &ps2_keyboard_fops);
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "devfs-types.h"
/** /**
* @brief devfs * @brief devfs

View File

@ -0,0 +1,109 @@
#pragma once
#include "devfs.h"
#include <common/string.h>
extern struct vfs_super_block_operations_t devfs_sb_ops;
extern struct vfs_dir_entry_operations_t devfs_dentry_ops;
extern struct vfs_file_operations_t devfs_file_ops;
extern struct vfs_inode_operations_t devfs_inode_ops;
extern struct vfs_superblock_t devfs_sb;
// 分配inode
#define __devfs_alloc_inode() ((struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0))
/**
* @brief devfs中注册字符设备devfs调用
*
* @param private_info inode私有信息
* @param target_dentry dentry的指针
* @return int
*/
int __devfs_chardev_register(struct devfs_private_inode_info_t *private_info, struct vfs_dir_entry_t **target_dentry);
/**
* @brief chardev管理机制
*
*/
void __devfs_chardev_init();
/**
* @brief dentry中寻找子dentry
*
* @param parent_dentry dentry结点
* @param name
* @return struct vfs_dir_entry_t*
*/
static inline struct vfs_dir_entry_t *__devfs_find_dentry(struct vfs_dir_entry_t *parent_dentry, const char *name)
{
struct List *list = &parent_dentry->subdirs_list;
while (list_next(list) != &parent_dentry->subdirs_list)
{
list = list_next(list);
// 获取目标dentry由于是子目录项因此是child_node_list
struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list);
if (strcmp(target_dent->name, name) == 0)
return target_dent;
}
return NULL;
}
/**
* @brief
*
* @param parent_dentry
* @param name
* @return struct vfs_dir_entry_t* dentry NULL
*/
static inline struct vfs_dir_entry_t *__devfs_find_dir(struct vfs_dir_entry_t *parent_dentry, const char *name)
{
struct vfs_dir_entry_t *target_dent = __devfs_find_dentry(parent_dentry, name);
if (target_dent->dir_inode->attribute & VFS_ATTR_DIR) // 名称相符且为目录则返回dentry
return target_dent;
else
return NULL; // 否则直接返回空
}
/**
* @brief dentry和inode进行绑定inode
*
* @param dentry dentry
* @param inode inode
* @param inode_attr inode的属性
* @param private_inode_data inode私有信息
*/
static inline void __devfs_fill_inode(struct vfs_dir_entry_t *dentry, struct vfs_index_node_t *inode, uint64_t inode_attr, struct devfs_private_inode_info_t *private_inode_data)
{
dentry->dir_inode = inode;
dentry->dir_inode->file_ops = private_inode_data->f_ops;
dentry->dir_inode->inode_ops = &devfs_inode_ops;
dentry->dir_inode->private_inode_info = private_inode_data;
dentry->dir_inode->sb = &devfs_sb;
dentry->dir_inode->attribute = inode_attr;
}
/**
* @brief dentry中的内容
*
* @param dentry dentry
* @param name dentry名称
*/
static inline void __devfs_fill_dentry(struct vfs_dir_entry_t *dentry, const char *name)
{
strcpy(dentry->name, name);
dentry->name_length = strlen(name);
dentry->dir_ops = &devfs_dentry_ops;
}
/**
* @brief dentry与父dentry进行绑定
* @param parent
* @param dentry
*/
#define __devfs_dentry_bind_parent(parent_dentry, dentry) \
do \
{ \
(dentry)->parent = (parent_dentry); \
list_append(&((parent_dentry)->subdirs_list), &((dentry)->child_node_list)); \
} while (0)

View File

@ -900,6 +900,7 @@ fail:;
* @param inode inode * @param inode inode
* @param dEntry dentry * @param dEntry dentry
* @param mode mode * @param mode mode
* @return long
*/ */
int64_t fat32_mkdir(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dEntry, int mode) int64_t fat32_mkdir(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dEntry, int mode)
{ {
@ -1053,7 +1054,7 @@ int64_t fat32_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr)
* @param file_ptr * @param file_ptr
* @param dirent dirent * @param dirent dirent
* @param filler dirent的函数 * @param filler dirent的函数
* @return int64_t * @return uint64_t dirent的总大小
*/ */
int64_t fat32_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler) int64_t fat32_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler)
{ {

29
kernel/lib/stdlib.c Normal file
View File

@ -0,0 +1,29 @@
#include <common/stdlib.h>
/**
* @brief
*
* @param input
* @return const char*
*/
const char *ltoa(long input)
{
/* large enough for -9223372036854775808 */
static char buffer[21] = {0};
char *pos = buffer + sizeof(buffer) - 1;
int neg = input < 0;
unsigned long n = neg ? -input : input;
*pos-- = '\0';
do
{
*pos-- = '0' + n % 10;
n /= 10;
if (pos < buffer)
return pos + 1;
} while (n);
if (neg)
*pos-- = '-';
return pos + 1;
}

View File

@ -425,7 +425,7 @@ uint64_t sys_chdir(struct pt_regs *regs)
* @brief * @brief
* *
* @param fd * @param fd
* @return uint64_t * @return uint64_t dirent的总大小
*/ */
uint64_t sys_getdents(struct pt_regs *regs) uint64_t sys_getdents(struct pt_regs *regs)
{ {

View File

@ -210,7 +210,7 @@ int shell_cmd_cd(int argc, char **argv)
new_path[current_dir_len] = '/'; new_path[current_dir_len] = '/';
strcat(new_path, argv[1] + dest_offset); strcat(new_path, argv[1] + dest_offset);
int x = chdir(new_path); int x = chdir(new_path);
printf("chdir: retval=%d\n",x);
if (x == 0) // 成功切换目录 if (x == 0) // 成功切换目录
{ {
free(shell_current_path); free(shell_current_path);

View File

@ -86,9 +86,9 @@ void main_loop(int kb_fd)
int main() int main()
{ {
// 打开键盘文件 // 打开键盘文件
char kb_file_path[] = "/dev/keyboard.dev"; char kb_file_path[] = "/dev/char/ps2.kb0";
int kb_fd = open(kb_file_path, 0); int kb_fd = open(kb_file_path, 0);
// printf("keyboard fd = %d\n", kb_fd);
print_ascii_logo(); print_ascii_logo();
// printf("before mkdir\n"); // printf("before mkdir\n");
// mkdir("/aaac", 0); // mkdir("/aaac", 0);