Fix PMM for real HW + serial lock

This commit is contained in:
2026-03-19 16:54:23 +01:00
parent b77c53ae99
commit 6a82d581fb
9 changed files with 52 additions and 45 deletions

View File

@@ -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)

View File

@@ -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 " : "");
}
}
/*

View File

@@ -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;

View File

@@ -6,9 +6,13 @@
#include <kernel.h>
#include <io/serial/serial.h>
#include <sched/spinlock.h>
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);
}
}
/*

View File

@@ -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
*

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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 <mem/paging.h>
#include <limine.h>
#include <stddef.h>
@@ -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; i<memmap->entry_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);
}

View File

@@ -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;
}
}