From 6a82d581fb03c2788c7d960245c778a62268d05d Mon Sep 17 00:00:00 2001 From: xamidev Date: Thu, 19 Mar 2026 16:54:23 +0100 Subject: [PATCH] Fix PMM for real HW + serial lock --- include/config.h | 2 +- src/debug/panic.c | 21 --------------------- src/idt/idt.c | 2 +- src/io/serial/serial.c | 16 +++++++++++++--- src/io/term/term.c | 2 +- src/kmain.c | 5 +++-- src/mem/paging.c | 4 ++-- src/mem/pmm.c | 41 ++++++++++++++++++++++++++++------------- src/sched/scheduler.c | 4 +++- 9 files changed, 52 insertions(+), 45 deletions(-) diff --git a/include/config.h b/include/config.h index 5c3dbc5..0231bf0 100644 --- a/include/config.h +++ b/include/config.h @@ -31,7 +31,7 @@ #define KERNEL_IDT_ENTRIES 33 /* paging */ -#define PAGING_MAX_PHYS 0x100000000 +#define PAGING_MAX_PHYS 0x200000000 /* heap */ #define KHEAP_SIZE (32*1024*1024) diff --git a/src/debug/panic.c b/src/debug/panic.c index 5fc2069..0e91c35 100644 --- a/src/debug/panic.c +++ b/src/debug/panic.c @@ -36,27 +36,6 @@ void read_rflags(uint64_t rflags) CHECK_BIT(rflags, 19) ? "VIF " : "", /*virtual interrupt flag*/ CHECK_BIT(rflags, 20) ? "VIP " : "", /*virtual interrupt pending*/ CHECK_BIT(rflags, 21) ? "ID " : ""); /*id flag*/ - - if (init.terminal) { - printf("\x1b[38;5;226m%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\x1b[38;5;231m\r\n", - CHECK_BIT(rflags, 0) ? "CF " : "", - CHECK_BIT(rflags, 2) ? "PF " : "", - CHECK_BIT(rflags, 4) ? "AF " : "", - CHECK_BIT(rflags, 6) ? "ZF " : "", - CHECK_BIT(rflags, 7) ? "SF " : "", - CHECK_BIT(rflags, 8) ? "TF " : "", - CHECK_BIT(rflags, 9) ? "IF " : "", - CHECK_BIT(rflags, 10) ? "DF " : "", - CHECK_BIT(rflags, 11) ? "OF " : "", - (CHECK_BIT(rflags, 12) && CHECK_BIT(rflags, 13)) ? "IOPL3 " : "IOPL0 ", - CHECK_BIT(rflags, 14) ? "NT " : "", - CHECK_BIT(rflags, 16) ? "RF " : "", - CHECK_BIT(rflags, 17) ? "VM " : "", - CHECK_BIT(rflags, 18) ? "AC " : "", - CHECK_BIT(rflags, 19) ? "VIF " : "", - CHECK_BIT(rflags, 20) ? "VIP " : "", - CHECK_BIT(rflags, 21) ? "ID " : ""); - } } /* diff --git a/src/idt/idt.c b/src/idt/idt.c index c101d05..51b0eca 100644 --- a/src/idt/idt.c +++ b/src/idt/idt.c @@ -258,7 +258,7 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context) case 33: // Keyboard Interrupt keyboard_handler(); - //process_create("keyboard-initiated", kbdproc_main, NULL); // DEBUG + process_create("keyboard-initiated", kbdproc_main, NULL); // DEBUG outb(0x20, 0x20); break; diff --git a/src/io/serial/serial.c b/src/io/serial/serial.c index 95ea78f..f36a450 100644 --- a/src/io/serial/serial.c +++ b/src/io/serial/serial.c @@ -6,9 +6,13 @@ #include #include +#include extern struct init_status init; +extern int panic_count; +struct spinlock_t serial_lock = {0}; + /* * outb - Writes a byte to a CPU port * @port: CPU port to write to @@ -85,9 +89,15 @@ static int is_transmit_empty() */ void skputc(char c) { - // TODO: Spinlock here (serial access) - while (!is_transmit_empty()); // wait for free spot - outb(PORT, c); + if (panic_count == 0) { + spinlock_acquire(&serial_lock); + while (!is_transmit_empty()); // wait for free spot + outb(PORT, c); + spinlock_release(&serial_lock); + } else { + while (!is_transmit_empty()); + outb(PORT, c); + } } /* diff --git a/src/io/term/term.c b/src/io/term/term.c index 785151d..31f7b18 100644 --- a/src/io/term/term.c +++ b/src/io/term/term.c @@ -113,7 +113,7 @@ extern struct flanterm_context* ft_ctx; extern struct boot_context boot_ctx; /* - * flanterm_free_wrapper - free() wrapper for Flanterm + * flanterm_free_wrapper - free() wrapper for Flanterm (DEPRECATED) * @ptr: pointer to free * @size: amount of bytes to free * diff --git a/src/kmain.c b/src/kmain.c index 139a515..2926773 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -80,10 +80,11 @@ void idle_main(void* arg) void thing_main(void* arg) { - printf("What's your name, pal? "); +/* printf("What's your name, pal? "); char name[10]; keyboard_getline(name, 10); - printf("\r\n{%s} is such a nice name!\r\n", name); + printf("\r\n{%s} is such a nice name!\r\n", name); */ + while (ticks < 500); } extern uintptr_t kheap_start; diff --git a/src/mem/paging.c b/src/mem/paging.c index b1de8a5..ae75bb4 100644 --- a/src/mem/paging.c +++ b/src/mem/paging.c @@ -173,9 +173,9 @@ void paging_init(struct boot_context boot_ctx) } } - // 4GB + // 8GB if (max_phys > PAGING_MAX_PHYS) { - DEBUG("WARNING: max_phys capped to 4GB (%x) (from max_phys=%p)", PAGING_MAX_PHYS, max_phys); + DEBUG("WARNING: max_phys capped to PAGING_MAX_PHYS (from max_phys=%p)", max_phys); max_phys = PAGING_MAX_PHYS; } diff --git a/src/mem/pmm.c b/src/mem/pmm.c index 81f7cfd..564837c 100644 --- a/src/mem/pmm.c +++ b/src/mem/pmm.c @@ -11,6 +11,7 @@ it will probably need to get some info from Limine, to see which pages are used by kernel/bootloader/mmio/fb etc. */ +#include "config.h" #include #include #include @@ -24,10 +25,11 @@ First we'll have to discover the physical memory layout, and for that we can use a Limine request. */ +// DEPRECATED struct limine_memmap_entry* biggest_entry; /* - * pmm_find_biggest_usable_region - Finding the biggest free memory region + * pmm_find_biggest_usable_region - Finding the biggest free memory region (DEPRECATED) * @memmap: Limine memory map * @hhdm: Limine HHDM offset * @@ -99,19 +101,32 @@ void pmm_free(uintptr_t addr) * This function marks the biggest memory region as * free, so we can use it in pmm_alloc. */ -static void pmm_init_freelist() +static void pmm_init_freelist(struct limine_memmap_response* memmap) { - // We simply call pmm_free() on each page that is marked USABLE - // in our big memory region. - uint64_t base = ALIGN_UP(biggest_entry->base, PAGE_SIZE); - uint64_t end = ALIGN_DOWN(biggest_entry->base + biggest_entry->length, PAGE_SIZE); + uint64_t total_pages = 0; - uint64_t page_count=0; - for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) { - pmm_free(addr); - page_count++; + for (size_t i=0; ientry_count; i++) { + struct limine_memmap_entry* entry = memmap->entries[i]; + + if (entry->type == LIMINE_MEMMAP_USABLE) { + uint64_t base = ALIGN_UP(entry->base, PAGE_SIZE); + uint64_t end = ALIGN_DOWN(entry->base + entry->length, PAGE_SIZE); + + if (end > PAGING_MAX_PHYS) { + end = PAGING_MAX_PHYS; + } + + // Region above PAGING_MAX_PHYS + if (base >= end) continue; + + for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) { + pmm_free(addr); + total_pages++; + } + } } - DEBUG("%u frames in freelist, available for use (%u bytes)", page_count, page_count*PAGE_SIZE); + + DEBUG("%u frames in freelist, %u bytes available (%u MB)", total_pages, total_pages*PAGE_SIZE, total_pages*PAGE_SIZE/1000000); } /* @@ -124,9 +139,9 @@ static void pmm_init_freelist() void pmm_init(struct boot_context boot_ctx) { hhdm_off = boot_ctx.hhdm->offset; - pmm_find_biggest_usable_region(boot_ctx.mmap, boot_ctx.hhdm); + //pmm_find_biggest_usable_region(boot_ctx.mmap, boot_ctx.hhdm); // Now we have biggest USABLE region, // so to populate the free list we just iterate through it - pmm_init_freelist(); + pmm_init_freelist(boot_ctx.mmap); } diff --git a/src/sched/scheduler.c b/src/sched/scheduler.c index 3e98632..a03e314 100644 --- a/src/sched/scheduler.c +++ b/src/sched/scheduler.c @@ -49,7 +49,6 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context) } current_process->context = context; - //current_process->status = READY; for (;;) { struct process_t* prev_process = current_process; @@ -65,6 +64,9 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context) return idle_proc->context; } else { current_process->status = RUNNING; + if (prev_process != current_process) { + DEBUG("Changed from {pid=%u, name=%s} to {pid=%u, name=%s}", prev_process->pid, prev_process->name, current_process->pid, current_process->name); + } break; } }