This commit is contained in:
nub31
2025-08-23 22:45:59 +02:00
parent b6caeb4a74
commit 751a182122
12 changed files with 348 additions and 41 deletions

View File

@@ -17,8 +17,8 @@ build-dir:
cp .build/kernel.bin .build/iso/boot/
grub-mkrescue -o .build/nub-os.iso .build/iso/
.build/kernel.bin: build-dir .build/boot.o .build/kernel.o .build/print.o
$(LD) -Ttext 0x100000 -o .build/kernel.bin .build/boot.o .build/kernel.o .build/print.o
.build/kernel.bin: build-dir .build/boot.o .build/kernel.o .build/print.o .build/idt.o .build/keyboard.o .build/exceptions.o .build/interrupts.o
$(LD) -Ttext 0x100000 -o .build/kernel.bin .build/boot.o .build/kernel.o .build/print.o .build/idt.o .build/keyboard.o .build/exceptions.o .build/interrupts.o
.build/kernel.o: build-dir src/kernel.c
$(CC) $(CFLAGS) -c -o .build/kernel.o src/kernel.c
@@ -26,5 +26,17 @@ build-dir:
.build/print.o: build-dir src/print.c
$(CC) $(CFLAGS) -c -o .build/print.o src/print.c
.build/idt.o: build-dir src/idt.c
$(CC) $(CFLAGS) -c -o .build/idt.o src/idt.c
.build/keyboard.o: build-dir src/keyboard.c
$(CC) $(CFLAGS) -c -o .build/keyboard.o src/keyboard.c
.build/exceptions.o: build-dir src/exceptions.c
$(CC) $(CFLAGS) -c -o .build/exceptions.o src/exceptions.c
.build/interrupts.o: build-dir src/interrupts.asm
nasm -f elf64 -o .build/interrupts.o src/interrupts.asm
.build/boot.o: build-dir src/boot.asm
nasm -f elf64 -o .build/boot.o src/boot.asm

30
src/exceptions.c Normal file
View File

@@ -0,0 +1,30 @@
#include "print.h"
#include <stdint.h>
void exception_handler(uint64_t* stack)
{
uint64_t interrupt_num = stack[0];
uint64_t error_code = stack[1];
print("EXCEPTION: ");
if (interrupt_num == 0)
{
print("Division by zero");
}
else if (interrupt_num == 13)
{
print("General protection fault");
}
else
{
print("Unknown exception");
}
print("\nError code: ");
// You'd need to implement number printing here
print("\nSystem halted.\n");
while (1)
{
__asm__ volatile("hlt");
}
}

59
src/idt.c Normal file
View File

@@ -0,0 +1,59 @@
#include "idt.h"
#include "print.h"
#define IDT_ENTRIES 256
struct idt_entry
{
uint16_t offset_low;
uint16_t selector;
uint8_t ist;
uint8_t type_attr;
uint16_t offset_mid;
uint32_t offset_high;
uint32_t zero;
} __attribute__((packed));
struct idt_ptr
{
uint16_t limit;
uint64_t base;
} __attribute__((packed));
static struct idt_entry idt[IDT_ENTRIES];
static struct idt_ptr idt_pointer;
extern void isr0(void);
extern void isr13(void);
extern void keyboard_handler_asm(void);
static void idt_set_gate(uint8_t num, uint64_t handler, uint16_t sel, uint8_t flags)
{
idt[num].offset_low = handler & 0xFFFF;
idt[num].selector = sel;
idt[num].ist = 0;
idt[num].type_attr = flags;
idt[num].offset_mid = (handler >> 16) & 0xFFFF;
idt[num].offset_high = (handler >> 32) & 0xFFFFFFFF;
idt[num].zero = 0;
}
void idt_init(void)
{
idt_pointer.limit = (sizeof(struct idt_entry) * IDT_ENTRIES) - 1;
idt_pointer.base = (uint64_t)&idt;
for (int i = 0; i < IDT_ENTRIES; i++)
{
idt_set_gate(i, 0, 0, 0);
}
idt_set_gate(0, (uint64_t)isr0, 0x08, 0x8E);
idt_set_gate(13, (uint64_t)isr13, 0x08, 0x8E);
idt_set_gate(33, (uint64_t)keyboard_handler_asm, 0x08, 0x8E);
__asm__ volatile("lidt %0" : : "m"(idt_pointer));
print_clr("[success]", FG_GREEN, BG_BLACK);
print(" idt initialized\n");
}

3
src/idt.h Normal file
View File

@@ -0,0 +1,3 @@
#pragma once
void idt_init(void);

96
src/interrupts.asm Normal file
View File

@@ -0,0 +1,96 @@
section .text
global isr0
global isr13
global keyboard_handler_asm
extern exception_handler
extern keyboard_handler
isr0:
push 0
push 0
jmp exception_common
isr13:
push 13
jmp exception_common
exception_common:
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push rbp
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
mov rdi, rsp
call exception_handler
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rbp
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
add rsp, 16
iretq
keyboard_handler_asm:
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push rbp
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
call keyboard_handler
mov al, 0x20
out 0x20, al
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rbp
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
iretq

View File

@@ -1,6 +1,12 @@
#include "idt.h"
#include "keyboard.h"
#include "print.h"
void kernel_main(void)
{
print("Starting nub-os\n");
}
idt_init();
keyboard_init();
print("Welcome to nub OS\n");
print("> ");
}

80
src/keyboard.c Normal file
View File

@@ -0,0 +1,80 @@
#include "print.h"
#include <stdbool.h>
#include <stdint.h>
#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_STATUS_PORT 0x64
static char scancode_to_ascii[] = { 0, 0, '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, ' ' };
static char input_buffer[256];
static int buffer_index = 0;
static bool key_available = false;
static uint8_t inb(uint16_t port)
{
uint8_t result;
__asm__ volatile("inb %1, %0" : "=a"(result) : "Nd"(port));
return result;
}
void keyboard_handler(void)
{
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
if (scancode & 0x80)
{
return;
}
if (scancode < sizeof(scancode_to_ascii))
{
char ascii = scancode_to_ascii[scancode];
if (ascii)
{
if (ascii == '\b')
{
if (buffer_index > 0)
{
buffer_index--;
print("\b \b");
}
}
else if (ascii == '\n')
{
input_buffer[buffer_index] = '\0';
print("\n");
key_available = true;
}
else if (buffer_index < 255)
{
input_buffer[buffer_index++] = ascii;
char str[2] = { ascii, '\0' };
print(str);
}
}
}
}
char* keyboard_get_line(void)
{
buffer_index = 0;
key_available = false;
while (!key_available)
{
__asm__ volatile("hlt");
}
return input_buffer;
}
void keyboard_init(void)
{
__asm__ volatile("sti");
print_clr("[success]", FG_GREEN, BG_BLACK);
print(" keyboard initialized\n");
}

4
src/keyboard.h Normal file
View File

@@ -0,0 +1,4 @@
#pragma once
void keyboard_init(void);
char* keyboard_get_line(void);

View File

@@ -8,38 +8,6 @@
#define BUF_START 0xb8000
#define BUF_END (BUF_START + BUF_SIZE)
enum FG_COLOR
{
FG_BLACK = 0x0,
FG_BLUE = 0x1,
FG_GREEN = 0x2,
FG_CYAN = 0x3,
FG_RED = 0x4,
FG_MAGENTA = 0x5,
FG_BROWN = 0x6,
FG_LIGHT_GRAY = 0x7,
FG_DARK_GRAY = 0x8,
FG_LIGHT_BLUE = 0x9,
FG_LIGHT_GREEN = 0xA,
FG_LIGHT_CYAN = 0xB,
FG_LIGHT_RED = 0xC,
FG_LIGHT_MAGENTA = 0xD,
FG_YELLOW = 0xE,
FG_WHITE = 0xF,
};
enum BG_COLOR
{
BG_BLACK = 0x0,
BG_BLUE = 0x1,
BG_GREEN = 0x2,
BG_CYAN = 0x3,
BG_RED = 0x4,
BG_MAGENTA = 0x5,
BG_BROWN = 0x6,
BG_LIGHT_GRAY = 0x7,
};
typedef struct
{
uint8_t character;
@@ -66,7 +34,7 @@ void scroll(void)
}
}
void put_char(char c, uint8_t color)
void put_char(char c, FG_COLOR fg_color, BG_COLOR bg_color)
{
if (c == '\n')
{
@@ -75,6 +43,7 @@ void put_char(char c, uint8_t color)
}
else
{
uint8_t color = fg_color | bg_color << 4;
vga_buffer[cursor_row * COLUMNS + cursor_col] = (vga_char){ c, color };
cursor_col++;
}
@@ -94,11 +63,14 @@ void put_char(char c, uint8_t color)
void print(const char* string)
{
uint8_t color = FG_WHITE | BG_BLACK << 4;
print_clr(string, FG_WHITE, BG_BLACK);
}
void print_clr(const char* string, FG_COLOR fg_color, BG_COLOR bg_color)
{
for (int i = 0; string[i]; i++)
{
put_char(string[i], color);
put_char(string[i], fg_color, bg_color);
}
}

View File

@@ -1,8 +1,40 @@
#pragma once
#include <stdint.h>
void kernel_print(const char* string);
typedef enum
{
FG_BLACK = 0x0,
FG_BLUE = 0x1,
FG_GREEN = 0x2,
FG_CYAN = 0x3,
FG_RED = 0x4,
FG_MAGENTA = 0x5,
FG_BROWN = 0x6,
FG_LIGHT_GRAY = 0x7,
FG_DARK_GRAY = 0x8,
FG_LIGHT_BLUE = 0x9,
FG_LIGHT_GREEN = 0xA,
FG_LIGHT_CYAN = 0xB,
FG_LIGHT_RED = 0xC,
FG_LIGHT_MAGENTA = 0xD,
FG_YELLOW = 0xE,
FG_WHITE = 0xF,
} FG_COLOR;
void put_char(char c, uint8_t color);
typedef enum
{
BG_BLACK = 0x0,
BG_BLUE = 0x1,
BG_GREEN = 0x2,
BG_CYAN = 0x3,
BG_RED = 0x4,
BG_MAGENTA = 0x5,
BG_BROWN = 0x6,
BG_LIGHT_GRAY = 0x7,
} BG_COLOR;
void put_char(char c, FG_COLOR fg_color, BG_COLOR bg_color);
void print(const char* string);
void print_clr(const char* string, FG_COLOR fg_color, BG_COLOR bg_color);
void clear_screen(void);
void set_cursor_position(int row, int col);

10
src/string.c Normal file
View File

@@ -0,0 +1,10 @@
int strcmp(const char* a, const char* b)
{
while ((*a != '\0' && *b != '\0') && *a == *b)
{
a++;
b++;
}
return (*a == *b) ? 0 : (*a > *b) ? 1 : -1;
}

3
src/string.h Normal file
View File

@@ -0,0 +1,3 @@
#pragma once
int strcmp(const char* a, const char* b);