]> Zhao Yanbai Git Server - kernel.git/commitdiff
... dev/tmp
authoracevest <zhaoyanbai@126.com>
Tue, 30 Apr 2024 14:44:21 +0000 (22:44 +0800)
committeracevest <zhaoyanbai@126.com>
Tue, 30 Apr 2024 14:45:08 +0000 (22:45 +0800)
13 files changed:
fs/ext2.c
fs/fs.c
fs/open.c
fs/path.c [new file with mode: 0644]
fs/ramfs.c [new file with mode: 0644]
fs/ramfs.h [new file with mode: 0644]
fs/vfs.c
fs/vfs.h
include/fs.h
include/task.h
include/types.h
kernel/irq.c
kernel/sched.c

index 36345ce11090659a2871b8fe46fc56e64fe3d651..ffa6e1b551037798660ceade2f1d0a40cee30fe8 100644 (file)
--- a/fs/ext2.c
+++ b/fs/ext2.c
 superblock_t *ext2_read_super(superblock_t *sb, void *data) { return sb; }
 
 fs_type_t ext2_fs_type = {
-    "ext2",
-    ext2_read_super,
-    0,
+    .name = "ext2",
+    .read_super = ext2_read_super,
+    .next = 0,
 };
 
+void ext2_setup() { vfs_register_filesystem(&ext2_fs_type); }
+
+//--------------------------------------------------------------------------
 struct {
     ext2_sb_t ext2_sb;
     ext2_gd_t *ext2_gd;
@@ -30,9 +33,9 @@ struct {
 extern void blk_rw(dev_t dev, u64_t offset, u32_t scnt, char *buf);
 extern void kmem_cache_free(kmem_cache_t *cache, void *addr);
 
-#define BLKRW(blkid, blkcnt, buf)                                                               \
-    do {                                                                                        \
-        blk_rw(system.root_dev, 1ULL * (blkid)*EXT2_BLOCK_SIZE, (blkcnt)*EXT2_BLOCK_SIZE, buf); \
+#define BLKRW(blkid, blkcnt, buf)                                                                   \
+    do {                                                                                            \
+        blk_rw(system.root_dev, 1ULL * (blkid) * EXT2_BLOCK_SIZE, (blkcnt) * EXT2_BLOCK_SIZE, buf); \
     } while (0)
 
 kmem_cache_t *ext2_block_cache;
@@ -213,7 +216,9 @@ void ext2_setup_fs() {
     memset(&ext2_fs, 0, sizeof(ext2_fs));
 
     char *buf = kmalloc(EXT2_BLOCK_SIZE, 0);
-    if (buf == 0) panic("out of memory");
+    if (buf == 0) {
+        panic("out of memory");
+    }
 
     BLKRW(1, 1, buf);  // now blocksize == 1024, so blkid == 1
 
diff --git a/fs/fs.c b/fs/fs.c
index 008818910ceb1e2c7d5dabf35741c23cf6392862..cde27a894501c9de547fa4eaf4475adad7183e82 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
 #include <printk.h>
 #include <system.h>
 
+// void ramfs_setup();
+// void ext2_setup();
+
+// void setup_fs() {
+//     ramfs_setup();
+
+//     // ext2_setup();
+// }
+
+//--------------------------------------------------------------------------
+
 extern chrdev_t cnsl_chrdev;
 
 chrdev_t *chrdev[CHRDEV_SIZE] = {&cnsl_chrdev};
 
-void ext2_setup_fs();
+// void ext2_setup_fs();
 unsigned int ext2_search_inpath(const char *path);
 
-void setup_fs() { ext2_setup_fs(); }
+// void setup_fs() {
+//     ext2_setup_fs();
+// }
 
 unsigned int namei(const char *path) { return ext2_search_inpath(path); }
index 46ff07e4ce755c05927d983c816325394176cf69..54c57b365900952c33dc56ec20ea413442f86f1e 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
 #include <syscall.h>
 #include <types.h>
 
-int sysc_open(const char *path, int flags, mode_t mode) { return 0; }
+int get_unused_fd() {
+    int fd;
+    task_files_t *files = &(current->files);
+
+    for (int i = 0; i < NR_TASK_OPEN_CNT; i++) {
+        if (files->fds[i] == 0) {
+            return i;
+        }
+    }
+
+    printk("too many open files for %s\n", current->name);
+    return -EMFILE;
+}
+
+file_t *filp_open(const char *path, int flags, mode_t mode) {
+    int ret = 0;
+
+    // ret = open_path(path, flags, mode, nd);
+
+    return NULL;
+}
+
+int sysc_open(const char *path, int flags, mode_t mode) {
+    int fd = 0;
+
+    fd = get_unused_fd();
+
+    if (fd < 0) {
+        return fd;
+    }
+
+    file_t *fp = filp_open(path, flags, mode);
+
+    current->files.fds[fd] = fp;
+
+    return 0;
+}
diff --git a/fs/path.c b/fs/path.c
new file mode 100644 (file)
index 0000000..0e02240
--- /dev/null
+++ b/fs/path.c
@@ -0,0 +1,131 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: path.c
+ *      Author: Zhao Yanbai
+ *              2024-04-20 19:24:42 Saturday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <errno.h>
+#include <fs.h>
+#include <sched.h>
+#include <types.h>
+#include <vfs.h>
+
+bool path_init(const char *path, unsigned int flags, namei_t *ni) {
+    if (path == NULL) {
+        return false;
+    }
+
+    if (*path == '/') {
+        ni->mnt = current->mnt_root;
+        ni->dentry = current->dentry_root;
+    }
+
+    ni->mnt = current->mnt_pwd;
+    ni->dentry = current->dentry_pwd;
+
+    return true;
+}
+
+void follow_dotdot(namei_t *ni) {
+    while (1) {
+        dentry_t *dentry = NULL;
+        vfsmount_t *parent = NULL;
+
+        // 如果当前目录已经是根目录
+        if (ni->dentry == current->dentry_root) {
+            assert(ni->mnt == current->mnt_root);
+            // do nothing
+            return;
+        }
+
+        // 如果当前目录不是挂载的根目录
+        if (ni->dentry != ni->mnt->root) {
+            dentry = ni->dentry->d_parent;
+            ni->dentry = dentry;
+            return;
+        }
+
+        // 当前目录是挂载的根目录,这就需要找到挂载点的上一层目录
+        // 所以先找到挂载点的父挂载点vfsmount
+        parent = ni->mnt->parent;
+
+        // 如果当前挂载点已经是最开始的挂载点vfsmount了
+        if (ni->mnt == parent) {
+            return;
+        }
+
+        // 如果当前挂载点有父挂载点
+        // 就记录当前挂载点的dentry和它所在的挂载vfsmount
+        dentry = ni->mnt->mount_point;
+        ni->dentry = dentry;
+        ni->mnt = parent;
+
+        // 此时有两种情况
+        // 1. dentry 是根目录,就需要继续往上找
+        // 2. dentry 不是根目录,也需要再往上找一层dentry
+    }
+}
+
+int path_walk(const char *path, namei_t *ni) {
+    if (path == NULL) {
+        return -EINVAL;
+    }
+
+    // 先跳过最开始的 '/'
+    while (*path == '/') {
+        path++;
+    }
+
+    // 所有连续'/'之后立即就是'\0'
+    if (*path == 0) {
+        return 0;
+    }
+
+    // 拿到当前目录的 inode
+    inode_t *inode = ni->dentry->d_inode;
+
+    while (1) {
+        qstr_t this;
+        this.name = path;
+
+        do {
+            path++;
+        } while (*path && (*path != '/'));
+
+        this.len = path - this.name;
+
+        // 看是不是路径的最后一个文件名
+        if (*path == 0) {
+            //
+        }
+
+        // 跳过所有连续的 '/'
+        while (*path == '/') {
+            path++;
+        }
+
+        // 看是不是路径其实是以'/'结尾的
+        if (*path == 0) {
+            //
+        }
+
+        // 开始解析name(到这里这个name后跟着的所有的'/'都已经跳过了)
+        if (this.name[0] == '.') {
+            if (this.len == 1) {
+                // 目录无变化,继续下一轮解析
+                continue;
+            } else if (this.len == 2 && this.name[1] == '.') {
+                follow_dotdot(ni);
+                inode = ni->dentry->d_inode;
+                continue;
+            }
+        }
+
+        //
+    }
+
+    return 0;
+}
diff --git a/fs/ramfs.c b/fs/ramfs.c
new file mode 100644 (file)
index 0000000..e1caf28
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: ramfs.c
+ *      Author: Zhao Yanbai
+ *              2024-04-13 23:43:49 Saturday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include "ramfs.h"
+
+#include "fs.h"
+#include "mm.h"
+#include "string.h"
+#include "system.h"
+#include "vfs.h"
+
+superblock_t *ramfs_read_super(superblock_t *sb, void *data);
+fs_type_t ramfs_type = {
+    .name = "ramfs",
+    .read_super = ramfs_read_super,
+    .next = 0,
+};
+
+typedef struct ramfs_superblock {
+    //
+} ramfs_superblock_t;
+
+typedef struct ramfs_dentry {
+    // d
+
+} ramfs_dentry_t;
+
+typedef struct ramfs_inode {
+    // d
+} ramfs_inode_t;
+
+void ramfs_init() { vfs_register_filesystem(&ramfs_type); }
+
+superblock_t *ramfs_read_super(superblock_t *sb, void *data) { return sb; }
diff --git a/fs/ramfs.h b/fs/ramfs.h
new file mode 100644 (file)
index 0000000..4fd1d9a
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: ramfs.h
+ *      Author: Zhao Yanbai
+ *              2024-04-13 23:43:53 Saturday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
index d1ab375a0341752edc4bc06ad42a555ee36bdc18..509e9d7d918d4cee288ab77b8fef33c1760ee3c0 100644 (file)
--- a/fs/vfs.c
+++ b/fs/vfs.c
@@ -8,6 +8,7 @@
  */
 
 #include <string.h>
+#include <system.h>
 #include <vfs.h>
 
 // 要访问一个文件就必需先访问一个目录,才能根据文件名从目录中找到该文件的目录项,进而找到其inode
@@ -42,3 +43,24 @@ void vfs_register_filesystem(fs_type_t *fs) {
     add->next = fs;
     fs->next = 0;
 }
+
+fs_type_t *vfs_find_filesystem(const char *name) {
+    for (fs_type_t *fs = &file_systems; fs != 0; fs = fs->next) {
+        if (strcmp(fs->name, name) == 0) {
+            return fs;
+        }
+    }
+
+    return NULL;
+}
+
+void ramfs_init();
+void vfs_init() {
+    ramfs_init();
+    fs_type_t *fs = vfs_find_filesystem("ramfs");
+    if (NULL == fs) {
+        panic("no ramfs");
+    }
+
+    superblock_t *sb = fs->read_super(NULL, NULL);
+}
index af9dee58de5404c5df9164dfcb7821e7831a5cfb..cfd215e533d6b0948b1abc689e29f252147533cd 100644 (file)
--- a/fs/vfs.h
+++ b/fs/vfs.h
@@ -10,6 +10,7 @@
 #pragma once
 
 #include <list.h>
+#include <types.h>
 
 typedef struct dentry dentry_t;
 
@@ -20,9 +21,11 @@ typedef struct dentry_operations dentry_operations_t;
 
 // super block
 typedef struct superblock {
-    //
+    // 该超级起的根目录的 dentry
     dentry_t *sb_root;
+    //
     void *sb_private;
+    //
     sb_operations_t *sb_ops;
 } superblock_t;
 
@@ -47,6 +50,11 @@ typedef struct inode {
 
     // 缓存的pages
     list_head_t i_pages;
+
+    dev_t i_dev;   // inode存储在该设备上
+    dev_t i_rdev;  // inode所代表的设备号
+
+    loff_t i_size;
 } inode_t;
 
 struct dentry {
@@ -67,6 +75,12 @@ struct dentry {
     // 但多个dentry可以指向同一个inode(不实现)
     inode_t *d_inode;
 
+    // 需要一个标记自己已经成为挂载点的标志?
+    // uint32_t d_flags;
+    // 也可以用一个指向vfsmount的指针,非0表示挂载?
+    // 貌似应该搞个链表,因为一个点可以重复挂N次,N个文件系统
+    list_head_t d_vfsmnt;  // 所有挂载到这个目录的挂载点
+
     //
     dentry_operations_t *d_ops;
 
@@ -75,17 +89,18 @@ struct dentry {
 };
 
 struct sb_operations {
-    //
+    // read_inode
 };
 
-struct file_operations {
-    // open
-    // close
-    // read
-    // write
-    // lseek
-    // ioctl
-};
+// struct file_operations {
+//     // open
+//     // close
+//     // read
+//     // write
+//     // lseek
+//     // ioctl
+
+// };
 struct inode_operations {
     //
 };
@@ -94,18 +109,39 @@ struct dentry_operations {
     //
     // hash
     // compare
+    // d_release 关闭文件
+    // d_delete 删除文件
+    //
 };
 
 // 每当将一个存储设备安装到现有文件系统中的某个节点时,内核就要为之建立一个vfsmount结构
 // 这个结构中即包含着该设备的有关信息,也包含了安装点的信息
 // 系统中的每个文件系统,包括根设备的根文件系统,都要经过安装
+//
+// 在安装文件系统时内核主要做如下的事情
+// 创建一个vfsmount
+// 为被安装的设备创建一个superblock,并由该设备对应的文件系统来设置这个superblock
+// 为被安装的设备的根目录创建一个dentry
+// 为被安装的设备的根目录创建一个inode,由sb->sb_ops->read_inode来实现
+// 将superblock与被安装设备根目录的dentry关联
+// 将vfsmount与被安装设备的根目录dentry关联
 typedef struct vfsmount {
+    dentry_t *mount_point;  // 挂载点 dentry
+    dentry_t *root;         // 设备根目录 dentry
+    superblock_t *sb;       // 被安装的设备的superblock
+    struct vfsmount *parent;
+    // sb->sb_ops->read_inode得到被安装设备根目录的inode
+
+    list_head_t list;  // vfsmount 链表
+
+    // 先简单实现:不支持一个设备挂载多次,或一个目录被挂载多次
 } vfsmount_t;
 
 typedef struct fs_type {
     const char *name;
     superblock_t *(*read_super)(superblock_t *, void *);
     struct fs_type *next;
+    list_head_t sbs;  // 同属于这个文件系统的所有超级块链表
 } fs_type_t;
 
 extern superblock_t *root_sb;
index 7750690b24dacde030d4e649d3b007b6ab8a9db3..7a0a9a6ddb48d033082984f22428250e6e971635 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <page.h>
 #include <types.h>
+#include <vfs.h>
 
 /* 分区表开始的位置 */
 #define PARTS_POS 0x1BE
 #define DEV_MINOR_MASK ((1UL << DEV_MAJOR_BITS) - 1)
 
 #define MAKE_DEV(major, minor) ((major) << DEV_MAJOR_BITS | minor)
-#define MAKE_DISK_DEV(drv_no, part_no) MAKE_DEV(DEV_MAJOR_DISK, (((drv_no)&0x03) << 8) | (((part_no)&0xFF) << 0))
+#define MAKE_DISK_DEV(drv_no, part_no) MAKE_DEV(DEV_MAJOR_DISK, (((drv_no) & 0x03) << 8) | (((part_no) & 0xFF) << 0))
 
 #define DEV_MAJOR(dev) ((unsigned int)((dev) >> DEV_MAJOR_BITS))
-#define DEV_MINOR(dev) ((unsigned int)((dev)&DEV_MINOR_MASK))
+#define DEV_MINOR(dev) ((unsigned int)((dev) & DEV_MINOR_MASK))
 
 // #define MAX_SUPT_FILE_SIZE    (1)
 #define NR_FILES (1)
@@ -53,8 +54,28 @@ enum { CHRDEV_CNSL, CHRDEV_SIZE };
 
 extern chrdev_t *chrdev[];
 
-typedef struct {
-} file_t;
+typedef struct file file_t;
+
+typedef struct file_operations {
+    int (*open)(inode_t *, file_t *);
+    ssize_t (*read)(file_t *, char *, size_t, loff_t *);
+} file_operations_t;
+
+struct file {
+    // 多个打开的文件可能是同一个文件
+    dentry_t *f_dentry;
+    file_operations_t *f_ops;
+};
+
+typedef struct namei {
+    vfsmount_t *mnt;
+    dentry_t *dentry;
+} namei_t;
+
+typedef struct qstr {
+    const char *name;
+    unsigned int len;
+} qstr_t;
 
 #if 0
 #define NR_FILES (PAGE_SIZE / sizeof(File))
@@ -107,6 +128,4 @@ static inline pInode find_empty_inode()
 }
 #endif
 
-typedef uint32_t dev_t;
-
 #endif  //_FS_H
index d47538ed56e3490793eff7620491c76179cb8a04..1ff15ce5c713f0d85125d516234359f7cc34490b 100644 (file)
@@ -22,6 +22,7 @@
 #include <processor.h>
 #include <system.h>
 #include <types.h>
+#include <vfs.h>
 // #include <wait.h>
 
 enum {
@@ -40,6 +41,12 @@ enum {
 
 #define TASK_MAGIC 0xAABBCCDD11223344
 
+#define NR_TASK_OPEN_CNT 32
+typedef struct task_files {
+    // 暂时先不用bitmap,直接线性搜索
+    file_t *fds[NR_TASK_OPEN_CNT];
+} task_files_t;
+
 typedef union task_union {
     struct {
         uint32_t esp0; /* kernel stack */
@@ -68,6 +75,14 @@ typedef union task_union {
 
         char name[TASK_NAME_SIZE];
 
+        task_files_t files;
+
+        dentry_t *dentry_root;
+        dentry_t *dentry_pwd;
+
+        vfsmount_t *mnt_root;
+        vfsmount_t *mnt_pwd;
+
         list_head_t list;  // 所有进程串成一个链表
 
         list_head_t pend;  // 某些条件串成一个链表
index 04a3aaad23da66ce14ab253c022971ab31aa4ee8..62c2b65dd00b56cad16460fb967e0529b0d77929 100644 (file)
@@ -50,6 +50,10 @@ typedef long int32_t;
 typedef unsigned long long uint64_t;
 typedef long long int64_t;
 
+typedef uint64_t loff_t;
+
+typedef uint32_t dev_t;
+
 typedef unsigned long pid_t;
 typedef unsigned long mode_t;
 
index b6f6a5b45b1378d27c60cee74ec845b5969c213e..30cd0016e9c4118f4daa521a1c035c2b8ca928f0 100644 (file)
@@ -89,6 +89,8 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) {
     assert(irq_disabled());
     reenter++;
 
+    // TODO 判断打断的是否是内核态代码
+
     // 屏蔽当前中断
     p->chip->disable(irq);
 
index b2af86ea03c226e089b4de843823b7cea231804c..e17539995030f66c65b4e258c71ca2d750aa56f3 100644 (file)
@@ -83,6 +83,10 @@ void init_root_task() {
     wrmsr(MSR_SYSENTER_ESP, root_task.esp0, 0);
 #endif
 
+    for (i = 0; i < NR_TASK_OPEN_CNT; i++) {
+        root_task.files.fds[i] = NULL;
+    }
+
     printk("init_root_task tss.esp0 %08x\n", tss.esp0);
 }