diff options
Diffstat (limited to 'lume-legacy/include/fs')
| -rw-r--r-- | lume-legacy/include/fs/fat32.h | 122 | ||||
| -rw-r--r-- | lume-legacy/include/fs/file.h | 78 | ||||
| -rw-r--r-- | lume-legacy/include/fs/fs.h | 105 | ||||
| -rw-r--r-- | lume-legacy/include/fs/stat.h | 27 |
4 files changed, 332 insertions, 0 deletions
diff --git a/lume-legacy/include/fs/fat32.h b/lume-legacy/include/fs/fat32.h new file mode 100644 index 0000000..63d62ae --- /dev/null +++ b/lume-legacy/include/fs/fat32.h @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2026 Richard QIn + */ + +#pragma once +#include "fs/fs.h" +#include "kernel/buf.h" + +// Disk Layout Structures (On-Disk) + +// FAT32 Boot Sector (BPB) +struct FAT32_BPB +{ + uint8 jmpBoot[3]; + char oemName[8]; + uint16 bytesPerSector; + uint8 secPerClus; + uint16 reservedSecCnt; + uint8 numFATs; + uint16 rootEntCnt; + uint16 totSec16; + uint8 media; + uint16 FATSz16; + uint16 secPerTrk; + uint16 numHeads; + uint32 hiddSec; + uint32 totSec32; + uint32 FATSz32; + uint16 extFlags; + uint16 FSVer; + uint32 rootClus; + uint16 FSInfo; + uint16 bkBootSec; + uint8 reserved[12]; + uint8 drvNum; + uint8 reserved1; + uint8 bootSig; + uint32 volID; + char volLab[11]; + char filSysType[8]; +} __attribute__((packed)); + +// FAT32 Directory Entry (32 bytes) +struct FAT32_DirEnt +{ + char name[11]; // 8.3 filename + uint8 attr; // File attributes + uint8 ntRes; + uint8 crtTimeTenth; + uint16 crtTime; + uint16 crtDate; + uint16 lstAccDate; + uint16 fstClusHI; // High 16 bits of first cluster + uint16 wrtTime; + uint16 wrtDate; + uint16 fstClusLO; // Low 16 bits of first cluster + uint32 fileSize; +} __attribute__((packed)); + +#define ATTR_READ_ONLY 0x01 +#define ATTR_HIDDEN 0x02 +#define ATTR_SYSTEM 0x04 +#define ATTR_VOLUME_ID 0x08 +#define ATTR_DIRECTORY 0x10 +#define ATTR_ARCHIVE 0x20 +#define ATTR_LONG_NAME 0x0F + +// In-Memory Classes + +class FAT32FileSystem; + +class FAT32Inode : public Inode +{ +public: + FAT32FileSystem *fs; + + // FAT32 Private Data + uint32 first_clus; // The starting cluster number of the file + uint32 parent_clus; // Starting cluster number of the parent directory + uint32 dir_offset; // The byte offset of this directory entry in the parent directory + uint32 ent_sec; // Sector number of the directory entry + uint32 ent_off; // Offset of the directory entry within the sector + + FAT32Inode() : fs(nullptr), first_clus(0) {} + // Implement VFS Interface + void update() override; + int read(char *dst, uint32 off, uint32 n, int isUser) override; + int write(const char *src, uint32 off, uint32 n, int isUser) override; + Inode *lookup(const char *name) override; + Inode *create(const char *name, short type, short major, short minor) override; + void truncate() override; + int unlink(const char *name) override; +}; + +class FAT32FileSystem : public FileSystem +{ +public: + uint32 fat_start_sector; + uint32 data_start_sector; + uint32 root_cluster; + uint32 sectors_per_cluster; + uint32 bytes_per_cluster; + uint32 fat_sz; // Size of the FAT table (number of sectors) + + void init() override; + Inode* root() override; + + // Helper functions + uint32 next_cluster(uint32 cluster); // Check the FAT table for the next cluster + uint32 alloc_cluster(); // Assign a new cluster + uint32 cluster_to_sector(uint32 cluster); + + // directory entry parsing + void read_dir_ent(struct FAT32_DirEnt *de, char *filename); + // Release the entire cluster chain starting from the cluster + void free_cluster_chain(uint32 cluster); +}; + +extern FAT32FileSystem fat32_fs; + +void fat32_test();
\ No newline at end of file diff --git a/lume-legacy/include/fs/file.h b/lume-legacy/include/fs/file.h new file mode 100644 index 0000000..9aff1af --- /dev/null +++ b/lume-legacy/include/fs/file.h @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2026 Richard QIn + */ + +#pragma once +#include "common/types.h" +#include "fs/fs.h" + +enum FileType +{ + FD_NONE, + FD_INODE, + FD_DEVICE, + FD_PIPE +}; + +class Pipe; + +struct file +{ + enum FileType type; + int ref; + char readable; + char writable; + + Pipe *pipe; // pipeline pointer + Inode *ip; // VFS Inode + uint32 off; // Current Offset +}; + +class Pipe +{ +public: + static constexpr uint32_t SIZE = 512; + + Pipe() : nread(0), nwrite(0), read_open(true), write_open(true) + { + lock.init("pipe"); + } + + // forbid copy + Pipe(const Pipe &) = delete; + Pipe &operator=(const Pipe &) = delete; + + ~Pipe() + { + // + } + + // creates a pair of connected file objects + static int create_pair(struct file **f0, struct file **f1); + + int read(uint64_t addr, int n); + int write(uint64_t addr, int n); + void close(bool is_writer); + +private: + Spinlock lock; + char data[SIZE]; + uint32_t nread; // read + uint32_t nwrite; // write + bool read_open; + bool write_open; +}; + +namespace FileTable +{ + void init(); + struct file *alloc(); // Allocate a free file handle + struct file *dup(struct file *f); // Duplicate handle (sys_dup) + void close(struct file *f); // Close handle + + int stat(struct file *f, uint64 addr); + int read(struct file *f, uint64 addr, int n); + int write(struct file *f, uint64 addr, int n); + int lseek(struct file *f, int offset, int whence); +} // namespace FileTable diff --git a/lume-legacy/include/fs/fs.h b/lume-legacy/include/fs/fs.h new file mode 100644 index 0000000..b511a84 --- /dev/null +++ b/lume-legacy/include/fs/fs.h @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2026 Richard QIn + */ + +#pragma once +#include "common/types.h" +#include "kernel/spinlock.h" +#include "fs/stat.h" + +class FileSystem; + +// VFS Inode (Abstract Base Class) + +class Inode +{ +private: + ; +public: + // VFS Common Fields + uint32 dev; // Device number (VirtIO Block ID) + uint32 inum; // Inode number + int ref_cnt; // Memory reference count (number of struct file or processes referencing it) + int valid; // Whether the data is valid (whether metadata has been read from disk) + + Mutex lock; // Sleep lock: protects internal Inode data and atomicity of read/write operations + + // Metadata Cache (for speeding up getattr) + short type; // T_DIR, T_FILE, T_DEVICE + short major; // Major device number (only for T_DEVICE) + short minor; // Minor device number (only for T_DEVICE) + short nlink; // Number of hard links + uint32 size; // File size + + Inode() : ref_cnt(0), valid(0) + { + lock.init("inode"); + } + virtual ~Inode() {} + + /* Core Operation Interface (Subclass Must Implement) */ + // Update metadata + // Sync size, type, links, etc. from memory back to disk + virtual void update() = 0; + // Read content + // Read n bytes from the file at offset into dst + // Returns the actual number of bytes read, returns -1 on error + virtual int read(char *dst, uint32 off, uint32 n, int isUser) = 0; + // 3. Write content + // Write n bytes from src to the file at the given offset + // Need to handle file growth + virtual int write(const char *src, uint32 off, uint32 n, int isUser) = 0; + // Directory Lookup (only valid when type == T_DIR) + // Search for a file named 'name' in the current directory and return its Inode pointer (locked) + // Return nullptr if not found + virtual Inode *lookup(const char *name) = 0; + // Create file/directory (only effective when type == T_DIR) + // Create a new entry in the current directory + virtual Inode *create(const char *name, short type, short major, short minor) = 0; + // Get file status (populate the stat structure) + // Default implementation, subclasses can override to provide more detailed information + virtual void getattr(struct kstat *st); + // Truncate file (set size to 0, release all data blocks) + virtual void truncate() = 0; + // Delete the file named 'name' from the directory (Unlink) + virtual int unlink(const char *name) = 0; +}; + +// File System Abstraction (SuperBlock) +class FileSystem +{ +private: + ; +public: + virtual void init() = 0; + virtual Inode* root() = 0; + virtual ~FileSystem() {}; +}; + +// Inode Cache Interface (Global Function) +namespace VFS +{ + void init(); + + // Decrease the reference count, and if it reaches 0, free the memory + void iput(Inode *ip); + // Increase reference count + Inode *idup(Inode *ip); + // lock and load data + void ilock(Inode *ip); + // unlock + void iunlock(Inode *ip); + void iunlockput(Inode *ip); + // Mount the root filesystem + void mount_root(Inode *root); + // Get system root node + Inode *get_root(); + // Path Analysis + Inode *namei(const char *path); + // Find the parent directory inode of the path, and copy the last part of the path (the file name) into the name buffer + Inode *nameiparent(const char *path, char *name); + // Register a file system + void register_fs(FileSystem *fs); + +} // namespace VFS diff --git a/lume-legacy/include/fs/stat.h b/lume-legacy/include/fs/stat.h new file mode 100644 index 0000000..e60ae42 --- /dev/null +++ b/lume-legacy/include/fs/stat.h @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2026 Richard QIn + */ + +#pragma once +#include "common/types.h" + +#define T_DIR 1 // Directory +#define T_FILE 2 // File +#define T_DEVICE 3 // Device + +struct kstat +{ + int dev; // File System's disk device + uint32 ino; // Inode number + short type; //Type of file + short nlink; // Number of links to file + uint64 size; // Size of file in bytes + + uint32 mode; // Protection: rwx + uint32 uid; // User ID + uint32 gid; // Group ID + uint32 atime; // Access time + uint32 mtime; // Modified time + uint32 ctime; // Change time +}; |
