Jelajahi Sumber

:new: vfs虚拟文件系统

fslongjin 3 tahun lalu
induk
melakukan
7d3c1b098e
4 mengubah file dengan 234 tambahan dan 3 penghapusan
  1. 5 2
      kernel/Makefile
  2. 66 0
      kernel/filesystem/VFS/VFS.c
  3. 136 0
      kernel/filesystem/VFS/VFS.h
  4. 27 1
      kernel/filesystem/fat32/fat32.h

+ 5 - 2
kernel/Makefile

@@ -88,6 +88,9 @@ fat32.o: filesystem/fat32/fat32.c
 MBR.o: filesystem/MBR.c
 	gcc $(CFLAGS) -c filesystem/MBR.c -o filesystem/MBR.o
 
+VFS.o: filesystem/VFS/VFS.c
+	gcc $(CFLAGS) -c filesystem/VFS/VFS.c -o filesystem/VFS/VFS.o
+
 # IPI的代码
 ifeq ($(ARCH), x86_64)
 OBJ_LIST += ipi.o
@@ -148,9 +151,9 @@ all: kernel
 	objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
 #
 
-kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o fat32.o MBR.o $(OBJ_LIST)
+kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o fat32.o MBR.o VFS.o $(OBJ_LIST)
 	ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \
-	common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o sched/sched.o	filesystem/fat32/fat32.o filesystem/MBR.o \
+	common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o sched/sched.o	filesystem/fat32/fat32.o filesystem/MBR.o filesystem/VFS/VFS.o \
 	driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o driver/timers/timer.o \
 	$(LD_LIST)	\
 	-T link.lds

+ 66 - 0
kernel/filesystem/VFS/VFS.c

@@ -0,0 +1,66 @@
+#include "VFS.h"
+#include <common/kprint.h>
+
+// 为filesystem_type_t结构体实例化一个链表头
+static struct vfs_filesystem_type_t vfs_fs = {"filesystem", 0};
+
+
+/**
+ * @brief 挂载文件系统
+ *
+ * @param name 文件系统名
+ * @param DPTE 分区表entry
+ * @param DPT_type 分区表类型
+ * @param buf 缓存去
+ * @return struct vfs_superblock_t*
+ */
+struct vfs_superblock_t *vfs_mount_fs(char *name, void *DPTE, uint8_t DPT_type, void *buf)
+{
+
+    struct vfs_filesystem_type_t *p = NULL;
+    for (p = &vfs_fs; p; p = p->next)
+    {
+        if (!strcmp(p->name, name)) // 存在符合的文件系统
+        {
+            return p->read_superblock(DPTE, DPT_type, buf);
+        }
+    }
+    kdebug("unsupported fs: %s", name);
+    return NULL;
+}
+
+/**
+ * @brief 在VFS中注册文件系统
+ * 
+ * @param fs 文件系统类型结构体
+ * @return uint64_t 
+ */
+uint64_t vfs_register_filesystem(struct vfs_filesystem_type_t *fs)
+{
+    struct vfs_filesystem_type_t *p = NULL;
+    for(p = &vfs_fs; p;p = p->next)
+    {
+        if(!strcmp(p->name,fs->name))   // 已经注册相同名称的文件系统
+            return VFS_E_FS_EXISTED;
+    }
+
+    fs->next = vfs_fs.next;
+    vfs_fs.next = fs;
+    return VFS_SUCCESS;
+}
+
+uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs)
+{
+    struct vfs_filesystem_type_t *p = &vfs_fs;
+    while(p->next)
+    {
+        if(p->next == fs)
+        {
+            p->next = p->next->next;
+            fs->next = NULL;
+            return VFS_SUCCESS;
+        }
+        else p = p->next;
+    }
+    return VFS_E_FS_NOT_EXIST;
+}

+ 136 - 0
kernel/filesystem/VFS/VFS.h

@@ -0,0 +1,136 @@
+/**
+ * @file VFS.h
+ * @author fslongjin (longjin@RinGoTek.cn)
+ * @brief 虚拟文件系统
+ * @version 0.1
+ * @date 2022-04-20
+ *
+ * @copyright Copyright (c) 2022
+ *
+ */
+
+#pragma once
+
+#include <common/glib.h>
+
+#define VFS_DPT_MBR 0 // MBR分区表
+#define VFS_DPT_GPT 1 // GPT分区表
+
+#define VFS_SUCCESS 0
+#define VFS_E_FS_EXISTED 1  // 错误:文件系统已存在
+#define VFS_E_FS_NOT_EXIST 2  // 错误:文件系统不存在
+
+struct vfs_super_block_operations_t;
+struct vfs_inode_operations_t;
+
+struct vfs_index_node_t;
+
+struct vfs_dir_entry_t
+{
+    char *name;
+    int name_length;
+    struct List child_node_list;
+    struct List subdirs_list;
+
+    struct vfs_index_node_t *dir_inode;
+    struct vfs_dir_entry_t *parent;
+    struct vfs_dir_entry_operatons_t *dir_ops;
+};
+
+struct vfs_superblock_t
+{
+    struct vfs_dir_entry_t *root;
+    struct vfs_super_block_operations_t *sb_ops;
+    void *private_sb_info;
+};
+
+struct vfs_index_node_t
+{
+    uint64_t file_size;
+    uint64_t blocks;
+    uint64_t attribute;
+
+    struct vfs_superblock_t *sb;
+    struct vfs_file_operations_t *file_ops;
+    struct vfs_inode_operations_t *inode_ops;
+
+    void *private_inode_info;
+};
+
+struct vfs_file_t
+{
+    long position;
+    uint64_t mode;
+
+    struct vfs_dir_entry_t *dEntry;
+    struct vfs_file_opeartions_t *file_ops;
+    void *private_data;
+};
+
+struct vfs_filesystem_type_t
+{
+    char *name;
+    int fs_flags;
+    struct vfs_superblock_t *(*read_superblock)(void *DPTE, uint8_t DPT_type, void *buf); // 解析文件系统引导扇区的函数,为文件系统创建超级块结构。其中DPTE为磁盘分区表entry(MBR、GPT不同)
+    struct vfs_filesystem_type_t *next;
+};
+
+struct vfs_super_block_operations_t
+{
+    void (*write_superblock)(struct vfs_superblock_t *sb);
+    void (*put_superblock)(struct vfs_superblock_t *sb);
+    void (*write_inode)(struct vfs_index_node_t *inode);
+};
+
+/**
+ * @brief 对vfs的inode的操作抽象
+ *
+ */
+struct vfs_inode_operations_t
+{
+    long (*create)(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode);
+    struct vfs_dir_entry_t *(*lookup)(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry);
+    long (*mkdir)(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode);
+    long (*rmdir)(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry);
+    long (*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);
+    long (*getAttr)(struct vfs_dir_entry_t *dEntry, uint64_t *attr);
+    long (*setAttr)(struct vfs_dir_entry_t *dEntry, uint64_t *attr);
+};
+
+struct vfs_dir_entry_operations_t
+{
+    long (*compare)(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename);
+    long (*hash)(struct vfs_dir_entry_t *dEntry, char *filename);
+    long (*release)(struct vfs_dir_entry_t *dEntry);
+    long (*iput)(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode);
+};
+
+struct vfs_file_operations_t
+{
+    long (*open)(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr);
+    long (*close)(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr);
+    long (*read)(struct vfs_file_t *file_ptr, char *buf, uint64_t buf_size, long *position);
+    long (*write)(struct vfs_file_t *file_ptr, char *buf, uint64_t buf_size, long *position);
+    long (*lseek)(struct vfs_file_t *file_ptr, long offset, long origin);
+    long (*ioctl)(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg);
+};
+
+/**
+ * @brief 在VFS中注册文件系统
+ * 
+ * @param fs 文件系统类型结构体
+ * @return uint64_t 
+ */
+uint64_t vfs_register_filesystem(struct vfs_filesystem_type_t *fs);
+uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs);
+
+/**
+ * @brief 挂载文件系统
+ *
+ * @param name 文件系统名
+ * @param DPTE 分区表entry
+ * @param DPT_type 分区表类型
+ * @param buf 缓存去
+ * @return struct vfs_superblock_t*
+ */
+struct vfs_superblock_t *vfs_mount_fs(char *name, void *DPTE, uint8_t DPT_type, void *buf);

+ 27 - 1
kernel/filesystem/fat32/fat32.h

@@ -129,13 +129,39 @@ struct fat32_partition_info_t
 
     struct fat32_BootSector_t bootsector;
     struct fat32_FSInfo_t fsinfo;
+    uint64_t fsinfo_sector_addr_infat;
+    uint64_t bootsector_bak_sector_addr_infat;
+
+    uint64_t starting_sector;
+    uint64_t sector_count;
+
+    uint64_t sec_per_clus;   // 每簇扇区数
+    uint64_t bytes_per_sec;  // 每扇区字节数
+    uint64_t bytes_per_clus; // 每簇字节数
 
     uint64_t first_data_sector; // 数据区起始扇区号
-    uint64_t bytes_per_clus;    // 每簇字节数
     uint64_t FAT1_base_sector;  // FAT1表的起始簇号
     uint64_t FAT2_base_sector;  // FAT2表的起始簇号
+    uint64_t sec_per_FAT;       // 每FAT表扇区数
+    uint64_t NumFATs;           // FAT表数
 };
 
+typedef struct fat32_partition_info_t fat32_sb_info_t;
+
+struct fat32_inode_info_t
+{
+    uint64_t first_clus;
+    uint64_t dEntry_location_clus;        // dEntry struct in cluster (0 is root, 1 is invalid)
+    uint64_t dEntry_location_clus_offset; // dEntry struct offset in cluster
+
+    uint16_t create_date;
+    uint16_t create_time;
+    uint16_t write_time;
+    uint16_t write_date;
+};
+
+typedef struct fat32_inode_info_t fat32_inode_info_t;
+
 /**
  * @brief 注册指定磁盘上的指定分区的fat32文件系统
  *