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
7 changes: 7 additions & 0 deletions Boot/boot.asm
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,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]
Expand Down
30 changes: 19 additions & 11 deletions Kernel/Core/Kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
#include "../System/Gdt.h"
#include "../Process/UserMode.h"
#include "../Drivers/Io.h"
#include "../Drivers/Driver.h"
#include "Panic.h"

// Driver registration
extern void KeyboardRegister(void);
int CurrentLine = 0;
int CurrentColumn = 0;
void ClearScreen(){
Expand Down Expand Up @@ -124,7 +128,7 @@ void PrintKernelAt(const char *str, int line, int col) {
}

// Fast print - no bounds checking, direct memory write
static inline void FastPrint(const char *str, int line, int col) {
void FastPrint(const char *str, int line, int col) {
uint16_t *vidptr = (uint16_t*)0xb8000;
int pos = line * 80 + col;

Expand All @@ -134,13 +138,13 @@ static inline void FastPrint(const char *str, int line, int col) {
}

// Fast print single character
static inline void FastPrintChar(char c, int line, int col) {
void FastPrintChar(char c, int line, int col) {
uint16_t *vidptr = (uint16_t*)0xb8000;
vidptr[line * 80 + col] = (0x03 << 8) | c;
}

// Fast print hex number
static inline void FastPrintHex(uint64_t num, int line, int col) {
void FastPrintHex(uint64_t num, int line, int col) {
uint16_t *vidptr = (uint16_t*)0xb8000;
int pos = line * 80 + col;

Expand Down Expand Up @@ -169,14 +173,14 @@ static inline void FastPrintHex(uint64_t num, int line, int col) {
void task1(void) {
while (1) {
FastPrint("T1 running", 10, 0);
for(volatile int i = 0; i < 10000; i++); // Faster loop
for(volatile int i = 0; i < 100; i++); // Tiny loop
}
}

void task2(void) {
while (1) {
FastPrint("T2 running", 11, 0);
for(volatile int i = 0; i < 10000; i++); // Faster loop
for(volatile int i = 0; i < 100; i++); // Tiny loop
}
}
void UserTask(void) {
Expand All @@ -201,10 +205,11 @@ void UserTask(void) {
void task3(void) {
while (1) {
FastPrint("T3 kernel", 12, 0);
for(volatile int i = 0; i < 10000; i++); // Faster loop
for(volatile int i = 0; i < 100; i++); // Tiny loop
}
}
void KernelMain(uint32_t magic, uint32_t info) {

ClearScreen();
PrintKernel("VoidFrame Kernel - Version 0.0.1-alpha\n");
PrintKernel("Initializing GDT...\n");
Expand All @@ -219,18 +224,21 @@ void KernelMain(uint32_t magic, uint32_t info) {
MemoryInit();
PrintKernel("Initializing Processes...\n");
ProcessInit();
PrintKernel("Initializing Drivers...\n");
KeyboardRegister();
DriverInit();
PrintKernel("Process system ready\n");
CreateProcess(task1);
CreateProcess(task2);
CreateProcess(task3);
CreateUserProcess(UserTask); // Ring 3 process
// Setup faster timer (PIT) - ~1000Hz instead of default 18.2Hz
// BLAZING FAST timer - ~4000Hz for maximum concurrency
outb(0x43, 0x36); // Command: channel 0, lobyte/hibyte, rate generator
outb(0x40, 0xA9); // Low byte of divisor (1193 = ~1000Hz)
outb(0x40, 0x04); // High byte of divisor
outb(0x40, 0x4B); // Low byte of divisor (299 = ~4000Hz)
outb(0x40, 0x01); // High byte of divisor

// Enable timer interrupt (IRQ0)
outb(0x21, inb(0x21) & ~0x01);
// Enable timer (IRQ0) and keyboard (IRQ1) interrupts
outb(0x21, inb(0x21) & ~0x03); // Enable IRQ0 and IRQ1

// Enable all interrupts
asm volatile("sti");
Expand Down
3 changes: 3 additions & 0 deletions Kernel/Core/Kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ void PrintKernel(const char *str);
void PrintKernelInt(int num);
void PrintKernelHex(uint64_t hex);
void PrintKernelAt(const char *str, int line, int col);
void FastPrint(const char *str, int line, int col);
void FastPrintHex(uint64_t num, int line, int col);
void FastPrintChar(char c, int line, int col);
#endif
32 changes: 32 additions & 0 deletions Kernel/Drivers/Driver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "Driver.h"
#include "../Core/Panic.h"

#define MAX_DRIVERS 16

static Driver* drivers[MAX_DRIVERS];
static int driver_count = 0;

void DriverRegister(Driver* driver) {
if (!driver || driver_count >= MAX_DRIVERS) {
Panic("Driver registration failed");
}

drivers[driver_count++] = driver;
}

void DriverInit(void) {
for (int i = 0; i < driver_count; i++) {
if (drivers[i]->init) {
drivers[i]->init();
}
}
}

Driver* DriverGet(DriverType type) {
for (int i = 0; i < driver_count; i++) {
if (drivers[i]->type == type) {
return drivers[i];
}
}
return 0;
}
30 changes: 30 additions & 0 deletions Kernel/Drivers/Driver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef DRIVER_H
#define DRIVER_H

#include "../Core/stdint.h"

// Driver types
typedef enum {
DRIVER_KEYBOARD,
DRIVER_MOUSE,
DRIVER_NETWORK,
DRIVER_STORAGE,
DRIVER_MAX
} DriverType;

// Driver interface - all drivers implement this
typedef struct {
DriverType type;
const char* name;
void (*init)(void);
void (*handle_interrupt)(uint8_t irq);
int (*read)(void* buffer, uint32_t size);
int (*write)(const void* buffer, uint32_t size);
} Driver;

// Driver registry
void DriverRegister(Driver* driver);
void DriverInit(void);
Driver* DriverGet(DriverType type);

#endif
20 changes: 15 additions & 5 deletions Kernel/Drivers/Interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "../Core/Kernel.h"
#include "Io.h"
#include "../Process/Process.h"
#include "../Core/stdint.h"
#include "Driver.h"

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
Expand Down Expand Up @@ -32,7 +32,7 @@ void itoa(uint64_t num, char* str) {
}

// Fast tick display using direct memory write
static inline void FastDisplayTicks(uint64_t ticks) {
static void FastDisplayTicks(uint64_t ticks) {
uint16_t *vidptr = (uint16_t*)0xb8000;
int pos = 20 * 80; // Line 20

Expand Down Expand Up @@ -67,19 +67,29 @@ static inline void FastDisplayTicks(uint64_t ticks) {

// The C-level interrupt handler
void InterruptHandler(struct Registers* regs) {
// Handle keyboard interrupt (IRQ1, remapped to 33)
if (regs->interrupt_number == 33) {
Driver* kbd = DriverGet(DRIVER_KEYBOARD);
if (kbd && kbd->handle_interrupt) {
kbd->handle_interrupt(1);
}
outb(0x20, 0x20); // EOI
return;
}

// Handle timer interrupt (IRQ0, remapped to 32)
if (likely(regs->interrupt_number == 32)) {
tick_count++;

// Fast tick display every 100 ticks to reduce overhead
if ((tick_count & 0x3F) == 0) { // Every 64 ticks
// Display ticks rarely to reduce overhead
if ((tick_count & 0x3FF) == 0) { // Every 1024 ticks
FastDisplayTicks(tick_count);
}

// Send EOI to master PIC
outb(0x20, 0x20);

// Do preemptive scheduling directly
// BLAZING FAST - schedule on EVERY interrupt
ScheduleFromInterrupt(regs);
return;
}
Expand Down
73 changes: 73 additions & 0 deletions Kernel/Drivers/Keyboard.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "Driver.h"
#include "Io.h"
#include "../Core/Kernel.h"

#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_STATUS_PORT 0x64

// Simple US keyboard layout
static char keymap[128] = {
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
'*', 0, ' '
};
Comment on lines +9 to +15
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Incomplete keymap may cause issues with extended keys.

The keymap only covers basic keys up to index 57 (space) but the array is sized for 128 entries. Extended keys, function keys, and other special keys will not be handled properly.

Consider extending the keymap to include commonly used keys:

static char keymap[128] = {
    0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
    '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
    0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
    0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
-    '*', 0, ' '
+    '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F1-F10 (scancodes 59-68)
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Additional keys
+    // ... continue for remaining entries
};

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In Kernel/Drivers/Keyboard.c around lines 9 to 15, the keymap array is sized for
128 entries but only partially initialized, missing extended keys, function
keys, and special keys. To fix this, extend the keymap array to include mappings
for all 128 possible scan codes, covering function keys (F1-F12), arrow keys,
and other special keys, ensuring proper handling of all keyboard inputs.


static char key_buffer[256];
static int buffer_head = 0;
static int buffer_tail = 0;

static void KeyboardInit(void) {
// Keyboard is already initialized by BIOS
FastPrint("Keyboard ready", 15, 0);
}

static void KeyboardInterrupt(uint8_t irq) {
if (irq != 1) return; // IRQ1 = keyboard

uint8_t scancode = inb(KEYBOARD_DATA_PORT);

// Only handle key press (not release)
if (scancode & 0x80) return;

char key = keymap[scancode];
if (key) {
// Add to buffer
int next_head = (buffer_head + 1) % 256;
if (next_head != buffer_tail) {
key_buffer[buffer_head] = key;
buffer_head = next_head;

// Echo key to screen
FastPrintChar(key, 16, (buffer_head % 80));
}
}
}
Comment on lines +26 to +46
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Potential screen bounds issue in echo functionality.

The echo position calculation (buffer_head % 80) may overwrite other screen content and doesn't account for different screen regions or line wrapping.

Consider implementing proper echo positioning:

            // Echo key to screen
-            FastPrintChar(key, 16, (buffer_head % 80));
+            static int echo_col = 0;
+            FastPrintChar(key, 16, echo_col);
+            echo_col = (echo_col + 1) % 80;
📝 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
static void KeyboardInterrupt(uint8_t irq) {
if (irq != 1) return; // IRQ1 = keyboard
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
// Only handle key press (not release)
if (scancode & 0x80) return;
char key = keymap[scancode];
if (key) {
// Add to buffer
int next_head = (buffer_head + 1) % 256;
if (next_head != buffer_tail) {
key_buffer[buffer_head] = key;
buffer_head = next_head;
// Echo key to screen
FastPrintChar(key, 16, (buffer_head % 80));
}
}
}
static void KeyboardInterrupt(uint8_t irq) {
if (irq != 1) return; // IRQ1 = keyboard
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
// Only handle key press (not release)
if (scancode & 0x80) return;
char key = keymap[scancode];
if (key) {
// Add to buffer
int next_head = (buffer_head + 1) % 256;
if (next_head != buffer_tail) {
key_buffer[buffer_head] = key;
buffer_head = next_head;
// Echo key to screen
static int echo_col = 0;
FastPrintChar(key, 16, echo_col);
echo_col = (echo_col + 1) % 80;
}
}
}
🤖 Prompt for AI Agents
In Kernel/Drivers/Keyboard.c between lines 26 and 46, the echo position for
printing the key uses (buffer_head % 80), which can cause overwriting and does
not handle line wrapping or screen regions. To fix this, implement a proper
cursor tracking mechanism that maintains current row and column positions,
updates them correctly on each character printed, and wraps to the next line
when reaching the screen width, ensuring the echo respects screen boundaries and
avoids overwriting unrelated content.


static int KeyboardRead(void* buffer, uint32_t size) {
char* buf = (char*)buffer;
int count = 0;

while (buffer_tail != buffer_head && count < size) {
buf[count++] = key_buffer[buffer_tail];
buffer_tail = (buffer_tail + 1) % 256;
}

return count;
}

// Keyboard driver instance
static Driver keyboard_driver = {
.type = DRIVER_KEYBOARD,
.name = "PS2 Keyboard",
.init = KeyboardInit,
.handle_interrupt = KeyboardInterrupt,
.read = KeyboardRead,
.write = 0 // Keyboard is input only
};

// Auto-register function
void KeyboardRegister(void) {
DriverRegister(&keyboard_driver);
}
1 change: 1 addition & 0 deletions grub.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ set timeout=0
set default=0

menuentry "VoidFrame" {
set gfxpayload=text
multiboot2 /boot/voidframe.krnl
boot
}
4 changes: 3 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ c_sources = [
'Kernel/System/Syscall.c',
'Kernel/Drivers/Interrupts.c',
'Kernel/Drivers/Pic.c',
'Kernel/Drivers/Cpu.c'
'Kernel/Drivers/Cpu.c',
'Kernel/Drivers/Driver.c',
'Kernel/Drivers/Keyboard.c'
]

# Build include flags
Expand Down