memory #7

Merged
xamidev merged 7 commits from memory into main 2026-01-04 09:28:00 +01:00
10 changed files with 52 additions and 68 deletions
Showing only changes of commit bb5fb9db33 - Show all commits

View File

@@ -1,8 +1,8 @@
SOURCES = src/mem/paging/pmm.c src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c SOURCES = src/mem/paging/paging.c src/mem/paging/pmm.c src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
build: build:
rm -f *.o rm -f *.o
x86_64-elf-gcc -g -c -I src $(SOURCES) -Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel x86_64-elf-gcc -g -c -Isrc $(SOURCES) -Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel
objcopy -O elf64-x86-64 -B i386 -I binary zap-light16.psf zap-light16.o objcopy -O elf64-x86-64 -B i386 -I binary zap-light16.psf zap-light16.o
nasm -f elf64 src/idt/idt.S -o idt_stub.o nasm -f elf64 src/idt/idt.S -o idt_stub.o
x86_64-elf-ld -o pepperk -T linker.ld *.o x86_64-elf-ld -o pepperk -T linker.ld *.o

View File

@@ -1,8 +1,8 @@
#include "idt.h" #include "idt.h"
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include "../io/serial/serial.h" #include "io/serial/serial.h"
#include "../io/kbd/ps2.h" #include "io/kbd/ps2.h"
#include <kernel.h> #include <kernel.h>
struct interrupt_descriptor idt[256]; struct interrupt_descriptor idt[256];

View File

@@ -1,9 +1,9 @@
// PS/2 Keyboard support // PS/2 Keyboard support
#include "../serial/serial.h" #include "io/serial/serial.h"
#include "ps2.h" #include "ps2.h"
#include <stdint.h> #include <stdint.h>
#include "../term/term.h" #include "io/term/term.h"
#include <kernel.h> #include <kernel.h>
// The key status bitfield will be used to see if ALT, CONTROL, or SHIFT is pressed // The key status bitfield will be used to see if ALT, CONTROL, or SHIFT is pressed

View File

@@ -11,6 +11,7 @@
#include "time/timer.h" #include "time/timer.h"
#include "io/kbd/ps2.h" #include "io/kbd/ps2.h"
#include "mem/paging/pmm.h" #include "mem/paging/pmm.h"
#include "mem/paging/paging.h"
// Limine version used // Limine version used
__attribute__((used, section(".limine_requests"))) __attribute__((used, section(".limine_requests")))
@@ -73,6 +74,7 @@ void kmain()
hhdm_display(hhdm_request.response); hhdm_display(hhdm_request.response);
pmm_init(memmap_request.response, hhdm_request.response); pmm_init(memmap_request.response, hhdm_request.response);
paging_init();
CLEAR_INTERRUPTS; CLEAR_INTERRUPTS;
gdt_init(); gdt_init();

View File

@@ -1,6 +1,6 @@
#include "gdt.h" #include "gdt.h"
#include <stdint.h> #include <stdint.h>
#include "../../io/serial/serial.h" #include "io/serial/serial.h"
#include <kernel.h> #include <kernel.h>
// Descriptors are 8-byte wide (64bits) // Descriptors are 8-byte wide (64bits)

View File

@@ -1,8 +1,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <limine.h> #include <limine.h>
#include "../../kernel.h" #include "kernel.h"
#include "../../string/string.h" #include "string/string.h"
// We won't be linked to standard library, but still need the basic mem* functions // We won't be linked to standard library, but still need the basic mem* functions
// so everything goes allright with the compiler // so everything goes allright with the compiler

13
src/mem/paging/paging.c Normal file
View File

@@ -0,0 +1,13 @@
#include "paging.h"
#include <kernel.h>
void paging_init()
{
uint64_t cr3;
asm volatile ("mov %%cr3, %0" : "=r"(cr3));
// Root directory address (cr3 without 12 less significant bits)
uint64_t* pml4 = PHYS_TO_VIRT(cr3 & ~0xFFF);
DEBUG("pml4=0x%p", pml4);
}

View File

@@ -1,16 +1,29 @@
#ifndef PAGING_PMM_H #ifndef PAGING_H
#define PAGING_PMM_H #define PAGING_H
/*
We are going to use a bitmap, consisting of an array of uint64_t
to represent pages for the PMM (physical memory manager).
Bit set (1) = page used
Bit clear (0) = page free
*/
#define PAGE_SIZE 4096 #define PAGE_SIZE 4096
#define BITS_PER_ROW 64 #define BITS_PER_ROW 64
#include <stdint.h>
void paging_init();
extern uint64_t hhdm_off;
#define PHYS_TO_VIRT(x) ((void*)((uintptr_t)(x) + hhdm_off))
#define VIRT_TO_PHYS(x) ((uintptr_t)(x) - hhdm_off)
// Stole it
#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
#define ALIGN_DOWN(x, align) ((x) & ~((align) - 1))
// Page entry special bits
// Bits set on a parent (directory, table) fall back to their children
#define PTE_PRESENT (1ULL << 0)
#define PTE_WRITE (1ULL << 1)
#define PTE_USER (1ULL << 2)
#define PTE_HUGE (1ULL << 7)
#define PTE_NOEXEC (1ULL << 63)
#endif #endif

View File

@@ -12,7 +12,7 @@ to see which pages are used by kernel/bootloader/mmio/fb etc.
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <kernel.h> #include <kernel.h>
#include "../misc/utils.h" #include "mem/misc/utils.h"
#include "pmm.h" #include "pmm.h"
/* /*
@@ -27,42 +27,6 @@ and use this for the bitmap. The reserved memory will be ignored.
struct usable_memory* usable_mem; struct usable_memory* usable_mem;
struct limine_memmap_entry* biggest_entry; struct limine_memmap_entry* biggest_entry;
/*
uint64_t* bitmap;
uint64_t* usable_memory_begin;
// Bitmap will be placed at the start of the biggest usable region
// 1 bitmap page = 4096 bytes = 32768 bits
// So 1 bitmap page can track up to 32768 pages of memory
static void pmm_allocate_bitmap(struct limine_hhdm_response* hhdm)
{
uint64_t pages = biggest_entry->length / PAGE_SIZE;
uint64_t bitmap_items = (pages+BITS_PER_ROW-1)/BITS_PER_ROW;
DEBUG("we need %u pages (bits) that will fit in %u uint64_t", pages, bitmap_items);
bitmap = (uint64_t*)(biggest_entry->base + hhdm->offset);
DEBUG("bitmap will live at 0x%p", bitmap);
uint64_t bitmap_bytes = bitmap_items*sizeof(uint64_t);
// All pages are marked free since we're in a USABLE region
memset(bitmap, 0x00, bitmap_bytes);
uint64_t bitmap_pages = (bitmap_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
// The 1st memory page we can use is at bitmap + bitmap_pages
usable_memory_begin = (void*)((uintptr_t)bitmap + bitmap_pages*PAGE_SIZE);
// Mark bitmap as allocated
for (uint64_t i=0; i<bitmap_pages; i++)
{
uint64_t row = i / BITS_PER_ROW;
uint64_t bit = i % BITS_PER_ROW;
bitmap[row] |= (1ULL << bit);
}
DEBUG("bitmap occupies %u pages", bitmap_pages);
} */
static void pmm_find_biggest_usable_region(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm) static void pmm_find_biggest_usable_region(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm)
{ {
@@ -97,13 +61,6 @@ uint64_t hhdm_off;
static uintptr_t g_freelist = 0; static uintptr_t g_freelist = 0;
#define PHYS_TO_VIRT(x) ((void*)((uintptr_t)(x) + hhdm_off))
#define VIRT_TO_PHYS(x) ((uintptr_t)(x) - hhdm_off)
// Stole it
#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
#define ALIGN_DOWN(x, align) ((x) & ~((align) - 1))
uintptr_t pmm_alloc() uintptr_t pmm_alloc()
{ {
if (!g_freelist) return 0; if (!g_freelist) return 0;
@@ -130,8 +87,9 @@ static void pmm_init_freelist()
{ {
pmm_free(addr); pmm_free(addr);
//DEBUG("page %u lives at phys 0x%p (virt 0x%p)", page_count, addr, PHYS_TO_VIRT(addr)); //DEBUG("page %u lives at phys 0x%p (virt 0x%p)", page_count, addr, PHYS_TO_VIRT(addr));
//page_count++; page_count++;
} }
DEBUG("%u frames in freelist, available for use (%u bytes)", page_count, page_count*PAGE_SIZE);
} }
void pmm_init(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm) void pmm_init(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm)
@@ -143,6 +101,4 @@ void pmm_init(struct limine_memmap_response* memmap, struct limine_hhdm_response
// Now we have biggest USABLE region, // Now we have biggest USABLE region,
// so to populate the free list we just iterate through it // so to populate the free list we just iterate through it
pmm_init_freelist(); pmm_init_freelist();
DEBUG("Trying pmm_alloc gives us page at 0x%p", pmm_alloc());
} }

View File

@@ -1,5 +1,5 @@
#include <stdint.h> #include <stdint.h>
#include "../io/serial/serial.h" #include "io/serial/serial.h"
#include <kernel.h> #include <kernel.h>
/* /*