From e1bcd70747ea5c9b7ab64ebf1add36ba7abda2dc Mon Sep 17 00:00:00 2001 From: Alexander Myltsev Date: Fri, 17 Jan 2025 23:29:01 +0400 Subject: [PATCH] Add kvmalloc. --- Makefile | 6 +++--- cpu/gdt.c | 1 + cpu/memlayout.h | 24 +++++++++++++++++++++++- cpu/x86.h | 6 ++++++ drivers/keyboard.c | 2 +- drivers/vga.c | 3 ++- kernel.c | 8 ++++++-- kernel/kstart.S | 11 ++++++++--- {lib => kernel}/mem.c | 0 kernel/mem.h | 14 ++++++++++++++ kernel/vm.c | 18 ++++++++++++++++++ lib/mem.h | 5 ----- lib/string.h | 1 - proc.c | 2 +- 14 files changed, 83 insertions(+), 18 deletions(-) rename {lib => kernel}/mem.c (100%) create mode 100644 kernel/mem.h create mode 100644 kernel/vm.c delete mode 100644 lib/mem.h diff --git a/Makefile b/Makefile index 2fbbb6e..dbaa2ec 100644 --- a/Makefile +++ b/Makefile @@ -26,8 +26,8 @@ LDKERNELFLAGS = --script=script.ld endif OBJECTS = kernel/kstart.o kernel.o console.o drivers/vga.o drivers/uart.o drivers/keyboard.o \ - cpu/idt.o cpu/gdt.o cpu/swtch.o cpu/vectors.o lib/mem.o proc.o lib/string.o \ - fs/fs.o drivers/ata.o lib/mem.o lib/string.o proc.o drivers/pit.o + cpu/idt.o cpu/gdt.o cpu/swtch.o cpu/vectors.o kernel/mem.o proc.o lib/string.o \ + fs/fs.o drivers/ata.o lib/string.o proc.o drivers/pit.o kernel/vm.o run: image.bin qemu-system-i386 -drive format=raw,file=$< -serial mon:stdio @@ -98,7 +98,7 @@ image.bin: mbr.bin fs.img cat $^ >$@ kernel.bin: $(OBJECTS) - $(LD) $(LDFLAGS) $(LDKERNELFLAGS) -o $@ -Ttext 0xf0009000 $^ + $(LD) $(LDFLAGS) $(LDKERNELFLAGS) -o $@ -Ttext 0x80009000 $^ bootmain.o: bootmain.c $(CC) $(CFLAGS) -Os -c $< -o $@ diff --git a/cpu/gdt.c b/cpu/gdt.c index f511ef0..0b046c9 100644 --- a/cpu/gdt.c +++ b/cpu/gdt.c @@ -1,5 +1,6 @@ #include "gdt.h" #include "../lib/string.h" +#include "kernel/mem.h" #include diff --git a/cpu/memlayout.h b/cpu/memlayout.h index d45326e..33a5818 100644 --- a/cpu/memlayout.h +++ b/cpu/memlayout.h @@ -1,8 +1,30 @@ #pragma once -#define KERNBASE 0xf0000000 +#define KERNBASE 0x80000000 #define PGSIZE 0x1000 #define PHYSTOP 0x8000000 #define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1)) + +#define PDXSHIFT 22 // offset of PDX in a linear address + +#define PXMASK 0x3FF + +#ifndef __ASSEMBLER__ +#include #define V2P(a) (((uintptr_t) (a)) - KERNBASE) +#define P2V(a) ((void *)(((uintptr_t) (a)) + KERNBASE)) + +// page directory index +#define PDX(va) (((uintptr_t)(va) >> PDXSHIFT) & PXMASK) +#endif + +// Page table/directory entry flags. +#define PTE_P 0x001 // Present +#define PTE_W 0x002 // Writeable +#define PTE_U 0x004 // User +#define PTE_PWT 0x008 // Write-Through +#define PTE_PCD 0x010 // Cache-Disable +#define PTE_A 0x020 // Accessed +#define PTE_D 0x040 // Dirty +#define PTE_PS 0x080 // Page Size diff --git a/cpu/x86.h b/cpu/x86.h index ae0488e..fafd892 100644 --- a/cpu/x86.h +++ b/cpu/x86.h @@ -11,3 +11,9 @@ stosb(void *addr, unsigned char data, int cnt) { asm volatile("cld; rep stosb" : : "D"(addr), "c"(cnt), "a"(data) : "memory"); } + +static inline void +lcr3(uint32_t val) +{ + asm volatile("mov %0,%%cr3" : : "r" (val)); +} diff --git a/drivers/keyboard.c b/drivers/keyboard.c index ad38a9b..c78615f 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -3,7 +3,7 @@ #include "cpu/memlayout.h" #include "console.h" #include "port.h" -#include "lib/mem.h" +#include "kernel/mem.h" static const char sc_ascii[] = { '?', '?', '1', '2', '3', '4', '5', '6', diff --git a/drivers/vga.c b/drivers/vga.c index 7cd44ee..ad0a364 100644 --- a/drivers/vga.c +++ b/drivers/vga.c @@ -1,7 +1,8 @@ #include "port.h" #include "../lib/string.h" +#include "cpu/memlayout.h" -static char* const video_memory = (char*) 0xb8000; +static char* const video_memory = (char*) (KERNBASE + 0xb8000); enum colors16 { black = 0, diff --git a/kernel.c b/kernel.c index fa83a72..98695fb 100644 --- a/kernel.c +++ b/kernel.c @@ -1,8 +1,7 @@ -asm(".asciz \"kernel start\\n\""); - #include "console.h" #include "cpu/isr.h" #include "cpu/gdt.h" +#include "cpu/memlayout.h" #include "drivers/keyboard.h" #include "drivers/vga.h" #include "drivers/ata.h" @@ -12,9 +11,14 @@ asm(".asciz \"kernel start\\n\""); #include "fs/fs.h" #include "lib/string.h" #include "proc.h" +#include "kernel/mem.h" void kmain() { + freerange(P2V(1u<<20), P2V(2u<<20)); // 1MB - 2MB + kvmalloc(); // map all of physical memory at KERNBASE + freerange(P2V(2u<<20), P2V(PHYSTOP)); + load_gdt(); init_keyboard(); init_pit(); diff --git a/kernel/kstart.S b/kernel/kstart.S index 73f49fb..51327a1 100644 --- a/kernel/kstart.S +++ b/kernel/kstart.S @@ -24,9 +24,14 @@ _start: // Set up the page table for the lowest 4 MiB: PD[0] -> PT mov dword ptr [0x1000], 0x2000 | 0x3 - // KERNBASE = 0xF000_0000 - // Use the same page table for the first 4 MiB after KERNBASE: PD[0x3c0] -> PT - mov dword ptr [0x1000 + (0x3c0 * 4)], 0x2000 | 0x3 + // KERNBASE = 0x8000_0000 + // Use the same page table for the first 4 MiB after KERNBASE: PD[0x200] -> PT + mov dword ptr [0x1000 + ((KERNBASE >> 22) * 4)], 0x2000 | 0x3 + + // Enable 4 MiB pages + mov eax, cr4 + or eax, 0x10 // Set the PSE bit (bit 4) + mov cr4, eax // Identity map the first 2 MiB mov edi, 0x2000 // Start of the PT diff --git a/lib/mem.c b/kernel/mem.c similarity index 100% rename from lib/mem.c rename to kernel/mem.c diff --git a/kernel/mem.h b/kernel/mem.h new file mode 100644 index 0000000..56ee2d5 --- /dev/null +++ b/kernel/mem.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +typedef uintptr_t pde_t; +typedef uintptr_t pte_t; + +void* memset(void *dst, unsigned c, uint64_t n); + +void freerange(void *vstart, void *vend); +void* kalloc(void); +void kfree(char*); + +void kvmalloc(); \ No newline at end of file diff --git a/kernel/vm.c b/kernel/vm.c new file mode 100644 index 0000000..e6836e6 --- /dev/null +++ b/kernel/vm.c @@ -0,0 +1,18 @@ +#include "mem.h" +#include "cpu/memlayout.h" +#include "cpu/x86.h" + +pde_t *kvm; + +void kvmalloc() { + kvm = kalloc(); + memset(kvm, 0, PGSIZE); + + // Map physical memory to KERNBASE..KERNBASE+PHYSTOP + for (uintptr_t pa = 0; pa < PHYSTOP; pa += 4 << 20) { + uintptr_t va = KERNBASE + pa; + kvm[PDX(va)] = pa | PTE_P | PTE_W | PTE_PS; + } + + lcr3(V2P(kvm)); +} diff --git a/lib/mem.h b/lib/mem.h deleted file mode 100644 index 8af959f..0000000 --- a/lib/mem.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -void freerange(void *vstart, void *vend); -void* kalloc(void); -void kfree(char*); diff --git a/lib/string.h b/lib/string.h index 6184c33..584f7d7 100644 --- a/lib/string.h +++ b/lib/string.h @@ -4,4 +4,3 @@ typedef unsigned size_t; void kmemmove(char* dst, char* src, size_t size); int strncmp(const char* s1, const char* s2, size_t size); -void memset(void* b, char c, size_t len); diff --git a/proc.c b/proc.c index 47b9432..3b462d6 100644 --- a/proc.c +++ b/proc.c @@ -3,7 +3,7 @@ #include "fs/fs.h" #include "cpu/gdt.h" #include "cpu/isr.h" -#include "lib/mem.h" +#include "kernel/mem.h" #include "lib/string.h" #include "console.h"