From e611a61fc20d32117f08b3ee35b6708126a05de6 Mon Sep 17 00:00:00 2001 From: Atheria Date: Wed, 29 Oct 2025 19:06:24 +0700 Subject: [PATCH 1/3] Dynamic Mounting/Unmounting --- fs/EXT/Ext2.c | 30 ++++++++++++++++++++-- fs/EXT/Ext2.h | 1 + fs/FAT/FAT1x.c | 37 +++++++++++++++++++++++++-- fs/FAT/FAT1x.h | 1 + fs/FileSystem.h | 2 ++ fs/NTFS/NTFS.c | 24 +++++++++++++++++- fs/NTFS/NTFS.h | 1 + fs/VFS.c | 26 ++++++++++++++++--- fs/VFS.h | 1 + kernel/etc/Shell.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ mm/MemPool.h | 2 -- 11 files changed, 176 insertions(+), 11 deletions(-) diff --git a/fs/EXT/Ext2.c b/fs/EXT/Ext2.c index 1bbbc10..ca93e34 100644 --- a/fs/EXT/Ext2.c +++ b/fs/EXT/Ext2.c @@ -118,7 +118,7 @@ int Ext2ReadBlock(uint32_t block, void* buffer) { return 0; } -static FileSystemDriver ext2_driver = {"EXT2", Ext2Detect, Ext2Mount}; +static FileSystemDriver ext2_driver = {"EXT2", Ext2Detect, Ext2Mount, Ext2Unmount}; int Ext2Mount(BlockDevice* device, const char* mount_point) { // Prepare or reuse per-device volume @@ -222,11 +222,37 @@ int Ext2Mount(BlockDevice* device, const char* mount_point) { } PrintKernelF("EXT2: Mounted filesystem\n"); - PrintKernelSuccess("EXT2: Filesystem initialized successfully.\n"); + PrintKernelSuccess("EXT2: Filesystem mounted.\n"); rust_rwlock_write_unlock(volume.lock); return 0; } +int Ext2Unmount(BlockDevice* device) { + if (!device) return -1; + int id = device->id; + if (id < 0 || id >= MAX_BLOCK_DEVICES) return -1; + + Ext2Volume* vol = g_ext2_by_dev[id]; + if (!vol) return -1; // Not mounted + + if (g_ext2_active == vol) { + g_ext2_active = NULL; + } + + if (vol->group_descs) { + KernelFree(vol->group_descs); + } + + if (vol->lock) { + rust_rwlock_free(vol->lock); + } + + KernelFree(vol); + g_ext2_by_dev[id] = NULL; + + return 0; +} + int Ext2ReadInode(uint32_t inode_num, Ext2Inode* inode) { rust_rwlock_read_lock(volume.lock, GetCurrentProcess()->pid); if (inode_num == 0) { diff --git a/fs/EXT/Ext2.h b/fs/EXT/Ext2.h index 6b66a29..bb48d71 100644 --- a/fs/EXT/Ext2.h +++ b/fs/EXT/Ext2.h @@ -101,6 +101,7 @@ typedef struct { // Function prototypes for VFS integration int Ext2Mount(BlockDevice* device, const char* mount_point); +int Ext2Unmount(BlockDevice* device); int Ext2Detect(BlockDevice* device); void Ext2SetActive(BlockDevice* device); int Ext2ReadFile(const char* path, void* buffer, uint32_t max_size); diff --git a/fs/FAT/FAT1x.c b/fs/FAT/FAT1x.c index 0124c4b..75c91a5 100644 --- a/fs/FAT/FAT1x.c +++ b/fs/FAT/FAT1x.c @@ -41,7 +41,7 @@ int Fat1xDetect(BlockDevice* device) { return 1; } -static FileSystemDriver fat_driver = {"FAT1x", Fat1xDetect, Fat1xMount}; +static FileSystemDriver fat_driver = {"FAT1x", Fat1xDetect, Fat1xMount, Fat1xUnmount}; int Fat1xMount(BlockDevice* device, const char* mount_point) { if (!device) return -1; @@ -67,7 +67,7 @@ int Fat1xMount(BlockDevice* device, const char* mount_point) { return -1; } - sector_buffer = FastAlloc(POOL_SIZE_512); + sector_buffer = KernelMemoryAlloc(POOL_SIZE_512); if (!sector_buffer) { return -1; } @@ -99,6 +99,39 @@ int Fat1xMount(BlockDevice* device, const char* mount_point) { return 0; } +int Fat1xUnmount(BlockDevice* device) { + if (!device) return -1; + int id = device->id; + if (id < 0 || id >= MAX_BLOCK_DEVICES) return -1; + + Fat1xVolume* vol = g_fat1x_by_dev[id]; + if (!vol) return -1; // Not mounted + + if (g_fat1x_active == vol) { + g_fat1x_active = NULL; + } + + + KernelFree(vol); + g_fat1x_by_dev[id] = NULL; + + // If no other FAT volumes are active, free the shared sector buffer + bool any_active = false; + for (int i = 0; i < MAX_BLOCK_DEVICES; i++) { + if (g_fat1x_by_dev[i]) { + any_active = true; + break; + } + } + + if (!any_active && sector_buffer) { + KernelFree(sector_buffer); + sector_buffer = NULL; + } + + return 0; +} + void Fat12ConvertFilename(const char* filename, char* fat_name) { FastMemset(fat_name, ' ', 11); int name_pos = 0, ext_pos = 0, in_ext = 0; diff --git a/fs/FAT/FAT1x.h b/fs/FAT/FAT1x.h index 7950ab3..5896fa3 100644 --- a/fs/FAT/FAT1x.h +++ b/fs/FAT/FAT1x.h @@ -62,6 +62,7 @@ typedef struct { // Core Functions int Fat1xMount(BlockDevice* device, const char* mount_point); +int Fat1xUnmount(BlockDevice* device); int Fat1xDetect(BlockDevice* device); // Set the active FAT1x volume context for subsequent FAT operations void Fat1xSetActive(BlockDevice* device); diff --git a/fs/FileSystem.h b/fs/FileSystem.h index 1ca24e4..47bee9f 100644 --- a/fs/FileSystem.h +++ b/fs/FileSystem.h @@ -8,11 +8,13 @@ struct FileSystemDriver; typedef int (*DetectFunc)(struct BlockDevice* device); typedef int (*MountFunc)(struct BlockDevice* device, const char* mount_point); +typedef int (*UnmountFunc)(struct BlockDevice* device); typedef struct FileSystemDriver { const char* name; DetectFunc detect; MountFunc mount; + UnmountFunc unmount; } FileSystemDriver; void FileSystemInit(); diff --git a/fs/NTFS/NTFS.c b/fs/NTFS/NTFS.c index c82f149..76457f9 100644 --- a/fs/NTFS/NTFS.c +++ b/fs/NTFS/NTFS.c @@ -43,7 +43,7 @@ int NtfsDetect(struct BlockDevice* device) { return 1; } -static FileSystemDriver ntfs_driver = {"NTFS", NtfsDetect, NtfsMount}; +static FileSystemDriver ntfs_driver = {"NTFS", NtfsDetect, NtfsMount, NtfsUnmount}; int NtfsMount(struct BlockDevice* device, const char* mount_point) { if (!device || !device->read_blocks) return -1; @@ -148,6 +148,28 @@ int NtfsMount(struct BlockDevice* device, const char* mount_point) { return 0; } +int NtfsUnmount(BlockDevice* device) { + if (!device) return -1; + int id = device->id; + if (id < 0 || id >= MAX_BLOCK_DEVICES) return -1; + + NtfsVolume* vol = g_ntfs_by_dev[id]; + if (!vol) return -1; // Not mounted + + if (g_ntfs_active == vol) { + g_ntfs_active = NULL; + } + + if (vol->lock) { + rust_rwlock_free(vol->lock); + } + + KernelFree(vol); + g_ntfs_by_dev[id] = NULL; + + return 0; +} + int NtfsReadMftRecord(uint64_t record_num, NtfsMftRecord* record) { if (!volume.device || !record) return -1; if (!volume.lock) return -1; diff --git a/fs/NTFS/NTFS.h b/fs/NTFS/NTFS.h index 66f83c0..afd1e1f 100644 --- a/fs/NTFS/NTFS.h +++ b/fs/NTFS/NTFS.h @@ -133,6 +133,7 @@ typedef struct { // VFS Interface Functions int NtfsDetect(struct BlockDevice* device); int NtfsMount(struct BlockDevice* device, const char* mount_point); +int NtfsUnmount(struct BlockDevice* device); int NtfsReadFile(const char* path, void* buffer, uint32_t max_size); int NtfsWriteFile(const char* path, const void* buffer, uint32_t size); int NtfsListDir(const char* path); diff --git a/fs/VFS.c b/fs/VFS.c index f298655..4ef650d 100644 --- a/fs/VFS.c +++ b/fs/VFS.c @@ -58,6 +58,24 @@ int VfsMount(const char* path, BlockDevice* device, FileSystemDriver* fs_driver) return -1; } +int VfsUmount(const char* path) { + VfsMountStruct* mount = VfsFindMount(path); + if (!mount) { + return -1; // Mount point not found + } + + if (mount->fs_driver && mount->fs_driver->unmount) { + int result = mount->fs_driver->unmount(mount->device); + if (result != 0) { + return result; // Filesystem-specific unmount failed + } + FsDelete(mount->mount_point); + } + + mount->active = 0; + return 0; +} + int VfsInit(void) { PrintKernel("VFS: Initializing Virtual File System...\n"); @@ -67,16 +85,16 @@ int VfsInit(void) { PrintKernel( "VFS: Mount table cleared\n"); // Register filesystems - static FileSystemDriver ntfs_driver = {"NTFS", NtfsDetect, NtfsMount}; + static FileSystemDriver ntfs_driver = {"NTFS", NtfsDetect, NtfsMount, NtfsUnmount}; FileSystemRegister(&ntfs_driver); PrintKernel("VFS: NTFS driver registered\n"); - static FileSystemDriver fat_driver = {"FAT1x", Fat1xDetect, Fat1xMount}; + static FileSystemDriver fat_driver = {"FAT1x", Fat1xDetect, Fat1xMount, Fat1xUnmount}; FileSystemRegister(&fat_driver); PrintKernel("VFS: FAT1x driver registered\n"); - static FileSystemDriver ext2_driver = {"EXT2", Ext2Detect, Ext2Mount}; + static FileSystemDriver ext2_driver = {"EXT2", Ext2Detect, Ext2Mount, Ext2Unmount}; FileSystemRegister(&ext2_driver); PrintKernel("VFS: EXT2 driver registered\n"); - static FileSystemDriver devfs_driver = {"DevFS", NULL, DevfsMount}; + static FileSystemDriver devfs_driver = {"DevFS", NULL, DevfsMount, NULL}; FileSystemRegister(&devfs_driver); PrintKernel("VFS: DevFS driver registered\n"); diff --git a/fs/VFS.h b/fs/VFS.h index 32b184e..c168773 100644 --- a/fs/VFS.h +++ b/fs/VFS.h @@ -54,6 +54,7 @@ static const char * RuntimeMounts = "/Runtime/Mounts"; // VFS Functions int VfsInit(void); int VfsMount(const char* path, BlockDevice* device, FileSystemDriver* fs_driver); +int VfsUmount(const char* path); int VfsReadFile(const char* path, void* buffer, uint32_t max_size); int VfsWriteFile(const char* path, const void* buffer, uint32_t size); int VfsListDir(const char* path); diff --git a/kernel/etc/Shell.c b/kernel/etc/Shell.c index f1cee4d..b113f1e 100644 --- a/kernel/etc/Shell.c +++ b/kernel/etc/Shell.c @@ -9,6 +9,8 @@ #include "Console.h" #include "Editor.h" #include "ExecLoader.h" +#include "Ext2.h" +#include "FAT1x.h" #include "Format.h" #include "FsUtils.h" #include "ISA.h" @@ -18,6 +20,7 @@ #include "../../mm/dynamic/rust/KernelHeapRust.h" #include "LPT/LPT.h" #include "MemOps.h" +#include "NTFS.h" #include "PCI/PCI.h" #include "PMem.h" #include "POST.h" @@ -212,6 +215,8 @@ static const HelpEntry hw_cmds[] = { {"lsusb", "List USB devices"}, {"lsblk", "List Block devices"}, {"lsmnt", "List Mountpoints"}, + {"mount ", "Mount a filesystem"}, + {"umount ", "Unmount a filesystem"}, {"beep ", "Send beep x times"}, {"pcbeep ", "PC speaker beep for seconds (200hz)"}, {"irqmask ", "Mask IRQ"}, @@ -1189,6 +1194,61 @@ static void LsMntHandler(const char* args) { VfsListMount(); } +static void MountHandler(const char* args) { + char* fs_type = GetArg(args, 1); + char* dev_name = GetArg(args, 2); + + if (!fs_type || !dev_name) { + PrintKernel("Usage: mount \n"); + if (fs_type) KernelFree(fs_type); + if (dev_name) KernelFree(dev_name); + return; + } + + BlockDevice* dev = SearchBlockDevice(dev_name); + if (!dev) { + PrintKernel("Device not found\n"); + KernelFree(fs_type); + KernelFree(dev_name); + return; + } + + char mount_point[64]; + FormatA(mount_point, sizeof(mount_point), "%s/%s", RuntimeMounts, dev_name); + + if (FastStrCmp(fs_type, "fat1x") == 0) { + Fat1xMount(dev, mount_point); + } else if (FastStrCmp(fs_type, "ext2") == 0) { + Ext2Mount(dev, mount_point); + } else if (FastStrCmp(fs_type, "ntfs") == 0) { + NtfsMount(dev, mount_point); + } else { + PrintKernel("Unknown filesystem type\n"); + } + + KernelFree(fs_type); + KernelFree(dev_name); +} + +static void UnmountHandler(const char* args) { + char* mount_point = GetArg(args, 1); + if (!mount_point) { + PrintKernel("Usage: umount \n"); + return; + } + + char new_path[256]; + ResolvePath(mount_point, new_path, 256); + + if (VfsUmount(new_path) != 0) { + PrintKernel("Failed to unmount\n"); + } else { + PrintKernel("Unmounted successfully\n"); + } + + KernelFree(mount_point); +} + FNDEF(GetSerialHandler) { char buff[1024]; SerialReadLine(buff, sizeof(buff)); @@ -1251,6 +1311,8 @@ static const ShellCommand commands[] = {\ {"lsblk", BlockDevicePrint}, {"heapperf", HeapPerfHandler}, {"lsmnt", LsMntHandler}, + {"mount", MountHandler}, + {"umount", UnmountHandler}, {"gserial", GetSerialHandler}, }; diff --git a/mm/MemPool.h b/mm/MemPool.h index 1cd8629..3ccea54 100644 --- a/mm/MemPool.h +++ b/mm/MemPool.h @@ -37,7 +37,5 @@ void* MemPoolAlloc(MemPool* pool); void MemPoolFree(MemPool* pool, void* ptr); void DestroyMemPool(MemPool* pool); void InitDefaultPools(void); -void* FastAlloc(uint64_t size); // Auto-select appropriate pool -void FastFree(void* ptr); #endif \ No newline at end of file From 2eb4af7b161ab3cd3ee0d1c087a7f84963aa6524 Mon Sep 17 00:00:00 2001 From: Atheria Date: Wed, 29 Oct 2025 19:21:17 +0700 Subject: [PATCH 2/3] ACPI proper shutdown --- drivers/ACPI.c | 34 ++++++++++++++++++++-------------- fs/VFS.c | 9 +++++++++ fs/VFS.h | 3 ++- include/Scheduler.h | 2 ++ kernel/sched/EEVDF.c | 9 +++++++++ kernel/sched/EEVDF.h | 1 + kernel/sched/MLFQ.c | 8 ++++++++ kernel/sched/MLFQ.h | 1 + kernel/sched/Scheduler.c | 10 ++++++++++ 9 files changed, 62 insertions(+), 15 deletions(-) diff --git a/drivers/ACPI.c b/drivers/ACPI.c index a04eefe..5e9f383 100644 --- a/drivers/ACPI.c +++ b/drivers/ACPI.c @@ -2,9 +2,11 @@ #include "Console.h" #include "Io.h" #include "MemOps.h" +#include "Scheduler.h" #include "StringOps.h" #include "VMem.h" #include "TSC.h" +#include "VFS.h" static ACPIFADT* g_fadt = NULL; static bool g_acpi_initialized = false; @@ -150,13 +152,17 @@ bool ACPIInit(void) { return false; } +void ACPIResetProcedure() { + PrintKernel("ACPI: Unmounting Filesystems...\n"); + VfsUnmountAll(); + PrintKernelSuccess("ACPI: Filesystems unmounted\n"); + + PrintKernel("ACPI: Stopping all processes and services...\n"); + KillAllProcess("SHUTDOWN"); + PrintKernelSuccess("ACPI: All processes and services stopped\n"); +} + void ACPIShutdown(void) { - if (!g_acpi_initialized || !g_fadt) { - PrintKernel("ACPI: Shutdown not available, using fallback\n"); - outw(0x604, 0x2000); - return; - } - PrintKernel("ACPI: Initiating shutdown...\n"); // Enable ACPI mode if needed @@ -164,11 +170,12 @@ void ACPIShutdown(void) { PrintKernel("ACPI: Enabling ACPI mode via SMI\n"); outb(g_fadt->smi_command_port, g_fadt->acpi_enable); } - + + ACPIResetProcedure(); + // Try multiple shutdown methods - uint16_t shutdown_values[] = {0x2000, 0x3C00, 0x1400, 0x0000}; - for (int i = 0; i < 4; i++) { + const uint16_t shutdown_values[] = {0x2000, 0x3C00, 0x1400, 0x0000}; PrintKernel("ACPI: Trying shutdown value 0x"); PrintKernelHex(shutdown_values[i]); PrintKernel(" on port 0x"); @@ -180,11 +187,7 @@ void ACPIShutdown(void) { // Wait a bit delay(10); } - - // Fallback methods - PrintKernel("ACPI: Trying QEMU shutdown\n"); - outw(0x604, 0x2000); - + PrintKernel("ACPI: Trying Bochs shutdown\n"); outw(0xB004, 0x2000); @@ -192,6 +195,9 @@ void ACPIShutdown(void) { } void ACPIReboot(void) { + + ACPIResetProcedure(); + PrintKernel("ACPI: Initiating reboot...\n"); // Try keyboard controller reset diff --git a/fs/VFS.c b/fs/VFS.c index 4ef650d..32404f0 100644 --- a/fs/VFS.c +++ b/fs/VFS.c @@ -76,6 +76,15 @@ int VfsUmount(const char* path) { return 0; } +int VfsUnmountAll() { + for (int i = 0; i < VFS_MAX_MOUNTS; i++) { + if (mounts[i].active) { + VfsUmount(mounts[i].mount_point); + } + } + return 0; +} + int VfsInit(void) { PrintKernel("VFS: Initializing Virtual File System...\n"); diff --git a/fs/VFS.h b/fs/VFS.h index c168773..863461a 100644 --- a/fs/VFS.h +++ b/fs/VFS.h @@ -102,4 +102,5 @@ int VfsAnalyze(const char* path, uint32_t* byte_counts, uint32_t* entropy); // Internal VfsMountStruct* VfsFindMount(const char* path); void VfsListMount(void); -const char* VfsStripMount(const char* path, VfsMountStruct* mount); \ No newline at end of file +const char* VfsStripMount(const char* path, VfsMountStruct* mount); +int VfsUnmountAll(); \ No newline at end of file diff --git a/include/Scheduler.h b/include/Scheduler.h index fbaf0b0..b1f6c95 100644 --- a/include/Scheduler.h +++ b/include/Scheduler.h @@ -56,6 +56,8 @@ void KillProcess(uint32_t pid); void KillCurrentProcess(const char * reason); +void KillAllProcess(const char* reason); + // List processes void ListProcesses(); diff --git a/kernel/sched/EEVDF.c b/kernel/sched/EEVDF.c index a998c50..8cc64df 100644 --- a/kernel/sched/EEVDF.c +++ b/kernel/sched/EEVDF.c @@ -1318,6 +1318,15 @@ void EEVDFKillProcess(uint32_t pid) { EEVDFTerminateProcess(pid, TERM_KILLED, 1); } +void EEVDFKillAllProcesses(const char* reason) { + for (int i = 0; i < EEVDF_MAX_PROCESSES; i++) { + EEVDFProcessControlBlock* proc = &processes[i]; + if (proc->state != PROC_TERMINATED && proc->pid != 0) { + EEVDFASTerminate(proc->pid, reason); + } + } +} + void EEVDFKillCurrentProcess(const char* reason) { EEVDFProcessControlBlock* current = EEVDFGetCurrentProcess(); if (current) EEVDFASTerminate(current->pid, reason); diff --git a/kernel/sched/EEVDF.h b/kernel/sched/EEVDF.h index d1ade62..4d8433c 100644 --- a/kernel/sched/EEVDF.h +++ b/kernel/sched/EEVDF.h @@ -201,6 +201,7 @@ void EEVDFYield(void); void EEVDFSchedule(Registers* regs); void EEVDFKillProcess(uint32_t pid); void EEVDFKillCurrentProcess(const char* reason); +void EEVDFKillAllProcesses(const char* reason); // Time management uint64_t EEVDFGetSystemTicks(void); diff --git a/kernel/sched/MLFQ.c b/kernel/sched/MLFQ.c index 076ecc6..86cc66b 100644 --- a/kernel/sched/MLFQ.c +++ b/kernel/sched/MLFQ.c @@ -1917,7 +1917,15 @@ void MLFQDumpSchedulerState(void) { void MLFQKillCurrentProcess(const char * reason) { MLFQProcessControlBlock* current = MLFQGetCurrentProcess(); if (current) ASTerminate(current->pid, reason); +} +void MLFQKillAllProcesses(const char * reason) { + for (int i = 1; i < MAX_PROCESSES; i++) { + MLFQProcessControlBlock* p = &processes[i]; + if (p->state != PROC_TERMINATED && p->pid != 0) { + ASTerminate(p->pid, reason); + } + } } // Get detailed process scheduling information diff --git a/kernel/sched/MLFQ.h b/kernel/sched/MLFQ.h index 58e24a2..d98a001 100644 --- a/kernel/sched/MLFQ.h +++ b/kernel/sched/MLFQ.h @@ -220,6 +220,7 @@ uint64_t MLFQGetSystemTicks(void); void MLFQListProcesses(void); void MLFQGetProcessStats(uint32_t pid, uint32_t* cpu_time, uint32_t* io_ops, uint32_t* preemptions); void MLFQKillProcess(uint32_t pid); +void MLFQKillAllProcesses(const char* reason); // DEBUG void MLFQDumpPerformanceStats(void); diff --git a/kernel/sched/Scheduler.c b/kernel/sched/Scheduler.c index 2855d65..36f03df 100644 --- a/kernel/sched/Scheduler.c +++ b/kernel/sched/Scheduler.c @@ -85,6 +85,16 @@ void KillProcess(uint32_t pid) { #endif } +void KillAllProcess(const char* reason) { +#if defined(VF_CONFIG_SCHED_MLFQ) + return MLFQKillAllProcess(reason); +#elif defined(VF_CONFIG_SCHED_EEVDF) + return EEVDFKillAllProcesses(reason); +#elif defined(VF_CONFIG_SCHED_CFS) + return; // not implemented +#endif +} + void KillCurrentProcess(const char * reason) { #if defined(VF_CONFIG_SCHED_MLFQ) return MLFQKillCurrentProcess(reason); From f570445b819fdc485ee73a0361a7921150fb4343 Mon Sep 17 00:00:00 2001 From: Atheria Date: Wed, 29 Oct 2025 20:00:32 +0700 Subject: [PATCH 3/3] ACPI proper shutdown --- CMakeLists.txt | 2 +- README.md | 19 +----- drivers/ACPI.c | 137 +++++++++++++++++++-------------------- drivers/ACPI.h | 3 +- fs/EXT/Ext2.c | 28 ++++---- fs/FAT/FAT1x.c | 10 +++ fs/VFS.c | 2 +- kernel/sched/EEVDF.c | 2 +- kernel/sched/EEVDF.h | 2 +- kernel/sched/MLFQ.h | 2 +- kernel/sched/Scheduler.c | 2 +- 11 files changed, 100 insertions(+), 109 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6acb0b3..8dd6ecd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,7 +217,7 @@ add_custom_target(extra-img COMMAND ${QEMU_IMG} create -f raw VirtioDisk.img 128M COMMAND ${MKFS_EXT2} VirtioDisk.img COMMAND ${QEMU_IMG} create -f raw SataDisk.img 128M - COMMAND ${MKFS_EXT2} SataDisk.img + COMMAND ${MKFS_FAT} -F12 SataDisk.img COMMAND ${QEMU_IMG} create -f raw NVMeDisk.img 256M COMMAND ${MKFS_EXT2} NVMeDisk.img COMMENT "Creating extra disk images" diff --git a/README.md b/README.md index f817b4f..95daf63 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # [VoidFrame] - a ring 0 kernel 💫 -> A fast, simple, secure 64-bit ring-0 kernel written in C and assembly. With modern capabilities. +> A fast, simple, secure 64-bit ring-0 kernel written in C (Rust) and assembly. With modern capabilities. --- -- How it works: [here!](docs/ARCHITECTURE.md) +- How it works (outdated): [here!](docs/ARCHITECTURE.md) - Development Guide: [here!](docs/DEVELOPMENT.md) --- @@ -28,7 +28,6 @@ It would be amazing if you could contribute to this project! - x64-compatible cpu (used: Intel i3-12100F) - POSIX-compliant OS (SysV ABI) (used: Arch Linux 6.16.9-arch1-1) - cmake >= 3.20 (used: cmake 4.1.2) -- meson >= 1.4 (used: meson 1.9.1) - ninja >= 1.11 (used: ninja 1.21.1) - clang/++ >= 18.0.0 (used: 20.1.8) - rustup (nightly, bare metal toolchain) >= 1.89.0 (used: 1.92.0-nightly) @@ -40,18 +39,6 @@ It would be amazing if you could contribute to this project! - Note: depending on your distro, grub-mkrescue may require xorriso and mtools packages. ### Quickstart -#### Full development setup -```bash -# Meson -git clone https://github.com/assembler-0/VoidFrame.git -cd VoidFrame -meson setup build -cd build -ninja -j$(nproc) -ninja img -ninja extra-img -ninja run -``` ```bash # CMake git clone https://github.com/assembler-0/VoidFrame.git @@ -61,7 +48,7 @@ cd build cmake .. -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/linux-x64.cmake \ -G Ninja \ - -DVF_SCHEDULER= + -DVF_SCHEDULER=EEVDF ccmake . # Optinal, tune as needed ninja -j$(nproc) ninja run diff --git a/drivers/ACPI.c b/drivers/ACPI.c index 5e9f383..9c780c9 100644 --- a/drivers/ACPI.c +++ b/drivers/ACPI.c @@ -49,107 +49,100 @@ static bool ValidateChecksum(void* table, uint32_t length) { // Map ACPI table to virtual memory static void* MapACPITable(uint32_t phys_addr, uint32_t size) { - // Align to page boundaries - uint32_t aligned_addr = phys_addr & ~0xFFF; - uint32_t offset = phys_addr - aligned_addr; - uint32_t aligned_size = ((size + offset + 0xFFF) & ~0xFFF); - + uint64_t aligned_addr = phys_addr & ~0xFFF; + uint64_t offset = phys_addr - aligned_addr; + uint64_t aligned_size = ((size + offset + 0xFFF) & ~0xFFF); + void* virt_addr = VMemAlloc(aligned_size); - if (!virt_addr) return NULL; - + if (!virt_addr) { + PrintKernelError("ACPI: Failed to allocate virtual memory for ACPI table\n"); + return NULL; + } + if (VMemUnmap((uint64_t)virt_addr, aligned_size) != VMEM_SUCCESS) { VMemFree(virt_addr, aligned_size); + PrintKernelError("ACPI: Failed to unmap virtual memory for ACPI table\n"); return NULL; } - + if (VMemMapMMIO((uint64_t)virt_addr, aligned_addr, aligned_size, PAGE_WRITABLE | PAGE_NOCACHE) != VMEM_SUCCESS) { - VMemFree(virt_addr, aligned_size); + // No need to free here as VMemMapMMIO should handle cleanup on failure + PrintKernelError("ACPI: Failed to map MMIO for ACPI table\n"); return NULL; } - + return (uint8_t*)virt_addr + offset; } +static ACPIRSDT* g_rsdt = NULL; + +void* AcpiFindTable(const char* signature) { + if (!g_rsdt) { + return NULL; + } + + uint32_t entries = (g_rsdt->header.length - sizeof(ACPISDTHeader)) / 4; + for (uint32_t i = 0; i < entries; i++) { + ACPISDTHeader* header = (ACPISDTHeader*)MapACPITable(g_rsdt->table_pointers[i], sizeof(ACPISDTHeader)); + if (!header) { + continue; + } + + if (FastMemcmp(header->signature, signature, 4) == 0) { + void* table = MapACPITable(g_rsdt->table_pointers[i], header->length); + VMemUnmap((uint64_t)header - (g_rsdt->table_pointers[i] & 0xFFF), ((sizeof(ACPISDTHeader) + (g_rsdt->table_pointers[i] & 0xFFF) + 0xFFF) & ~0xFFF)); + return table; + } + + VMemUnmap((uint64_t)header - (g_rsdt->table_pointers[i] & 0xFFF), ((sizeof(ACPISDTHeader) + (g_rsdt->table_pointers[i] & 0xFFF) + 0xFFF) & ~0xFFF)); + } + + return NULL; +} + bool ACPIInit(void) { PrintKernel("ACPI: Initializing ACPI subsystem...\n"); - - // Find RSDP + ACPIRSDPv1* rsdp = FindRSDP(); if (!rsdp) { PrintKernelError("ACPI: RSDP not found\n"); return false; } - - PrintKernel("ACPI: Found RSDP at 0x"); - PrintKernelHex((uint64_t)rsdp); - PrintKernel("\n"); - - // Validate RSDP checksum + if (!ValidateChecksum(rsdp, sizeof(ACPIRSDPv1))) { PrintKernelError("ACPI: Invalid RSDP checksum\n"); return false; } - ACPIRSDT* rsdt = (ACPIRSDT*)MapACPITable(rsdp->rsdt_address, - sizeof(ACPISDTHeader)); - if (!rsdt) { - PrintKernelError("ACPI: Failed to map RSDT\n"); + g_rsdt = (ACPIRSDT*)MapACPITable(rsdp->rsdt_address, sizeof(ACPISDTHeader)); + if (!g_rsdt) { + PrintKernelError("ACPI: Failed to map RSDT header\n"); return false; } - // Validate RSDT signature - if (FastMemcmp(rsdt->header.signature, ACPI_RSDT_SIG, 4) != 0) { + + if (FastMemcmp(g_rsdt->header.signature, ACPI_RSDT_SIG, 4) != 0) { PrintKernelError("ACPI: Invalid RSDT signature\n"); - // Clean up the initial header‐only mapping - VMemUnmap((uint64_t)rsdt - (rsdp->rsdt_address & 0xFFF), - ((sizeof(ACPISDTHeader) + (rsdp->rsdt_address & 0xFFF) + 0xFFF) - & ~0xFFF)); + VMemUnmap((uint64_t)g_rsdt - (rsdp->rsdt_address & 0xFFF), ((sizeof(ACPISDTHeader) + (rsdp->rsdt_address & 0xFFF) + 0xFFF) & ~0xFFF)); return false; } - // Remap with the full table length - uint32_t rsdt_size = rsdt->header.length; - // Remember the old header mapping so we can free it afterward - void* old_rsdt = rsdt; - uint32_t old_offset = rsdp->rsdt_address & 0xFFF; - rsdt = (ACPIRSDT*)MapACPITable(rsdp->rsdt_address, rsdt_size); - // Now unmap the temporary header‐only region - VMemUnmap((uint64_t)old_rsdt - old_offset, - ((sizeof(ACPISDTHeader) + old_offset + 0xFFF) & ~0xFFF)); - - PrintKernel("ACPI: RSDT mapped, length="); - PrintKernelInt(rsdt_size); - PrintKernel("\n"); - - // Find FADT - uint32_t entries = (rsdt_size - sizeof(ACPISDTHeader)) / 4; - for (uint32_t i = 0; i < entries; i++) { - ACPISDTHeader* header = (ACPISDTHeader*)MapACPITable( - rsdt->table_pointers[i], - sizeof(ACPISDTHeader) - ); - if (!header) continue; - - bool is_fadt = FastMemcmp(header->signature, ACPI_FADT_SIG, 4) == 0; - uint32_t table_length = header->length; - uint32_t header_offset = rsdt->table_pointers[i] & 0xFFF; - - // Unmap the header mapping now that we've inspected it - VMemUnmap( - (uint64_t)header - header_offset, - ( (sizeof(ACPISDTHeader) + header_offset + 0xFFF) & ~0xFFF ) - ); - - if (is_fadt) { - PrintKernel("ACPI: Found FADT\n"); - g_fadt = (ACPIFADT*)MapACPITable( - rsdt->table_pointers[i], - table_length - ); - break; - } + + uint32_t rsdt_size = g_rsdt->header.length; + VMemUnmap((uint64_t)g_rsdt - (rsdp->rsdt_address & 0xFFF), ((sizeof(ACPISDTHeader) + (rsdp->rsdt_address & 0xFFF) + 0xFFF) & ~0xFFF)); + g_rsdt = (ACPIRSDT*)MapACPITable(rsdp->rsdt_address, rsdt_size); + if (!g_rsdt) { + PrintKernelError("ACPI: Failed to map full RSDT\n"); + return false; } - - PrintKernelError("ACPI: FADT not found or invalid\n"); - return false; + + g_fadt = (ACPIFADT*)AcpiFindTable(ACPI_FADT_SIG); + if (!g_fadt) { + PrintKernelError("ACPI: FADT not found or invalid\n"); + return false; + } + + g_acpi_initialized = true; + PrintKernelSuccess("ACPI: Subsystem initialized\n"); + return true; } void ACPIResetProcedure() { diff --git a/drivers/ACPI.h b/drivers/ACPI.h index da00da1..24b814f 100644 --- a/drivers/ACPI.h +++ b/drivers/ACPI.h @@ -82,4 +82,5 @@ typedef struct { // Function declarations bool ACPIInit(void); void ACPIShutdown(void); -void ACPIReboot(void); \ No newline at end of file +void ACPIReboot(void); +void* AcpiFindTable(const char* signature); \ No newline at end of file diff --git a/fs/EXT/Ext2.c b/fs/EXT/Ext2.c index ca93e34..bca8c28 100644 --- a/fs/EXT/Ext2.c +++ b/fs/EXT/Ext2.c @@ -228,28 +228,28 @@ int Ext2Mount(BlockDevice* device, const char* mount_point) { } int Ext2Unmount(BlockDevice* device) { - if (!device) return -1; - int id = device->id; - if (id < 0 || id >= MAX_BLOCK_DEVICES) return -1; - - Ext2Volume* vol = g_ext2_by_dev[id]; - if (!vol) return -1; // Not mounted - + if (!device) { return -1; } + int device_id = device->id; + if (device_id < 0 || device_id >= MAX_BLOCK_DEVICES) { return -1; } + Ext2Volume* vol = g_ext2_by_dev[device_id]; + if (!vol) { return -1; } // Not mounted + RustRwLock* lock = vol->lock; + if (lock) { + rust_rwlock_write_lock(lock, GetCurrentProcess()->pid); + } if (g_ext2_active == vol) { g_ext2_active = NULL; } - if (vol->group_descs) { KernelFree(vol->group_descs); + vol->group_descs = NULL; } - - if (vol->lock) { - rust_rwlock_free(vol->lock); + g_ext2_by_dev[device_id] = NULL; + if (lock) { + rust_rwlock_write_unlock(lock); + rust_rwlock_free(lock); } - KernelFree(vol); - g_ext2_by_dev[id] = NULL; - return 0; } diff --git a/fs/FAT/FAT1x.c b/fs/FAT/FAT1x.c index 75c91a5..f625345 100644 --- a/fs/FAT/FAT1x.c +++ b/fs/FAT/FAT1x.c @@ -59,16 +59,22 @@ int Fat1xMount(BlockDevice* device, const char* mount_point) { // Read boot sector uint8_t boot_sector[512]; if (BlockDeviceRead(device->id, 0, 1, boot_sector) != 0) { + g_fat1x_by_dev[device->id] = NULL; // Critical: Free volume if read fails + KernelFree(vol); return -1; } FastMemcpy(&volume.boot, boot_sector, sizeof(Fat1xBootSector)); if (volume.boot.bytes_per_sector != 512) { + g_fat1x_by_dev[device->id] = NULL; // Critical: Free volume if read fails + KernelFree(vol); return -1; } sector_buffer = KernelMemoryAlloc(POOL_SIZE_512); if (!sector_buffer) { + g_fat1x_by_dev[device->id] = NULL; // Critical: Free volume if read fails + KernelFree(vol); return -1; } @@ -111,6 +117,10 @@ int Fat1xUnmount(BlockDevice* device) { g_fat1x_active = NULL; } + // if (vol->fat_table) { + // KernelFree(vol->fat_table); + // vol->fat_table = NULL; + // } KernelFree(vol); g_fat1x_by_dev[id] = NULL; diff --git a/fs/VFS.c b/fs/VFS.c index 32404f0..aa7f51d 100644 --- a/fs/VFS.c +++ b/fs/VFS.c @@ -77,7 +77,7 @@ int VfsUmount(const char* path) { } int VfsUnmountAll() { - for (int i = 0; i < VFS_MAX_MOUNTS; i++) { + for (int i = VFS_MAX_MOUNTS - 1; i >= 0; i--) { if (mounts[i].active) { VfsUmount(mounts[i].mount_point); } diff --git a/kernel/sched/EEVDF.c b/kernel/sched/EEVDF.c index 8cc64df..8ca201d 100644 --- a/kernel/sched/EEVDF.c +++ b/kernel/sched/EEVDF.c @@ -1318,7 +1318,7 @@ void EEVDFKillProcess(uint32_t pid) { EEVDFTerminateProcess(pid, TERM_KILLED, 1); } -void EEVDFKillAllProcesses(const char* reason) { +void EEVDFKillAllProcess(const char* reason) { for (int i = 0; i < EEVDF_MAX_PROCESSES; i++) { EEVDFProcessControlBlock* proc = &processes[i]; if (proc->state != PROC_TERMINATED && proc->pid != 0) { diff --git a/kernel/sched/EEVDF.h b/kernel/sched/EEVDF.h index 4d8433c..add6542 100644 --- a/kernel/sched/EEVDF.h +++ b/kernel/sched/EEVDF.h @@ -201,7 +201,7 @@ void EEVDFYield(void); void EEVDFSchedule(Registers* regs); void EEVDFKillProcess(uint32_t pid); void EEVDFKillCurrentProcess(const char* reason); -void EEVDFKillAllProcesses(const char* reason); +void EEVDFKillAllProcess(const char* reason); // Time management uint64_t EEVDFGetSystemTicks(void); diff --git a/kernel/sched/MLFQ.h b/kernel/sched/MLFQ.h index d98a001..d1a1e7a 100644 --- a/kernel/sched/MLFQ.h +++ b/kernel/sched/MLFQ.h @@ -220,7 +220,7 @@ uint64_t MLFQGetSystemTicks(void); void MLFQListProcesses(void); void MLFQGetProcessStats(uint32_t pid, uint32_t* cpu_time, uint32_t* io_ops, uint32_t* preemptions); void MLFQKillProcess(uint32_t pid); -void MLFQKillAllProcesses(const char* reason); +void MLFQKillAllProcess(const char* reason); // DEBUG void MLFQDumpPerformanceStats(void); diff --git a/kernel/sched/Scheduler.c b/kernel/sched/Scheduler.c index 36f03df..e60b513 100644 --- a/kernel/sched/Scheduler.c +++ b/kernel/sched/Scheduler.c @@ -89,7 +89,7 @@ void KillAllProcess(const char* reason) { #if defined(VF_CONFIG_SCHED_MLFQ) return MLFQKillAllProcess(reason); #elif defined(VF_CONFIG_SCHED_EEVDF) - return EEVDFKillAllProcesses(reason); + return EEVDFKillAllProcess(reason); #elif defined(VF_CONFIG_SCHED_CFS) return; // not implemented #endif