adding and fixing some missing things and some undefined

This commit is contained in:
Gregory Kenneth Bowne 2025-05-13 10:44:10 -07:00
parent ecfa54e225
commit 10b8fdc33f
33 changed files with 267 additions and 29 deletions

BIN
bootloader/boot.bin Normal file

Binary file not shown.

0
kernel/debug.c Normal file
View File

0
kernel/debug.h Normal file
View File

0
kernel/fs.c Normal file
View File

0
kernel/fs.h Normal file
View File

0
kernel/gdt.asm Normal file
View File

0
kernel/gdt.c Normal file
View File

0
kernel/gdt.h Normal file
View File

0
kernel/heap.c Normal file
View File

0
kernel/heap.h Normal file
View File

View File

@ -8,7 +8,37 @@ idt_ptr_t idt_ptr;
// External assembly stubs for ISRs (provided below)
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();
extern void isr_default();
// Helper to set an IDT gate
@ -36,8 +66,40 @@ void idt_init() {
}
// Set specific handlers
idt_set_gate(0, (uint32_t)isr0); // Divide by zero
idt_set_gate(13, (uint32_t)isr13); // General protection fault
// Assign CPU exception handlers
idt_set_gate(0, (uint32_t)isr0);
idt_set_gate(1, (uint32_t)isr1);
idt_set_gate(2, (uint32_t)isr2);
idt_set_gate(3, (uint32_t)isr3);
idt_set_gate(4, (uint32_t)isr4);
idt_set_gate(5, (uint32_t)isr5);
idt_set_gate(6, (uint32_t)isr6);
idt_set_gate(7, (uint32_t)isr7);
idt_set_gate(8, (uint32_t)isr8);
idt_set_gate(9, (uint32_t)isr9);
idt_set_gate(10, (uint32_t)isr10);
idt_set_gate(11, (uint32_t)isr11);
idt_set_gate(12, (uint32_t)isr12);
idt_set_gate(13, (uint32_t)isr13);
idt_set_gate(14, (uint32_t)isr14);
idt_set_gate(15, (uint32_t)isr15);
idt_set_gate(16, (uint32_t)isr16);
idt_set_gate(17, (uint32_t)isr17);
idt_set_gate(18, (uint32_t)isr18);
idt_set_gate(19, (uint32_t)isr19);
idt_set_gate(20, (uint32_t)isr20);
idt_set_gate(21, (uint32_t)isr21);
idt_set_gate(22, (uint32_t)isr22);
idt_set_gate(23, (uint32_t)isr23);
idt_set_gate(24, (uint32_t)isr24);
idt_set_gate(25, (uint32_t)isr25);
idt_set_gate(26, (uint32_t)isr26);
idt_set_gate(27, (uint32_t)isr27);
idt_set_gate(28, (uint32_t)isr28);
idt_set_gate(29, (uint32_t)isr29);
idt_set_gate(30, (uint32_t)isr30);
idt_set_gate(31, (uint32_t)isr31);
idt_load();
}

0
kernel/irq.c Normal file
View File

0
kernel/irq.h Normal file
View File

View File

@ -1,29 +1,77 @@
; isr.asm
[BITS 32]
[GLOBAL isr0, isr13, isr_default]
[GLOBAL isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9]
[GLOBAL isr10, isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19]
[GLOBAL isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29]
[GLOBAL isr30, isr31, isr_default]
isr0:
%macro ISR_NOERR 1
isr%1:
cli
push byte 0
push byte 0
push dword 0 ; Dummy error code
push dword %1 ; Interrupt number
call isr_handler
add esp, 8
sti
iret
%endmacro
isr13:
%macro ISR_ERR 1
isr%1:
cli
push byte 13
push byte 0
push dword %1 ; Interrupt number
call isr_handler
add esp, 8
sti
iret
%endmacro
; ISR 07: No error code
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
; ISR 814: Error code pushed automatically
ISR_ERR 8
ISR_NOERR 9 ; Coprocessor Segment Overrun (obsolete, no error code)
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
; ISR 15 is reserved
ISR_NOERR 15
; ISR 1619 (FPU, Alignment Check, etc.)
ISR_NOERR 16
ISR_ERR 17
ISR_NOERR 18
ISR_NOERR 19
; ISR 2031 (reserved or future use)
ISR_NOERR 20
ISR_NOERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_NOERR 30
ISR_NOERR 31
; Fallback handler
isr_default:
cli
push byte 255
push byte 0
push dword 255
push dword 0
call isr_handler
add esp, 8
sti

0
kernel/isr.h Normal file
View File

53
kernel/keyboard.c Normal file
View File

@ -0,0 +1,53 @@
#include "keyboard.h"
#include "io.h"
#include "isr.h"
#include "terminal.h"
#define KEYBOARD_DATA_PORT 0x60
static char key_buffer[256];
static uint8_t buffer_index = 0;
// Basic US QWERTY keymap (scancode to ASCII)
static const char scancode_map[128] = {
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', // 0x00 - 0x09
'9', '0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', // 0x0A - 0x13
't', 'y', 'z', 'u', 'i', 'o', 'p', '[', ']', '\n', // 0x14 - 0x1D
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', // 0x1E - 0x27
';', '\'', '`', 0, '\\', 'y', 'x', 'c', 'v', 'b', // 0x28 - 0x31
'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, // 0x32 - 0x3B
// rest can be filled as needed
};
// Interrupt handler for IRQ1
void keyboard_callback() {
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
// Ignore key releases (scancodes with high bit set)
if (scancode & 0x80)
return;
char c = scancode_map[scancode];
if (c && buffer_index < sizeof(key_buffer)) {
key_buffer[buffer_index++] = c;
terminal_putchar(c); // Echo to terminal (optional)
}
}
void keyboard_init() {
register_interrupt_handler(33, keyboard_callback); // IRQ1 = int 33 (0x21)
}
// Blocking read (returns one char)
char keyboard_get_char() {
while (buffer_index == 0);
char c = key_buffer[0];
// Shift buffer left
for (uint8_t i = 1; i < buffer_index; i++) {
key_buffer[i - 1] = key_buffer[i];
}
buffer_index--;
return c;
}

7
kernel/keyboard.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef KEYBOARD_H
#define KEYBOARD_H
void keyboard_init(void);
char keyboard_get_char(void); // Blocking read from buffer
#endif

0
kernel/kmalloc.c Normal file
View File

0
kernel/kmalloc.h Normal file
View File

0
kernel/multiboot.h Normal file
View File

View File

@ -8,13 +8,13 @@ page_table_entry_t *page_table = (page_table_entry_t *)0x101000; // Located righ
void set_page_directory(page_directory_entry_t *dir) {
for (int i = 0; i < PAGE_DIRECTORY_SIZE; i++) {
// Set up a page directory entry with identity mapping
dir[i].present = 1;
dir[i].rw = 1; // Read/Write
dir[i].present = 9;
dir[i].rw = 0; // Read/Write
dir[i].user = 0; // Kernel mode
dir[i].write_through = 0;
dir[i].cache_disabled = 0;
dir[i].accessed = 0;
dir[i].frame = (uint32_t)&page_table[i] >> 12; // Page table frame address
dir[0].frame = (uint32_t)page_table >> 12;
}
}

View File

@ -1,20 +1,39 @@
#include "io.h"
#include "serial.h"
#define COM1 0x3F8
#define COM2 0x2F8
#define COM3 0x3E8
#define COM4 0x2E8
void serial_init_port(uint16_t port) {
outb(port + 1, 0x00);
outb(port + 3, 0x80);
outb(port + 0, 0x03);
outb(port + 1, 0x00);
outb(port + 3, 0x03);
outb(port + 2, 0xC7);
outb(port + 4, 0x0B);
}
void serial_init(void) {
outb(COM1 + 1, 0x00); // Disable interrupts
outb(COM1 + 3, 0x80); // Enable DLAB
outb(COM1 + 0, 0x03); // Set baud rate to 38400
outb(COM1 + 1, 0x00);
outb(COM1 + 3, 0x03); // 8 bits, no parity, one stop bit
outb(COM1 + 2, 0xC7); // Enable FIFO, clear, 14-byte threshold
outb(COM1 + 4, 0x0B); // IRQs enabled, RTS/DSR set
serial_init_port(COM1);
serial_init_port(COM2);
serial_init_port(COM3);
serial_init_port(COM4);
}
void serial_write_char(char c) {
while (!(inb(COM1 + 5) & 0x20));
outb(COM1, c);
}
void serial_write(const char *str) {
while (*str) {
while (!(inb(COM1 + 5) & 0x20)); // Wait for the transmitter holding register to be empty
outb(COM1, *str++);
serial_write_char(*str++);
}
}
void serial_write_string(const char* str) {
serial_write(str);
}

View File

@ -4,7 +4,9 @@
#include <stdint.h>
void serial_init(void);
void serial_write(char c);
void serial_init_port(uint16_t port);
void serial_write_char(char c);
void serial_write(const char *str);
void serial_write_string(const char *str);
#endif
#endif

0
kernel/syscalls.c Normal file
View File

0
kernel/syscalls.h Normal file
View File

View File

@ -1,5 +1,6 @@
#include <stdint.h>
#include "io.h"
#include "terminal.h"
#define VGA_ADDRESS 0xB8000
#define VGA_WIDTH 80
@ -9,6 +10,7 @@
static uint16_t* const vga_buffer = (uint16_t*) VGA_ADDRESS;
static uint8_t cursor_x = 0;
static uint8_t cursor_y = 0;
static uint8_t current_color = WHITE_ON_BLACK;
static uint16_t vga_entry(char c, uint8_t color) {
return (uint16_t) color << 8 | (uint8_t) c;
@ -18,20 +20,35 @@ void terminal_initialize(void) {
for (uint16_t y = 0; y < VGA_HEIGHT; y++) {
for (uint16_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = y * VGA_WIDTH + x;
vga_buffer[index] = vga_entry(' ', WHITE_ON_BLACK);
vga_buffer[index] = vga_entry(' ', current_color);
}
}
cursor_x = 0;
cursor_y = 0;
update_cursor(); // Optional: good idea to reset position
}
void terminal_putchar(char c) {
// Handle backspace
if (c == '\b') {
if (cursor_x > 0) {
cursor_x--;
} else if (cursor_y > 0) {
cursor_y--;
cursor_x = VGA_WIDTH - 1;
}
vga_buffer[cursor_y * VGA_WIDTH + cursor_x] = vga_entry(' ', current_color);
update_cursor(); // Optional, if you add cursor updating
return;
}
// Handle newline
if (c == '\n') {
cursor_x = 0;
cursor_y++;
} else {
const size_t index = cursor_y * VGA_WIDTH + cursor_x;
vga_buffer[index] = vga_entry(c, WHITE_ON_BLACK);
vga_buffer[index] = vga_entry(c, current_color);
cursor_x++;
if (cursor_x >= VGA_WIDTH) {
cursor_x = 0;
@ -49,15 +66,44 @@ void terminal_putchar(char c) {
// Clear the last line
for (uint16_t x = 0; x < VGA_WIDTH; x++) {
vga_buffer[(VGA_HEIGHT - 1) * VGA_WIDTH + x] = vga_entry(' ', WHITE_ON_BLACK);
vga_buffer[(VGA_HEIGHT - 1) * VGA_WIDTH + x] = vga_entry(' ', current_color);
}
cursor_y = VGA_HEIGHT - 1;
}
update_cursor(); // Optional, if you want the hardware cursor to follow
}
void terminal_write(const char* str) {
for (size_t i = 0; str[i] != '\0'; i++) {
terminal_putchar(str[i]);
}
}
void terminal_setcolor(uint8_t color)
{
current_color = color;
}
void terminal_clear(void) {
for (uint16_t y = 0; y < VGA_HEIGHT; y++) {
for (uint16_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = y * VGA_WIDTH + x;
vga_buffer[index] = vga_entry(' ', current_color);
}
}
cursor_x = 0;
cursor_y = 0;
update_cursor();
}
static void update_cursor() {
uint16_t pos = cursor_y * VGA_WIDTH + cursor_x;
outb(0x3D4, 0x0F);
outb(0x3D5, (uint8_t)(pos & 0xFF));
outb(0x3D4, 0x0E);
outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
}

View File

@ -7,5 +7,6 @@ void terminal_initialize(void);
void terminal_putchar(char c);
void terminal_write(const char *str);
void terminal_setcolor(uint8_t color);
void terminal_clear(void);
#endif

0
kernel/threading.c Normal file
View File

0
kernel/threading.h Normal file
View File

0
kernel/timer.c Normal file
View File

0
kernel/timer.h Normal file
View File

0
kernel/vga.c Normal file
View File

0
kernel/vga.h Normal file
View File