memory #7
4
Makefile
4
Makefile
@@ -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
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
13
src/mem/paging/paging.c
Normal 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);
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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());
|
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user