|
@@ -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;
|
|
|
|
-static struct vfs_dir_entry_operations_t devfs_dentry_ops;
|
|
|
|
-static struct vfs_file_operations_t devfs_file_ops;
|
|
|
|
-static 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_super_block_operations_t devfs_sb_ops;
|
|
|
|
+struct vfs_dir_entry_operations_t devfs_dentry_ops;
|
|
|
|
+struct vfs_file_operations_t devfs_file_ops;
|
|
|
|
+struct vfs_inode_operations_t devfs_inode_ops;
|
|
|
|
|
|
|
|
+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,6 @@ 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);
|
|
@@ -101,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,
|
|
@@ -121,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,
|
|
@@ -141,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,
|
|
@@ -151,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;
|
|
|
|
|
|
@@ -168,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)
|
|
{
|
|
{
|
|
- // 暂时只支持键盘文件
|
|
|
|
- char name[] = "keyboard.dev";
|
|
|
|
- struct vfs_dir_entry_t *dentry = vfs_alloc_dentry(sizeof(name));
|
|
|
|
- strcpy(dentry->name, name);
|
|
|
|
- dentry->name_length = strlen(name);
|
|
|
|
- dentry->dir_inode = (struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0);
|
|
|
|
- dentry->dir_ops = &devfs_dentry_ops;
|
|
|
|
- dentry->dir_inode->file_ops = &ps2_keyboard_fops;
|
|
|
|
- dentry->dir_inode->inode_ops = &devfs_inode_ops;
|
|
|
|
- dentry->dir_inode->private_inode_info = NULL; // todo:
|
|
|
|
- dentry->dir_inode->sb = &devfs_sb;
|
|
|
|
- dentry->dir_inode->attribute = VFS_ATTR_DEVICE;
|
|
|
|
- dentry->parent = devfs_root_dentry;
|
|
|
|
- list_init(&dentry->child_node_list);
|
|
|
|
- list_init(&dentry->subdirs_list);
|
|
|
|
- list_append(&devfs_root_dentry->subdirs_list, &dentry->child_node_list);
|
|
|
|
- kdebug("add dev: %s", dentry->name);
|
|
|
|
- // devfs_create(&devfs_root_dentry->dir_inode, dentry->dir_inode, 0);
|
|
|
|
|
|
+ int retval = 0;
|
|
|
|
+ // 申请private info结构体
|
|
|
|
+ struct devfs_private_inode_info_t *private_info = (struct devfs_private_inode_info_t *)kzalloc(sizeof(struct devfs_private_inode_info_t), 0);
|
|
|
|
+ private_info->f_ops = file_ops;
|
|
|
|
+ private_info->type = device_type;
|
|
|
|
+ private_info->sub_type = sub_type;
|
|
|
|
+
|
|
|
|
+ struct vfs_dir_entry_t *dentry = NULL; // 该指针由对应类型设备的注册函数设置
|
|
|
|
+
|
|
|
|
+ switch (device_type)
|
|
|
|
+ {
|
|
|
|
+ case DEV_TYPE_CHAR:
|
|
|
|
+ retval = __devfs_chardev_register(private_info, &dentry);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ kerror("Unsupported device type [ %d ].", device_type);
|
|
|
|
+ retval = -ENOTSUP;
|
|
|
|
+ goto failed;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return retval;
|
|
|
|
+failed:;
|
|
|
|
+ kfree(private_info);
|
|
|
|
+ return retval;
|
|
}
|
|
}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* @brief 初始化devfs
|
|
* @brief 初始化devfs
|
|
*
|
|
*
|
|
@@ -201,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_chardev_init();
|
|
|
|
|
|
- devfs_register_device();
|
|
|
|
|
|
+ // todo: 当rootfs实现后,将ps/2键盘的注册改为在驱动程序中进行(目前没有rootfs,因此还不能在不依赖fat32的情况下,挂载设备)
|
|
|
|
+ devfs_register_device(DEV_TYPE_CHAR, CHAR_DEV_STYPE_PS2_KEYBOARD, &ps2_keyboard_fops);
|
|
}
|
|
}
|