From 5e9c5828330b5926aa5fda97c57086d8a15204d4 Mon Sep 17 00:00:00 2001 From: xamidev Date: Sun, 8 Mar 2026 09:54:45 +0100 Subject: [PATCH 1/3] Fixed kbd (buffer flush) --- src/idt/idt.S | 3 ++- src/idt/idt.c | 3 ++- src/io/kbd/ps2.c | 30 +++++++++++++++++------------- src/io/serial/serial.c | 1 + src/io/term/term.c | 1 + 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/idt/idt.S b/src/idt/idt.S index de819e6..52eb314 100644 --- a/src/idt/idt.S +++ b/src/idt/idt.S @@ -151,12 +151,13 @@ vector_7_handler: align 16 vector_8_handler: ; No error code, we only push vector number - push qword 1 + push qword 8 jmp interrupt_stub ; Coprocessor Segment Overrun align 16 vector_9_handler: + push qword 0 push qword 9 jmp interrupt_stub diff --git a/src/idt/idt.c b/src/idt/idt.c index 34efe6b..13195d8 100644 --- a/src/idt/idt.c +++ b/src/idt/idt.c @@ -54,7 +54,7 @@ void idt_init() { // We set 256 entries, but we have only the first few stubs. // Undefined behavior? - for (size_t i=0; i<256; i++) + for (size_t i=0; i<=33; i++) { // Each vector handler is 16-byte aligned, so *16 = address of that handler idt_set_entry(i, vector_0_handler + (i*16), 0); @@ -210,6 +210,7 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context) case 33: DEBUG("Keyboard Interrupt"); keyboard_handler(); + outb(0x20, 0x20); break; default: diff --git a/src/io/kbd/ps2.c b/src/io/kbd/ps2.c index 65b1585..872d88e 100644 --- a/src/io/kbd/ps2.c +++ b/src/io/kbd/ps2.c @@ -176,9 +176,6 @@ void keyboard_handler() key_status &= ~ALT_PRESSED_BIT; break; } - - // Send EOI - outb(0x20, 0x20); return; } else @@ -200,20 +197,21 @@ void keyboard_handler() default: { - // Should we get a SHIFTED char or a regular one? - unsigned char c = (key_status & SHIFT_PRESSED_BIT) ? keymap_shifted[scancode] : keymap[scancode]; - - if (c) + // Avoiding buffer overflow from extended keys lol + if (scancode < 128) { - // Should probably have a keyboard buffer here... instead of this - _putchar(c); + // Should we get a SHIFTED char or a regular one? + unsigned char c = (key_status & SHIFT_PRESSED_BIT) ? keymap_shifted[scancode] : keymap[scancode]; + + if (c) + { + // Should probably have a keyboard buffer here... instead of this + _putchar(c); + } } } } } - - // End of Interrupt (to master PIC) - outb(0x20, 0x20); } void keyboard_init(unsigned char layout) @@ -233,10 +231,16 @@ void keyboard_init(unsigned char layout) break; default: - skputs("Unsupported layout."); + panic(NULL, "Unsupported keyboard layout"); return; } + // Flush keyboard buffer + while (inb(0x64) & 1) + { + inb(0x60); + } + // Unmask IRQ1 uint8_t mask = inb(0x21); mask &= ~(1 << 1); diff --git a/src/io/serial/serial.c b/src/io/serial/serial.c index e2b9c57..469501b 100644 --- a/src/io/serial/serial.c +++ b/src/io/serial/serial.c @@ -54,6 +54,7 @@ static int is_transmit_empty() // Serial kernel putchar void skputc(char c) { + // TODO: Spinlock here (serial access) while (!is_transmit_empty()); // wait for free spot outb(PORT, c); } diff --git a/src/io/term/term.c b/src/io/term/term.c index 6d7b709..b44c086 100644 --- a/src/io/term/term.c +++ b/src/io/term/term.c @@ -22,6 +22,7 @@ extern struct flanterm_context* ft_ctx; // Overhead that could be avoided, right? (for printf) void _putchar(char character) { + // TODO: Spinlock here (terminal access) flanterm_write(ft_ctx, &character, 1); } From 42c7a55d3ffdac814f729e7dca0f157f2d014f0e Mon Sep 17 00:00:00 2001 From: xamidev Date: Sun, 8 Mar 2026 13:21:19 +0100 Subject: [PATCH 2/3] Init struct + freeing a bit of kmain() --- README.md | 3 ++- src/idt/idt.c | 2 +- src/io/kbd/ps2.c | 7 +++++++ src/io/serial/serial.c | 3 +++ src/io/term/term.c | 35 +++++++++++++++++++++++++++++++++++ src/io/term/term.h | 1 + src/kernel.h | 15 ++++++++++++++- src/kmain.c | 35 +++++------------------------------ src/time/timer.c | 3 +++ 9 files changed, 71 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 1f5ad34..113bfb2 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,9 @@ PepperOS wouldn't be possible without the following freely-licensed software: - the [Limine](https://codeberg.org/Limine/Limine) portable bootloader - Marco Paland's freestanding [printf implementation](https://github.com/mpaland) -- the [ZAP](https://www.zap.org.au/projects/console-fonts-zap/) PSF console fonts +- Mintuski's [Flanterm](https://codeberg.org/Mintsuki/Flanterm) terminal emulator ...and without these amazing resources: - the [OSDev](https://osdev.org) wiki & forums +- Intel 64 and IA-32 Architectures Software Developer's Manual diff --git a/src/idt/idt.c b/src/idt/idt.c index 13195d8..bab6525 100644 --- a/src/idt/idt.c +++ b/src/idt/idt.c @@ -22,7 +22,7 @@ struct idtr idt_reg; extern char vector_0_handler[]; // Timer ticks -extern uint64_t ticks; +extern volatile uint64_t ticks; void idt_set_entry(uint8_t vector, void* handler, uint8_t dpl) { diff --git a/src/io/kbd/ps2.c b/src/io/kbd/ps2.c index 872d88e..fdd1946 100644 --- a/src/io/kbd/ps2.c +++ b/src/io/kbd/ps2.c @@ -17,6 +17,8 @@ uint8_t key_status = 0b00000000; unsigned char* keymap; unsigned char* keymap_shifted; +extern struct init_status init; + unsigned char kbdus[128] = { 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */ @@ -205,6 +207,10 @@ void keyboard_handler() if (c) { + if (c == '\n') + { + _putchar('\r'); + } // Should probably have a keyboard buffer here... instead of this _putchar(c); } @@ -247,4 +253,5 @@ void keyboard_init(unsigned char layout) outb(0x21, mask); DEBUG("PS/2 Keyboard initialized"); + init.keyboard = true; } \ No newline at end of file diff --git a/src/io/serial/serial.c b/src/io/serial/serial.c index 469501b..8c8c9ac 100644 --- a/src/io/serial/serial.c +++ b/src/io/serial/serial.c @@ -7,6 +7,8 @@ #include #include "serial.h" +extern struct init_status init; + void outb(int port, unsigned char data) { __asm__ __volatile__("outb %%al, %%dx" :: "a" (data),"d" (port)); @@ -43,6 +45,7 @@ int serial_init() outb(PORT + 4, 0x0F); DEBUG("*** Welcome to PepperOS! ***"); + init.serial = true; return 0; } diff --git a/src/io/term/term.c b/src/io/term/term.c index b44c086..89e5df9 100644 --- a/src/io/term/term.c +++ b/src/io/term/term.c @@ -16,8 +16,12 @@ because this shitty implementation will be replaced one day by Flanterm #include "term.h" #include "config.h" #include "flanterm.h" +#include "flanterm_backends/fb.h" +#include "mem/heap/kheap.h" +#include "limine.h" extern struct flanterm_context* ft_ctx; +extern struct init_status init; // Overhead that could be avoided, right? (for printf) void _putchar(char character) @@ -36,4 +40,35 @@ void kputs(const char* str) i++; } _putchar('\r'); +} + +extern struct flanterm_context* ft_ctx; +extern struct boot_context boot_ctx; + +void flanterm_free_wrapper(void* ptr, size_t size) +{ + (void)size; + kfree(ptr); +} + +void term_init() +{ + uint32_t bgColor = 0x252525; + ft_ctx = flanterm_fb_init( + kmalloc, + flanterm_free_wrapper, + boot_ctx.fb->address, boot_ctx.fb->width, boot_ctx.fb->height, boot_ctx.fb->pitch, + boot_ctx.fb->red_mask_size, boot_ctx.fb->red_mask_shift, + boot_ctx.fb->green_mask_size, boot_ctx.fb->green_mask_shift, + boot_ctx.fb->blue_mask_size, boot_ctx.fb->blue_mask_shift, + NULL, + NULL, NULL, + &bgColor, NULL, + NULL, NULL, + NULL, 0, 0, 1, + 0, 0, + 0, + 0 + ); + init.terminal = true; } \ No newline at end of file diff --git a/src/io/term/term.h b/src/io/term/term.h index 26e89d0..b470c1b 100644 --- a/src/io/term/term.h +++ b/src/io/term/term.h @@ -9,5 +9,6 @@ void kputs(const char* str); void _putchar(char character); +void term_init(); #endif diff --git a/src/kernel.h b/src/kernel.h index d901915..a8f59ba 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -19,8 +19,11 @@ enum ErrorCodes #include "io/serial/serial.h" #include "io/term/printf.h" #include "idt/idt.h" +#include -#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "debug: [%s]: " log "\r\n", __FILE__, ##__VA_ARGS__) +extern volatile uint64_t ticks; + +#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "[%8u] debug: [%s]: " log "\r\n", ticks, __FILE__, ##__VA_ARGS__) /* #define DEBUG(log, ...) \ @@ -38,6 +41,7 @@ void panic(struct cpu_status_t* ctx, const char* str); void hcf(); void idle(); +/* debug */ void debug_stack_trace(unsigned int max_frames); const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset); void boot_mem_display(); @@ -52,4 +56,13 @@ struct boot_context struct limine_kernel_address_response* kaddr; }; +// Are these modules initialized yet? +struct init_status +{ + bool terminal; + bool serial; + bool keyboard; + bool timer; +}; + #endif diff --git a/src/kmain.c b/src/kmain.c index cb79c5e..557c10a 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -30,8 +30,6 @@ __attribute__((used, section(".limine_requests"))) volatile LIMINE_BASE_REVISION(3); -struct flanterm_context *ft_ctx; - // Halt and catch fire (makes machine stall) void hcf() { @@ -41,9 +39,9 @@ void hcf() // Doing nothing (can be interrupted) void idle() {SET_INTERRUPTS; for(;;)asm("hlt");} -// uint8_t kernel_stack[KERNEL_STACK_SIZE] __attribute__((aligned(16))); - +struct flanterm_context *ft_ctx; struct boot_context boot_ctx; +struct init_status init = {0}; extern volatile struct limine_framebuffer_request framebuffer_request; extern volatile struct limine_memmap_request memmap_request; @@ -64,12 +62,6 @@ void idle_main(void* arg) for(;;)asm("hlt"); } -void flanterm_free_wrapper(void* ptr, size_t size) -{ - (void)size; - kfree(ptr); -} - extern uintptr_t kheap_start; // This is our entry point @@ -79,6 +71,7 @@ void kmain() if (!LIMINE_BASE_REVISION_SUPPORTED) hcf(); serial_init(); + timer_init(); // Populate boot context boot_ctx.fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL; @@ -95,29 +88,10 @@ void kmain() keyboard_init(FR); - uint32_t bgColor = 0x252525; - ft_ctx = flanterm_fb_init( - kmalloc, - flanterm_free_wrapper, - boot_ctx.fb->address, boot_ctx.fb->width, boot_ctx.fb->height, boot_ctx.fb->pitch, - boot_ctx.fb->red_mask_size, boot_ctx.fb->red_mask_shift, - boot_ctx.fb->green_mask_size, boot_ctx.fb->green_mask_shift, - boot_ctx.fb->blue_mask_size, boot_ctx.fb->blue_mask_shift, - NULL, - NULL, NULL, - &bgColor, NULL, // &bgColor - NULL, NULL, - NULL, 0, 0, 1, - 0, 0, - 0, - 0 - ); + term_init(); gdt_init(); idt_init(); - - timer_init(); - vmm_init(); process_init(); struct process_t* idle_proc = process_create("idle", (void*)idle_main, 0); @@ -131,5 +105,6 @@ void kmain() current_process->status = RUNNING; kputs(PEPPEROS_SPLASH); + //panic(NULL, "Test panic"); idle(); } diff --git a/src/time/timer.c b/src/time/timer.c index 781c677..ab1cc24 100644 --- a/src/time/timer.c +++ b/src/time/timer.c @@ -18,6 +18,8 @@ interested in multi-core functionnality like SMP) volatile uint64_t ticks = 0; +extern struct init_status init; + void pic_remap() { uint8_t master_mask = inb(0x21); @@ -91,4 +93,5 @@ void timer_init() pic_enable(); pit_init(); DEBUG("PIT initialized"); + init.timer = true; } \ No newline at end of file From 3f9b78b05e9629d43a09ebf68ad5284ada47c581 Mon Sep 17 00:00:00 2001 From: xamidev Date: Mon, 9 Mar 2026 09:27:55 +0100 Subject: [PATCH 3/3] Scheduler returns to IDLE when.. idle. --- README.md | 1 + src/idt/idt.c | 3 +-- src/kernel.h | 3 +-- src/kmain.c | 16 ++++++++++------ src/sched/process.c | 4 ++-- src/sched/scheduler.c | 10 +++++----- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 113bfb2..70a26f1 100644 --- a/README.md +++ b/README.md @@ -47,3 +47,4 @@ PepperOS wouldn't be possible without the following freely-licensed software: - the [OSDev](https://osdev.org) wiki & forums - Intel 64 and IA-32 Architectures Software Developer's Manual +- Documentation for the [GNU Compiler Collection](https://gcc.gnu.org/onlinedocs/gcc/) \ No newline at end of file diff --git a/src/idt/idt.c b/src/idt/idt.c index bab6525..5b9504b 100644 --- a/src/idt/idt.c +++ b/src/idt/idt.c @@ -52,8 +52,7 @@ void idt_load(void* idt_addr) void idt_init() { - // We set 256 entries, but we have only the first few stubs. - // Undefined behavior? + // Hardcoded... for (size_t i=0; i<=33; i++) { // Each vector handler is 16-byte aligned, so *16 = address of that handler diff --git a/src/kernel.h b/src/kernel.h index a8f59ba..f7dd570 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -23,8 +23,7 @@ enum ErrorCodes extern volatile uint64_t ticks; -#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "[%8u] debug: [%s]: " log "\r\n", ticks, __FILE__, ##__VA_ARGS__) - +#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "[%8u] debug: <%s>: " log "\r\n", ticks, __func__, ##__VA_ARGS__) /* #define DEBUG(log, ...) \ printf("debug: [%s]: " log "\r\n", __FILE__, ##__VA_ARGS__); \ diff --git a/src/kmain.c b/src/kmain.c index 557c10a..5c38aa3 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -50,16 +50,24 @@ extern volatile struct limine_kernel_address_request kerneladdr_request; extern struct process_t* processes_list; extern struct process_t* current_process; +struct process_t* idle_proc; +bool iran = false; + +// Never gets executed although pedicel is scheduled? void pedicel_main(void* arg) { + bool iran = true; // FROM THE NEXT LINE ONWARDS, CANNOT WRITE TO FRAMEBUFFER WITHOUT PAGE FAULT! //printf("\n\nWelcome to PepperOS! Pedicel speaking.\nNothing left to do, halting the system!"); } void idle_main(void* arg) { - for(;;)asm("hlt"); + for (;;) + { + asm("hlt"); + } } extern uintptr_t kheap_start; @@ -94,17 +102,13 @@ void kmain() idt_init(); process_init(); - struct process_t* idle_proc = process_create("idle", (void*)idle_main, 0); + idle_proc = process_create("idle", (void*)idle_main, 0); struct process_t* pedicel = process_create("pedicel", (void*)pedicel_main, 0); process_display_list(processes_list); scheduler_init(); - current_process = idle_proc; - current_process->status = RUNNING; - kputs(PEPPEROS_SPLASH); - //panic(NULL, "Test panic"); idle(); } diff --git a/src/sched/process.c b/src/sched/process.c index e0fc25b..484f7dc 100644 --- a/src/sched/process.c +++ b/src/sched/process.c @@ -45,7 +45,7 @@ void process_display_list(struct process_t* processes_list) struct process_t* process_create(char* name, void(*function)(void*), void* arg) { -/* CLEAR_INTERRUPTS; */ + CLEAR_INTERRUPTS; struct process_t* proc = (struct process_t*)kmalloc(sizeof(struct process_t)); struct cpu_status_t* ctx = (struct cpu_status_t*)kmalloc(sizeof(struct cpu_status_t)); @@ -79,7 +79,7 @@ struct process_t* process_create(char* name, void(*function)(void*), void* arg) process_add(&processes_list, proc); -/* SET_INTERRUPTS; */ + SET_INTERRUPTS; return proc; } diff --git a/src/sched/scheduler.c b/src/sched/scheduler.c index e1b3299..14a3fe0 100644 --- a/src/sched/scheduler.c +++ b/src/sched/scheduler.c @@ -12,6 +12,7 @@ extern struct process_t* processes_list; extern struct process_t* current_process; +extern struct process_t* idle_proc; void scheduler_init() { @@ -28,9 +29,8 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context) if (current_process == NULL) { - // Wtf happened - current_process = processes_list; - //panic(NULL, "Scheduler called without current process"); + // If no more processes, then set IDLE as the current process, that's it. + current_process = idle_proc; } current_process->context = context; @@ -49,15 +49,15 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context) if (current_process != NULL && current_process->status == DEAD) { process_delete(&prev_process, current_process); + current_process = NULL; + return idle_proc->context; } else { current_process->status = RUNNING; break; } } - - // Current_process gets wrong context?? (iret_rip points to other stuff than process function; like putpixel() for example) DEBUG("current_process={pid=%u, name='%s', root_page_table[virt]=%p}", current_process->pid, current_process->name, current_process->root_page_table); load_cr3(VIRT_TO_PHYS((uint64_t)current_process->root_page_table));