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
15 changes: 14 additions & 1 deletion arch/x86_64/interrupts/Interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "Keyboard.h"
#include "Panic.h"
#include "Process.h"

#include "Serial.h"
// The C-level interrupt handler, called from the assembly stub
void InterruptHandler(Registers* regs) {
ASSERT(regs != NULL);
Expand Down Expand Up @@ -72,9 +72,22 @@ void InterruptHandler(Registers* regs) {
uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(cr2));

// Serial logging for debugging
SerialWrite("\n[PAGEFAULT] CR2: 0x");
SerialWriteHex(cr2);
SerialWrite(" RIP: 0x");
SerialWriteHex(regs->rip);
SerialWrite(" RSP: 0x");
SerialWriteHex(regs->rsp);
SerialWrite(" Error: 0x");
SerialWriteHex(regs->error_code);
SerialWrite("\n");

PrintKernelError(" TYPE: Page Fault (PF)\n");
PrintKernelError(" Faulting Address: ");
PrintKernelHex(cr2);
PrintKernelError("\n RIP: ");
PrintKernelHex(regs->rip);
PrintKernelError("\n Error Code: ");
PrintKernelHex(regs->error_code);
PrintKernelError("\n Details:\n");
Expand Down
38 changes: 20 additions & 18 deletions drivers/Ide.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,35 @@ static volatile int ide_lock = 0;

// Wait for drive to be ready (not busy)
static int IdeWaitReady(uint16_t base_port) {
uint32_t timeout = 100000; // ~100ms timeout
uint32_t timeout = 500000; // Increased timeout for QEMU

while (timeout--) {
uint8_t status = inb(base_port + IDE_REG_STATUS);
if (!(status & IDE_STATUS_BSY)) {
if (status & IDE_STATUS_ERR) {
if (status & IDE_STATUS_ERR)
return IDE_ERROR_IO;
}
return IDE_OK;
return IDE_OK; // Don't require RDY bit
}
// Small delay
for (volatile int i = 0; i < 100; i++);
}
return IDE_ERROR_TIMEOUT;
}

// Wait for data ready
static int IdeWaitData(uint16_t base_port) {
uint32_t timeout = 100000;
uint32_t timeout = 500000; // Increased timeout

while (timeout--) {
uint8_t status = inb(base_port + IDE_REG_STATUS);
if (status & IDE_STATUS_DRQ) {
if (!(status & IDE_STATUS_BSY) && (status & IDE_STATUS_DRQ)) {
return IDE_OK;
}
if (status & IDE_STATUS_ERR) {
return IDE_ERROR_IO;
}
// Small delay
for (volatile int i = 0; i < 100; i++);
}
return IDE_ERROR_TIMEOUT;
}
Expand Down Expand Up @@ -65,9 +68,12 @@ static int IdeIdentifyDrive(uint16_t base_port, uint8_t drive, uint16_t* buffer)
// Send IDENTIFY command
outb(base_port + IDE_REG_COMMAND, IDE_CMD_IDENTIFY);

// Check if drive exists
// Wait a bit after command
for (volatile int i = 0; i < 1000; i++);

// Check if drive exists - be more lenient
uint8_t status = inb(base_port + IDE_REG_STATUS);
if (status == 0) return IDE_ERROR_NO_DRIVE;
if (status == 0 || status == 0xFF) return IDE_ERROR_NO_DRIVE;

result = IdeWaitData(base_port);
if (result != IDE_OK) return result;
Expand Down Expand Up @@ -146,15 +152,15 @@ int IdeReadSector(uint8_t drive, uint32_t lba, void* buffer) {
return IDE_ERROR_NO_DRIVE;
}

irq_flags_t flags = SpinLockIrqSave(&ide_lock);

// Protect access to shared channels structure only
SpinLock(&ide_lock);
uint16_t base_port = channels[channel].base_port;
SpinUnlock(&ide_lock);
int result;

// Select drive and set LBA
result = IdeSelectDrive(base_port, drive_num, lba);
if (result != IDE_OK) {
SpinUnlockIrqRestore(&ide_lock, flags);
return result;
}

Expand All @@ -170,7 +176,6 @@ int IdeReadSector(uint8_t drive, uint32_t lba, void* buffer) {
// Wait for data ready
result = IdeWaitData(base_port);
if (result != IDE_OK) {
SpinUnlockIrqRestore(&ide_lock, flags);
return result;
}

Expand All @@ -180,7 +185,6 @@ int IdeReadSector(uint8_t drive, uint32_t lba, void* buffer) {
buf16[i] = inw(base_port + IDE_REG_DATA);
}

SpinUnlockIrqRestore(&ide_lock, flags);
return IDE_OK;
}

Expand All @@ -194,15 +198,15 @@ int IdeWriteSector(uint8_t drive, uint32_t lba, const void* buffer) {
return IDE_ERROR_NO_DRIVE;
}

irq_flags_t flags = SpinLockIrqSave(&ide_lock);

// Protect access to shared channels structure only
SpinLock(&ide_lock);
uint16_t base_port = channels[channel].base_port;
SpinUnlock(&ide_lock);
int result;

// Select drive and set LBA
result = IdeSelectDrive(base_port, drive_num, lba);
if (result != IDE_OK) {
SpinUnlockIrqRestore(&ide_lock, flags);
return result;
}

Expand All @@ -218,7 +222,6 @@ int IdeWriteSector(uint8_t drive, uint32_t lba, const void* buffer) {
// Wait for data ready
result = IdeWaitData(base_port);
if (result != IDE_OK) {
SpinUnlockIrqRestore(&ide_lock, flags);
return result;
}

Expand All @@ -230,7 +233,6 @@ int IdeWriteSector(uint8_t drive, uint32_t lba, const void* buffer) {

// Wait for write completion
result = IdeWaitReady(base_port);
SpinUnlockIrqRestore(&ide_lock, flags);
return result;
}

Expand Down
4 changes: 0 additions & 4 deletions drivers/Ide.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,3 @@ int IdeGetDriveInfo(uint8_t drive, char* model_out);
void IDEPrimaryIRQH(void);
void IDESecondaryIRQH(void);

// Internal Functions
static int IdeWaitReady(uint16_t base_port);
static int IdeSelectDrive(uint16_t base_port, uint8_t drive, uint32_t lba);
static int IdeIdentifyDrive(uint16_t base_port, uint8_t drive, uint16_t* buffer);
12 changes: 12 additions & 0 deletions drivers/Serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,16 @@ void SerialWrite(const char* str) {
for (int i = 0; str[i] != '\0'; i++) {
SerialWriteChar(str[i]);
}
}

void SerialWriteHex(uint64_t value) {
const char hex[] = "0123456789ABCDEF";
char buffer[17];
buffer[16] = '\0';

for (int i = 15; i >= 0; i--) {
buffer[15-i] = hex[(value >> (i * 4)) & 0xF];
}

SerialWrite(buffer);
}
2 changes: 2 additions & 0 deletions drivers/Serial.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#ifndef VOIDFRAME_SERIAL_H
#define VOIDFRAME_SERIAL_H
#include "stdint.h"

void SerialInit(void);
void SerialWriteChar(char c);
void SerialWrite(const char* str);
void SerialWriteHex(uint64_t value);

#endif // VOIDFRAME_SERIAL_H
46 changes: 34 additions & 12 deletions fs/FAT12.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

static Fat12Volume volume;
static uint8_t* sector_buffer = NULL;
static int fat12_initialized = 0;
int fat12_initialized = 0; // Make global for VFS

int Fat12Init(uint8_t drive) {
if (fat12_initialized) {
Expand Down Expand Up @@ -44,13 +44,18 @@ int Fat12Init(uint8_t drive) {
uint32_t fat_size = volume.boot.sectors_per_fat * 512;
volume.fat_table = KernelMemoryAlloc(fat_size);
if (!volume.fat_table) {
KernelFree(sector_buffer);
sector_buffer = NULL;
return -1;
}

// Read FAT table
for (int i = 0; i < volume.boot.sectors_per_fat; i++) {
if (IdeReadSector(drive, volume.fat_sector + i, volume.fat_table + (i * 512)) != IDE_OK) {
KernelFree(volume.fat_table);
volume.fat_table = NULL;
KernelFree(sector_buffer);
sector_buffer = NULL;
return -1;
}
}
Expand All @@ -76,7 +81,7 @@ static uint16_t Fat12GetNextCluster(uint16_t cluster) {
}

int Fat12GetCluster(uint16_t cluster, uint8_t* buffer) {
if (cluster < 2 || cluster >= 0xFF8) return -1;
if (volume.boot.sectors_per_cluster == 0 || volume.boot.sectors_per_cluster > 8) return -1;

uint32_t sector = volume.data_sector + ((cluster - 2) * volume.boot.sectors_per_cluster);

Expand All @@ -90,13 +95,13 @@ int Fat12GetCluster(uint16_t cluster, uint8_t* buffer) {
}

int Fat12ListRoot(void) {
PrintKernel("[FAT12] Root directory contents:\n");
PrintKernel("[SYSTEM] Root directory contents:\n");

uint32_t root_sectors = (volume.boot.root_entries * 32 + 511) / 512;

for (uint32_t sector = 0; sector < root_sectors; sector++) {
if (IdeReadSector(volume.drive, volume.root_sector + sector, sector_buffer) != IDE_OK) {
PrintKernelError("[FAT12] Failed to read root directory\n");
PrintKernelError("[SYSTEM] Failed to read root directory\n");
return -1;
}

Expand Down Expand Up @@ -179,22 +184,39 @@ int Fat12ReadFile(const char* filename, void* buffer, uint32_t max_size) {
// Found file, read it
uint16_t cluster = entry->cluster_low;
uint32_t bytes_read = 0;
uint32_t file_size = entry->file_size;
uint8_t* buf_ptr = (uint8_t*)buffer;

while (cluster < 0xFF8 && bytes_read < max_size) {
uint8_t cluster_buffer[512 * 8]; // Max cluster size
if (file_size == 0) {
return 0;
}
// Safety bound: max clusters we should traverse
uint32_t cluster_bytes = volume.boot.sectors_per_cluster * 512;
if (cluster_bytes == 0) return -1;
uint32_t max_clusters = (file_size + cluster_bytes - 1) / cluster_bytes;
uint32_t visited = 0;

while (cluster < 0xFF8 && bytes_read < max_size && visited < max_clusters) {
uint8_t* cluster_buffer = KernelMemoryAlloc(cluster_bytes);
if (!cluster_buffer) return -1;

if (Fat12GetCluster(cluster, cluster_buffer) != 0) {
KernelFree(cluster_buffer);
return -1;
}

uint32_t cluster_size = volume.boot.sectors_per_cluster * 512;
uint32_t copy_size = (bytes_read + cluster_size > max_size) ?
(max_size - bytes_read) : cluster_size;


uint32_t cluster_size = cluster_bytes;
uint32_t remaining_in_file = (file_size > bytes_read) ? (file_size - bytes_read) : 0;
uint32_t copy_size = cluster_size;
if (copy_size > remaining_in_file) copy_size = remaining_in_file;
if (copy_size > (max_size - bytes_read)) copy_size = (max_size - bytes_read);
if (copy_size == 0) break;

FastMemcpy(buf_ptr + bytes_read, cluster_buffer, copy_size);
bytes_read += copy_size;

++visited;
cluster = Fat12GetNextCluster(cluster);
KernelFree(cluster_buffer);
}

return bytes_read;
Expand Down
55 changes: 49 additions & 6 deletions fs/Fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "KernelHeap.h"
#include "MemOps.h"
#include "Process.h"
#include "StringOps.h"
#include "Serial.h"

static FsNode* root_node = NULL;
static FileHandle file_handles[MAX_OPEN_FILES];
Expand Down Expand Up @@ -72,7 +74,12 @@ FsNode* FsCreateNode(const char* name, FsNodeType type, FsNode* parent) {
FsNode* node = AllocNode();
if (!node) return NULL;

FastMemcpy(node->name, name, MAX_FILENAME);
int len = 0;
while (name[len] && len < MAX_FILENAME - 1) {
node->name[len] = name[len];
len++;
}
node->name[len] = '\0';
node->type = type;
node->parent = parent;
node->size = 0;
Expand All @@ -93,9 +100,21 @@ FsNode* FsCreateNode(const char* name, FsNodeType type, FsNode* parent) {
}

FsNode* FsFind(const char* path) {
if (!path || !root_node) return NULL;
SerialWrite("[FS] FsFind called with path: ");
if (!path) {
SerialWrite("NULL\n");
return NULL;
}
SerialWrite(path);
SerialWrite("\n");

if (!root_node) {
SerialWrite("[FS] root_node is NULL!\n");
return NULL;
}

if (path[0] == '/' && path[1] == '\0') {
SerialWrite("[FS] Returning root node\n");
return root_node;
}

Expand All @@ -112,9 +131,24 @@ FsNode* FsFind(const char* path) {

if (name_idx == 0) continue;

SerialWrite("[FS] Looking for child: ");
SerialWrite(name_buf);
SerialWrite("\n");

FsNode* child = current->children;
while (child) {
if (FastMemcmp(child->name, name_buf, name_idx + 1) == 0) {
SerialWrite("[FS] Checking child at: 0x");
SerialWriteHex((uint64_t)child);
SerialWrite(" name: ");
if (child->name) {
SerialWrite(child->name);
} else {
SerialWrite("NULL");
}
SerialWrite("\n");

if (FastStrCmp(child->name, name_buf) == 0) {
SerialWrite("[FS] Found match!\n");
current = child;
break;
}
Expand Down Expand Up @@ -150,9 +184,18 @@ int FsOpen(const char* path, FsOpenFlags flags) {

if (last_slash == -1) return -1;

FastMemcpy(parent_path, path, last_slash + 1);
for (int i = 0; i <= last_slash; i++) {
parent_path[i] = path[i];
}
parent_path[last_slash + 1] = '\0';
FastMemcpy(filename, path + last_slash + 1, MAX_FILENAME);

int fn_len = 0;
const char* fn_start = path + last_slash + 1;
while (fn_start[fn_len] && fn_len < MAX_FILENAME - 1) {
filename[fn_len] = fn_start[fn_len];
fn_len++;
}
filename[fn_len] = '\0';

FsNode* parent = FsFind(parent_path);
if (!parent || parent->type != FS_DIRECTORY) return -1;
Expand Down Expand Up @@ -338,7 +381,7 @@ int FsCreateDir(const char* path) {
return FsMkdir(path);
}

int FsWriteFile(const char* path, const void* buffer, uint32_t size) {
int FsWriteFile(const char* path, const void* buffer, size_t size) {
int fd = FsOpen(path, FS_WRITE);
if (fd < 0) return -1;
int result = FsWrite(fd, buffer, size);
Expand Down
Loading