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
32 changes: 22 additions & 10 deletions Boot/boot.asm
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ header_start:
dd 0xE85250D6 ; Multiboot2 magic number
dd 0 ; Architecture 0 (protected mode i386)
dd header_end - header_start ; header length
dd -(0xE85250D6 + 0 + (header_end - header_start)) ; checksum
dd 0x17ADAF12 ; checksum (calculated: -(0xE85250D6 + 0 + 24))
; end tag
dw 0 ; type
dw 0 ; flags
Expand All @@ -14,6 +14,13 @@ bits 32

section .text

; Macro for debugging output
%macro debug_print 1
mov dx, 0xE9
mov al, %1
out dx, al
%endmacro

; Enhanced GDT for long mode (keeping your original structure)
gdt64:
dq 0 ; NULL descriptor
Expand All @@ -37,12 +44,14 @@ gdt64:

global start
start:
debug_print '1'
cli
cld

; Save multiboot info for kernel
mov [multiboot_magic], eax
mov [multiboot_info], ebx
debug_print 'B'

; Setup temporary stack
mov esp, stack_top
Expand All @@ -52,15 +61,18 @@ start:

; Load GDT (same as original)
lgdt [gdt64.pointer]
debug_print '2'

; Enable PAE (same as original)
mov eax, cr4
or eax, 1 << 5
mov cr4, eax
debug_print '3'

; Setup paging (keeping your original mapping approach)
mov edi, pml4_table
mov cr3, edi
debug_print '4'

; Initialize the tables by zeroing them out (same as original)
mov edi, pml4_table
Expand Down Expand Up @@ -89,19 +101,23 @@ start:
add edi, 8
add eax, 0x200000 ; Next 2MB
loop .map_loop
debug_print '5'

; Enable long mode (same as original)
mov ecx, 0xC0000080 ; EFER MSR
rdmsr
or eax, 1 << 8 ; LME (Long Mode Enable)
wrmsr
debug_print '6'

; Enable paging (same as original)
mov eax, cr0
or eax, 1 << 31 ; PG (Paging)
mov cr0, eax
debug_print '7'

; Jump to long mode (same as original)
debug_print '8'
jmp 0x08:long_mode

; Check and enable CPU features (non-critical)
Expand Down Expand Up @@ -144,6 +160,7 @@ bits 64
extern KernelMain

long_mode:
debug_print '9'
; Load data segments (same as original)
mov ax, 0x10 ; selector for data segment
mov ss, ax
Expand All @@ -157,18 +174,13 @@ long_mode:

; Clear direction flag
cld

; DEBUG: Write 'BOOT' to VGA before calling C code
mov rax, 0xb8000
mov word [rax], 0x0442 ; Red 'B'
mov word [rax+2], 0x044F ; Red 'O'
mov word [rax+4], 0x044F ; Red 'O'
mov word [rax+6], 0x0454 ; Red 'T'


; Pass multiboot info to kernel
mov rdi, [multiboot_magic]
mov rsi, [multiboot_info]

debug_print 'A'
; Jump to the C kernel (same as original)
call KernelMain

Expand All @@ -179,8 +191,8 @@ long_mode:
jmp .halt_loop

section .data
multiboot_magic: dq 0
multiboot_info: dq 0
multiboot_magic: dd 0
multiboot_info: dd 0

section .bss

Expand Down
24 changes: 21 additions & 3 deletions Kernel/Core/Kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
int CurrentLine = 0;
int CurrentColumn = 0;
void ClearScreen(){
PrintKernel("ClearScreen\n");

char *vidptr = (char*)0xb8000;
for (int j = 0; j < 80 * 25 * 2; j += 2) {
vidptr[j] = ' ';
Expand Down Expand Up @@ -155,7 +157,23 @@ void PrintKernelAt(const char *str, int line, int col) {
}
}

void RemapPIC() {

outb(0x20, 0x11); // Start init
outb(0xA0, 0x11);
outb(0x21, 0x20); // Master offset = 0x20 (32)
outb(0xA1, 0x28); // Slave offset = 0x28 (40)
outb(0x21, 0x04);
outb(0xA1, 0x02);
outb(0x21, 0x01);
outb(0xA1, 0x01);
outb(0x21, 0xFF); // Mask all
outb(0xA1, 0xFF);
}


void KernelMain(uint32_t magic, uint32_t info) {
PrintKernel("KernelMain\n");
ClearScreen();
PrintKernel("[SUCCESS] VoidFrame Kernel - Version 0.0.1-alpha loaded\n");

Expand All @@ -178,19 +196,19 @@ void KernelMain(uint32_t magic, uint32_t info) {

PrintKernel("[SUCCESS] Core system modules loaded\n");

// Timer setup for scheduling
RemapPIC();
outb(0x43, 0x36); // Command: channel 0, lobyte/hibyte, rate generator
outb(0x40, 0x4B); // Low byte of divisor (299 = ~4000Hz)
outb(0x40, 0x01); // High byte of divisor
outb(0x21, inb(0x21) & ~0x03);
outb(0x21, inb(0x21) & ~1);

// Enable interrupts
asm volatile("sti");

PrintKernel("[SUCCESS] Kernel initialization complete - entering main loop\n");
while (1) {
if (ShouldSchedule()) {
Schedule();
RequestSchedule();
}
asm volatile("hlt"); // Wait for the next interrupt
}
Expand Down
25 changes: 20 additions & 5 deletions Kernel/Drivers/Interrupts.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "../Core/stdint.h"
#include "../Core/Kernel.h"
#include "Io.h"
#include "../Core/Panic.h"
#include "../Process/Process.h"

#define likely(x) __builtin_expect(!!(x), 1)
Expand Down Expand Up @@ -64,17 +65,31 @@ static void FastDisplayTicks(uint64_t ticks) {
}
}

void PrintStack(uint64_t* ptr, int count) {
for (int i = 0; i < count; i++) {
PrintKernelHex(ptr[i]);
PrintKernel(" ");
}
PrintKernel("\n");
}
Comment on lines +68 to +74
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add bounds checking for stack dump.

The PrintStack function doesn't validate that accessing ptr[i] is safe. Consider adding bounds checking or documenting the safety assumptions.

-void PrintStack(uint64_t* ptr, int count) {
+void PrintStack(uint64_t* ptr, int count) {
+    if (!ptr || count <= 0) return;
     for (int i = 0; i < count; i++) {
         PrintKernelHex(ptr[i]);
         PrintKernel(" ");
     }
     PrintKernel("\n");
 }
📝 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
void PrintStack(uint64_t* ptr, int count) {
for (int i = 0; i < count; i++) {
PrintKernelHex(ptr[i]);
PrintKernel(" ");
}
PrintKernel("\n");
}
void PrintStack(uint64_t* ptr, int count) {
if (!ptr || count <= 0) return;
for (int i = 0; i < count; i++) {
PrintKernelHex(ptr[i]);
PrintKernel(" ");
}
PrintKernel("\n");
}
🤖 Prompt for AI Agents
In Kernel/Drivers/Interrupts.c around lines 68 to 74, the PrintStack function
accesses ptr[i] without verifying that the pointer is valid or that the index is
within safe bounds. To fix this, add explicit bounds checking to ensure ptr is
not null and that i is less than the actual size of the stack or the accessible
memory region before accessing ptr[i]. Alternatively, document the assumptions
clearly if bounds checking is not feasible here.


// The C-level interrupt handler
void InterruptHandler(struct Registers* regs) {

// Handle timer interrupt (IRQ0, remapped to 32)
if (likely(regs->interrupt_number == 32)) {
PrintKernel("Stack dump: ");
PrintStack((uint64_t*)regs, 20);
PrintKernel("InterruptHandler: interrupt_number=");
PrintKernelInt(regs->interrupt_number);
PrintKernel("\n");
if (regs->interrupt_number == 32) {
tick_count++;
FastDisplayTicks(tick_count); // Re-enabled
outb(0x20, 0x20);
ScheduleFromInterrupt(regs);
ScheduleFromInterrupt(regs); // Re-enabled
return;
}

// if (regs->interrupt_number == 13) {
// Panic("InterruptHandler: Page fault (GPF handler)");
// }
// Send EOI to PICs for other hardware interrupts
if (regs->interrupt_number >= 40) {
outb(0xA0, 0x20); // EOI to slave PIC
Expand Down
Loading