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
2 changes: 1 addition & 1 deletion Kernel/Gdt.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "Gdt.h"

#include "Panic.h"
// GDT with user mode segments
static struct GdtEntry gdt[5];
static struct GdtPtr gdt_ptr;
Expand Down
21 changes: 16 additions & 5 deletions Kernel/Kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "Gdt.h"
#include "UserMode.h"
#include "Io.h"
#include "Panic.h"
int CurrentLine = 0;
int CurrentColumn = 0;
void ClearScreen(){
Expand All @@ -21,17 +22,23 @@ void ClearScreen(){
}

void PrintKernel(const char *str){
if (!str) return;

char *vidptr = (char*)0xb8000;
int offset = (CurrentLine * 80 + CurrentColumn) * 2;

for (int k = 0; str[k] != '\0'; k++) {
if (CurrentLine >= 25) break; // Screen bounds

if (str[k] == '\n') {
CurrentLine++;
CurrentColumn = 0;
offset = (CurrentLine * 80 + CurrentColumn) * 2;
} else {
vidptr[offset] = str[k];
vidptr[offset + 1] = 0x03;
if (offset < 80 * 25 * 2) {
vidptr[offset] = str[k];
vidptr[offset + 1] = 0x03;
}
offset += 2;
CurrentColumn++;
if (CurrentColumn >= 80) {
Expand Down Expand Up @@ -101,10 +108,15 @@ void PrintKernelInt(int num) {
}

void PrintKernelAt(const char *str, int line, int col) {
if (line >= 25) line = 24;
if (!str) return;
if (line < 0 || line >= 25) return;
if (col < 0 || col >= 80) return;

char *vidptr = (char*)0xb8000;
int offset = (line * 80 + col) * 2;
for (int k = 0; str[k] != '\0'; k++) {

for (int k = 0; str[k] != '\0' && k < 80; k++) {
if (offset >= 80 * 25 * 2) break;
vidptr[offset] = str[k];
vidptr[offset + 1] = 0x03;
offset += 2;
Expand Down Expand Up @@ -164,7 +176,6 @@ void KernelMain(uint32_t magic, uint32_t info) {
PrintKernel("Initializing Processes...\n");
ProcessInit();
PrintKernel("Process system ready\n");
// Create your processes
CreateProcess(task1);
CreateProcess(task2);
CreateProcess(task3);
Expand Down
13 changes: 11 additions & 2 deletions Kernel/Memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "MemOps.h"
#include "Cpu.h"
#include "Kernel.h"
#include "Panic.h"
static uint8_t page_bitmap[BITMAP_SIZE / 8];
static uint64_t total_pages = 0;
static uint64_t used_pages = 0;
Expand Down Expand Up @@ -40,11 +41,19 @@ void* AllocPage(void) {
}

void FreePage(void* page) {
if (!page) {
Panic("FreePage: NULL pointer");
}

uint64_t addr = (uint64_t)page;
if (addr < memory_start) return;
if (addr < memory_start) {
Panic("FreePage: Address below memory start");
}

int page_idx = (addr - memory_start) / PAGE_SIZE;
if (page_idx >= total_pages) return;
if (page_idx >= total_pages) {
Panic("FreePage: Page index out of bounds");
}

int byte_idx = page_idx / 8;
int bit_idx = page_idx % 8;
Expand Down
39 changes: 39 additions & 0 deletions Kernel/Panic.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "Panic.h"
#include "Kernel.h"
#include "Io.h"

void __attribute__((noreturn)) Panic(const char* message) {

asm volatile("cli");

ClearScreen();
CurrentLine = 0;
CurrentColumn = 0;

PrintKernel("[----KERNEL PANIC----]\n");
PrintKernel(message);
PrintKernel("\n\nSystem halted.\n");

while(1) {
asm volatile("hlt");
}
}

void __attribute__((noreturn)) PanicWithCode(const char* message, uint64_t error_code) {
asm volatile("cli");

ClearScreen();
CurrentLine = 0;
CurrentColumn = 0;

PrintKernel("[----KERNEL PANIC----]\n");
PrintKernel(message);
PrintKernel("\nError Code: ");
PrintKernelHex(error_code);
PrintKernel(" -- Not handled");
PrintKernel("\n\nSystem halted.\n");

while(1) {
asm volatile("hlt");
}
}
Comment on lines +22 to +39
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential truncation of error code in PrintKernelHex call.

The function passes a uint64_t error_code to PrintKernelHex which accepts an int parameter. This will truncate high 32 bits of the error code on 64-bit systems.

Consider either:

  1. Updating PrintKernelHex to accept uint64_t
  2. Adding a separate PrintKernelHex64 function
  3. Documenting that only 32-bit error codes are supported
🤖 Prompt for AI Agents
In Kernel/Panic.c around lines 22 to 39, the function PanicWithCode passes a
64-bit error_code to PrintKernelHex, which only accepts an int, causing
truncation of the high 32 bits on 64-bit systems. To fix this, update
PrintKernelHex to accept a uint64_t parameter to handle full 64-bit values, or
alternatively create a new PrintKernelHex64 function that supports 64-bit
printing and use it here instead. Ensure the printing function correctly formats
the full 64-bit error code without truncation.

18 changes: 18 additions & 0 deletions Kernel/Panic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef PANIC_H
#define PANIC_H

#include "stdint.h"

// Panic function - never returns
void __attribute__((noreturn)) Panic(const char* message);
void __attribute__((noreturn)) PanicWithCode(const char* message, uint64_t error_code);

// Assert macro
#define ASSERT(condition) \
do { \
if (!(condition)) { \
Panic("Assertion failed: " #condition " at " __FILE__ ":" __LINE__); \
} \
} while(0)
Comment on lines +11 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix ASSERT macro stringification of LINE.

The __LINE__ macro expands to an integer and cannot be directly concatenated into a string literal. This will cause a compilation error.

Apply this fix to properly stringify the line number:

-#define ASSERT(condition) \
-    do { \
-        if (!(condition)) { \
-            Panic("Assertion failed: " #condition " at " __FILE__ ":" __LINE__); \
-        } \
-    } while(0)
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+#define ASSERT(condition) \
+    do { \
+        if (!(condition)) { \
+            Panic("Assertion failed: " #condition " at " __FILE__ ":" TOSTRING(__LINE__)); \
+        } \
+    } while(0)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#define ASSERT(condition) \
do { \
if (!(condition)) { \
Panic("Assertion failed: " #condition " at " __FILE__ ":" __LINE__); \
} \
} while(0)
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define ASSERT(condition) \
do { \
if (!(condition)) { \
Panic("Assertion failed: " #condition " at " __FILE__ ":" TOSTRING(__LINE__)); \
} \
} while (0)
🤖 Prompt for AI Agents
In Kernel/Panic.h around lines 11 to 16, the ASSERT macro incorrectly
concatenates the __LINE__ macro, which is an integer, directly into a string
literal causing a compilation error. To fix this, define helper macros to
stringify the __LINE__ macro properly and use them to convert the line number to
a string before concatenation in the Panic call within the ASSERT macro.


#endif
29 changes: 26 additions & 3 deletions Kernel/Process.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Process.h"
#include "Kernel.h"
#include "Memory.h"
#include "Panic.h"
#include "Io.h"
static Process processes[MAX_PROCESSES];
static uint32_t next_pid = 1;
Expand Down Expand Up @@ -40,7 +41,14 @@ void ProcessInit(void) {
}

uint32_t CreateProcess(void (*entry_point)(void)) {
if (process_count >= MAX_PROCESSES) return 0;
if (!entry_point) {
Panic("CreateProcess: NULL entry point");
}

if (process_count >= MAX_PROCESSES) {
Panic("CreateProcess: Too many processes");
}

// Find free slot
int slot = -1;
for (int i = 1; i < MAX_PROCESSES; i++) {
Expand All @@ -49,11 +57,15 @@ uint32_t CreateProcess(void (*entry_point)(void)) {
break;
}
}
if (slot == -1) return 0;
if (slot == -1) {
Panic("CreateProcess: No free process slots");
}

// Allocate stack
void* stack = AllocPage();
if (!stack) return 0;
if (!stack) {
Panic("CreateProcess: Failed to allocate stack");
}

// Initialize a process
processes[slot].pid = next_pid++;
Expand Down Expand Up @@ -126,6 +138,14 @@ void Schedule(void) {


void ScheduleFromInterrupt(struct Registers* regs) {
if (!regs) {
Panic("ScheduleFromInterrupt: NULL registers");
}

if (current_process >= MAX_PROCESSES) {
Panic("ScheduleFromInterrupt: Invalid current process");
}

if (process_count <= 1) return;

// Find next ready process
Expand Down Expand Up @@ -200,6 +220,9 @@ void ScheduleFromInterrupt(struct Registers* regs) {
}

Process* GetCurrentProcess(void) {
if (current_process >= MAX_PROCESSES) {
Panic("GetCurrentProcess: Invalid current process index");
}
return &processes[current_process];
}

Expand Down
12 changes: 12 additions & 0 deletions Kernel/Syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
#include "Kernel.h"
#include "Process.h"
#include "Idt.h"
#include "Panic.h"
extern void SyscallEntry(void);
uint64_t SyscallHandler(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint64_t arg3) {
Process* current = GetCurrentProcess();
if (!current) {
Panic("Syscall from invalid process");
}
switch (syscall_num) {
case SYS_EXIT:
// Terminate current process
Expand All @@ -17,13 +21,21 @@ uint64_t SyscallHandler(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint
case SYS_WRITE:
// arg1 = fd (ignored for now), arg2 = buffer, arg3 = count
if (arg1 == 1) { // stdout
if (!arg2) {
return -1; // NULL buffer
}
if (arg3 > 4096) {
return -1; // Buffer too large
}

char* buffer = (char*)arg2;
for (uint64_t i = 0; i < arg3; i++) {
if (buffer[i] == '\0') break;
PrintKernelAt(&buffer[i], CurrentLine, CurrentColumn++);
if (CurrentColumn >= 80) {
CurrentLine++;
CurrentColumn = 0;
if (CurrentLine >= 25) CurrentLine = 24; // Screen bounds
}
}
return arg3;
Expand Down
5 changes: 4 additions & 1 deletion Kernel/UserMode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
#include "Memory.h"
#include "Process.h"
#include "Gdt.h"
#include "Panic.h"

void JumpToUserMode(void (*user_function)(void)) {
// Allocate user stack
void* user_stack = AllocPage();
if (!user_stack) return;
if (!user_stack) {
Panic("Failed to allocate user stack");
}

uint64_t user_stack_top = (uint64_t)user_stack + STACK_SIZE;

Expand Down
3 changes: 2 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ c_sources = [
'Kernel/Process.c',
'Kernel/Syscall.c',
'Kernel/Gdt.c',
'Kernel/UserMode.c'
'Kernel/UserMode.c',
'Kernel/Panic.c'
]

# Compile assembly files
Expand Down