From 7d3c1b098e296ba471d200cffaa2ea19137b5727 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Thu, 21 Apr 2022 23:48:47 +0800 Subject: [PATCH] =?UTF-8?q?:new:=20vfs=E8=99=9A=E6=8B=9F=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/Makefile | 7 +- kernel/filesystem/VFS/VFS.c | 66 ++++++++++++++++ kernel/filesystem/VFS/VFS.h | 136 ++++++++++++++++++++++++++++++++ kernel/filesystem/fat32/fat32.h | 28 ++++++- 4 files changed, 234 insertions(+), 3 deletions(-) create mode 100644 kernel/filesystem/VFS/VFS.c create mode 100644 kernel/filesystem/VFS/VFS.h diff --git a/kernel/Makefile b/kernel/Makefile index fe84d15c..fa54fb9f 100644 --- a/kernel/Makefile +++ b/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 diff --git a/kernel/filesystem/VFS/VFS.c b/kernel/filesystem/VFS/VFS.c new file mode 100644 index 00000000..646f6bfe --- /dev/null +++ b/kernel/filesystem/VFS/VFS.c @@ -0,0 +1,66 @@ +#include "VFS.h" +#include + +// 为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; +} \ No newline at end of file diff --git a/kernel/filesystem/VFS/VFS.h b/kernel/filesystem/VFS/VFS.h new file mode 100644 index 00000000..9e3c3243 --- /dev/null +++ b/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 + +#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); \ No newline at end of file diff --git a/kernel/filesystem/fat32/fat32.h b/kernel/filesystem/fat32/fat32.h index d9eba3ac..85e50f52 100644 --- a/kernel/filesystem/fat32/fat32.h +++ b/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文件系统 *