Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion fs/FAT12.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "Ide.h"
#include "KernelHeap.h"
#include "MemOps.h"
#include "MemPool.h"

static Fat12Volume volume;
static uint8_t* sector_buffer = NULL;
Expand All @@ -29,7 +30,7 @@ int Fat12Init(uint8_t drive) {
}

// Allocate sector buffer
sector_buffer = KernelMemoryAlloc(512);
sector_buffer = FastAlloc(POOL_SIZE_512);
if (!sector_buffer) {
return -1;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/VFS.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ int VfsInit(void) {
if (result != 0) {
SerialWrite("[VFS] Failed to mount root\n");
}
SerialWrite("[VFS] Root mounted");
SerialWrite("[VFS] Root mounted\n");

// Only mount FAT12 if it was successfully initialized
extern int fat12_initialized;
Expand Down
221 changes: 166 additions & 55 deletions kernel/core/Kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "stdbool.h"
#include "stdint.h"
#include "FAT12.h"
#include "MemPool.h"

void KernelMainHigherHalf(void);
#define KERNEL_STACK_SIZE (16 * 1024) // 16KB stack
Expand Down Expand Up @@ -60,32 +61,43 @@ void ParseMultibootInfo(uint32_t info) {
PrintKernelSuccess("[SYSTEM] Multiboot2 info parsed.\n");
}

uint64_t AllocPageTable(const char* table_name) {
(void)table_name;
uint64_t table_phys = 0;
for (int attempt = 0; attempt < 32; attempt++) {
void* candidate = AllocPage();
if (!candidate) {
PANIC("Bootstrap: Out of memory allocating");
}
if ((uint64_t)candidate < IDENTITY_MAP_SIZE) {
table_phys = (uint64_t)candidate;
break;
}
FreePage(candidate);
}
if (!table_phys) {
PANIC("Bootstrap: Failed to allocate in identity-mapped memory");
}
if (table_phys & 0xFFF) PANIC("Page table not aligned");
FastZeroPage((void*)table_phys);
return table_phys;
}

void BootstrapMapPage(uint64_t pml4_phys, uint64_t vaddr, uint64_t paddr, uint64_t flags) {
// Input validation for safety
// Input validation
if (!pml4_phys || (pml4_phys & 0xFFF)) PANIC("Invalid PML4 address");
// align
if (vaddr & 0xFFF || paddr & 0xFFF) {
vaddr &= ~0xFFF; // Page-align virtual address
paddr &= ~0xFFF; // Page-align physical address
}

uint64_t* pml4 = (uint64_t*)pml4_phys;

// 1. Get/Create PDPT with validation
// 1. Get/Create PDPT
int pml4_idx = (vaddr >> 39) & 0x1FF;
uint64_t pdpt_phys;
if (!(pml4[pml4_idx] & PAGE_PRESENT)) {
// allocate PDPT in identity-mapped region
pdpt_phys = 0;
for (int attempt = 0; attempt < 32; attempt++) {
void* candidate = AllocPage();
if (!candidate) break;
if ((uint64_t)candidate < IDENTITY_MAP_SIZE) { pdpt_phys = (uint64_t)candidate; break; }
FreePage(candidate);
}
if (!pdpt_phys) PANIC("BootstrapMapPage: Out of memory for PDPT");
if (pdpt_phys & 0xFFF) PANIC("PDPT not aligned");
FastZeroPage((void*)pdpt_phys);
pdpt_phys = AllocPageTable("PDPT");
pml4[pml4_idx] = pdpt_phys | PAGE_PRESENT | PAGE_WRITABLE;
} else {
pdpt_phys = pml4[pml4_idx] & PT_ADDR_MASK;
Expand All @@ -97,16 +109,7 @@ void BootstrapMapPage(uint64_t pml4_phys, uint64_t vaddr, uint64_t paddr, uint64
int pdpt_idx = (vaddr >> 30) & 0x1FF;
uint64_t pd_phys;
if (!(pdpt[pdpt_idx] & PAGE_PRESENT)) {
// allocate PD in identity-mapped region
pd_phys = 0;
for (int attempt = 0; attempt < 32; attempt++) {
void* candidate = AllocPage();
if (!candidate) break;
if ((uint64_t)candidate < IDENTITY_MAP_SIZE) { pd_phys = (uint64_t)candidate; break; }
FreePage(candidate);
}
if (!pd_phys) PANIC("BootstrapMapPage: Out of memory for PD");
FastZeroPage((void*)pd_phys);
pd_phys = AllocPageTable("PD");
pdpt[pdpt_idx] = pd_phys | PAGE_PRESENT | PAGE_WRITABLE;
} else {
pd_phys = pdpt[pdpt_idx] & PT_ADDR_MASK;
Expand All @@ -117,27 +120,47 @@ void BootstrapMapPage(uint64_t pml4_phys, uint64_t vaddr, uint64_t paddr, uint64
const int pd_idx = (vaddr >> 21) & 0x1FF;
uint64_t pt_phys;
if (!(pd[pd_idx] & PAGE_PRESENT)) {
// allocate PT in identity-mapped region
pt_phys = 0;
for (int attempt = 0; attempt < 32; attempt++) {
void* candidate = AllocPage();
if (!candidate) break;
if ((uint64_t)candidate < IDENTITY_MAP_SIZE) { pt_phys = (uint64_t)candidate; break; }
FreePage(candidate);
}
if (!pt_phys) PANIC("BootstrapMapPage: Out of memory for PT");
FastZeroPage((void*)pt_phys);
pt_phys = AllocPageTable("PT");
pd[pd_idx] = pt_phys | PAGE_PRESENT | PAGE_WRITABLE;
} else {
pt_phys = pd[pd_idx] & PT_ADDR_MASK;
}

// 4. Set the final PTE
// 4. Set the final PTE with validation
uint64_t* pt = (uint64_t*)pt_phys;
const int pt_idx = (vaddr >> 12) & 0x1FF;

// NEW: Check for remapping
if (pt[pt_idx] & PAGE_PRESENT) {
uint64_t existing_paddr = pt[pt_idx] & PT_ADDR_MASK;
if (existing_paddr != paddr) {
PrintKernelWarning("[BOOTSTRAP] Remapping 0x");
PrintKernelHex(vaddr);
PrintKernel(" from 0x");
PrintKernelHex(existing_paddr);
PrintKernel(" to 0x");
PrintKernelHex(paddr);
PrintKernel("\n");
}
}

pt[pt_idx] = paddr | flags | PAGE_PRESENT;

static uint64_t pages_mapped = 0;
pages_mapped++;

// Show progress every 64K pages (256MB)
if (pages_mapped % 65536 == 0) {
PrintKernelInt((pages_mapped * PAGE_SIZE) / (1024 * 1024));
PrintKernel("MB ");
}
// Show dots every 16K pages (64MB) for finer progress
else if (pages_mapped % 16384 == 0) {
PrintKernel(".");
}
}


// Memory hardening functions
static void SetupMemoryProtection(void) {
PrintKernel("[SYSTEM] Setting up memory protection...\n");
Expand Down Expand Up @@ -197,23 +220,54 @@ static void SetupMemoryProtection(void) {
}
}

static bool CheckHugePageSupport(void) {
uint32_t eax, ebx, ecx, edx;

// Check for PSE (Page Size Extension) - required for 2MB pages
__asm__ volatile("cpuid" : "=a"(eax), "=d"(edx) : "a"(1) : "ebx", "ecx");
if (!(edx & (1 << 3))) {
PrintKernel("[INFO] PSE not supported - no huge pages\n");
return false;
}

// Check for PSE-36 for extended physical addressing
if (edx & (1 << 17)) {
PrintKernel("[INFO] PSE-36 supported\n");
}

return true;
}

// Enhanced CoreInit function with memory enhancements
static InitResultT CoreInit(void) {
// Initialize virtual memory manager with validation
PrintKernel("[INFO] Initializing virtual memory manager...\n");
VMemInit();
PrintKernelSuccess("[SYSTEM] Virtual memory manager initialized\n");

// Initialize kernel heap with memory statistics
PrintKernel("[INFO] Initializing kernel heap...\n");
KernelHeapInit();
PrintKernelSuccess("[SYSTEM] Kernel heap initialized\n");

// Display memory statistics for monitoring
PrintKernel("[INFO] Memory statistics:\n");
// Add memory usage display here if available

// NEW: Initialize memory pools early for efficient small allocations
PrintKernel("[INFO] Initializing memory pools...\n");
InitDefaultPools();
PrintKernelSuccess("[SYSTEM] Memory pools initialized\n");

// NEW: Display detailed memory statistics
PrintKernel("[INFO] Initial memory statistics:\n");
MemoryStats stats;
GetDetailedMemoryStats(&stats);
PrintKernel(" Physical: ");
PrintKernelInt(stats.free_physical_bytes / (1024*1024));
PrintKernel("MB free, ");
PrintKernelInt(stats.fragmentation_score);
PrintKernel("% fragmented\n");
PrintVMemStats();

PrintKernel("[INFO] Initializing GDT...\n");
GdtInit(); // void function - assume success
GdtInit();
PrintKernelSuccess("[SYSTEM] GDT initialized\n");

// Initialize CPU features
Expand All @@ -223,32 +277,32 @@ static InitResultT CoreInit(void) {

// Initialize IDT
PrintKernel("[INFO] Initializing IDT...\n");
IdtInstall(); // void function - assume success
IdtInstall();
PrintKernelSuccess("[SYSTEM] IDT initialized\n");

// Initialize System Calls
PrintKernel("[INFO] Initializing system calls...\n");
SyscallInit(); // void function - assume success
SyscallInit();
PrintKernelSuccess("[SYSTEM] System calls initialized\n");

// Initialize PIC
PrintKernel("[INFO] Initializing PIC...\n");
PicInstall(); // void function - assume success
PicInstall();
PrintKernelSuccess("[SYSTEM] PIC initialized\n");

// Initialize keyboard
PrintKernel("[INFO] Initializing keyboard...\n");
KeyboardInit();
PrintKernelSuccess("[SYSTEM] Keyboard initialized\n");

// Initialize shell
PrintKernel("[INFO] Initializing shell...\n");
ShellInit();
PrintKernelSuccess("[SYSTEM] Shell initialized\n");

// Initialize Process Management
PrintKernel("[INFO] Initializing process management...\n");
ProcessInit(); // void function - assume success
ProcessInit();
PrintKernelSuccess("[SYSTEM] Process management initialized\n");

PrintKernel("[INFO] Initializing serial driver management...\n");
Expand All @@ -260,8 +314,8 @@ static InitResultT CoreInit(void) {
int ide_result = IdeInit();
if (ide_result == IDE_OK) {
PrintKernelSuccess("[SYSTEM] IDE driver initialized\n");
// Explicitly initialize FAT12 before VFS (explicit > auto-detect)

// Explicitly initialize FAT12 before VFS
PrintKernel("[INFO] Initializing FAT12...\n");
if (Fat12Init(0) == 0) {
PrintKernelSuccess("[SYSTEM] FAT12 Driver initialized\n");
Expand All @@ -277,16 +331,29 @@ static InitResultT CoreInit(void) {
PrintKernel("[INFO] Initializing VFRFS...\n");
FsInit();
PrintKernelSuccess("[SYSTEM] VFRFS (VoidFrame RamFS) initialized\n");

// Initialize VFS
PrintKernel("[INFO] Initializing VFS...\n");
VfsInit();
PrintKernelSuccess("[SYSTEM] VFS initialized\n");

// NEW: Check if huge pages should be enabled
PrintKernel("[INFO] Checking huge page support...\n");
if (CheckHugePageSupport()) {
PrintKernelSuccess("[SYSTEM] Huge pages available\n");
}

// Setup memory protection LAST - after all systems are ready
StackGuardInit();
SetupMemoryProtection();


// NEW: Final memory health check
PrintKernel("[INFO] Final memory health check...\n");
GetDetailedMemoryStats(&stats);
if (stats.fragmentation_score > 50) {
PrintKernelWarning("[WARN] High memory fragmentation detected\n");
}

return INIT_SUCCESS;
}

Expand All @@ -312,6 +379,7 @@ void KernelMain(const uint32_t magic, const uint32_t info) {
// Initialize physical memory manager first
MemoryInit(g_multiboot_info_addr);


// Create new PML4 with memory validation (ensure identity-mapped physical page)
void* pml4_phys = NULL;
for (int attempt = 0; attempt < 64; attempt++) {
Expand Down Expand Up @@ -371,25 +439,68 @@ static void ValidateMemoryLayout(void) {
PrintKernel(" (");
PrintKernelInt(kernel_size / 1024);
PrintKernel(" KB)\n");

// Check for dangerous overlaps
uint64_t stack_start = (uint64_t)kernel_stack;
uint64_t stack_end = stack_start + KERNEL_STACK_SIZE;

if ((stack_start >= kernel_start && stack_start < kernel_end) ||
(stack_end > kernel_start && stack_end <= kernel_end)) {
PrintKernelWarning("[WARNING] Stack overlaps with kernel code\n");
}

// NEW: Check multiboot info location
if (g_multiboot_info_addr >= kernel_start && g_multiboot_info_addr < kernel_end) {
PrintKernelWarning("[WARNING] Multiboot info overlaps with kernel\n");
}


// NEW: Validate virtual address space boundaries
if (VIRT_ADDR_SPACE_START >= KERNEL_SPACE_START) {
PrintKernelError("[ERROR] Virtual address space overlaps with kernel space\n");
}


PrintKernelSuccess("[SYSTEM] Memory layout validated\n");
}

static void PrintBootstrapSummary(void) {
PrintKernel("\n[BOOTSTRAP] Summary:\n");

// Count page table pages used
uint64_t pt_pages = 0;
for (uint64_t i = 0x100000 / PAGE_SIZE; i < total_pages; i++) {
if (!IsPageFree(i)) {
uint64_t addr = i * PAGE_SIZE;
// Heuristic: if it's not kernel or stack, likely a page table
if (addr < (uint64_t)_kernel_phys_start ||
addr >= (uint64_t)_kernel_phys_end) {
pt_pages++;
}
}
}

PrintKernel(" Identity mapping: 4GB (");
PrintKernelInt(IDENTITY_MAP_SIZE / (1024 * 1024 * 1024));
PrintKernel("GB)\n");

PrintKernel(" Page tables: ~");
PrintKernelInt(pt_pages);
PrintKernel(" pages (");
PrintKernelInt((pt_pages * PAGE_SIZE) / 1024);
PrintKernel("KB)\n");

PrintKernel(" Bootstrap complete\n");
}

void KernelMainHigherHalf(void) {
PrintKernelSuccess("[SYSTEM] Successfully jumped to higher half. Virtual memory is active.\n");

// Memory safety validation
ValidateMemoryLayout();


// Print bootstrap summary
PrintBootstrapSummary();

// Initialize core systems
CoreInit();

Expand Down
Loading