diff --git a/Makefile b/Makefile index 86a11ad..809e8ee 100644 --- a/Makefile +++ b/Makefile @@ -91,8 +91,8 @@ LibCDep=$(patsubst %.c,$(KOBJDIR)/%.d,$(LibCSources)) LibCObj += $(KOBJDIR)/libc/atoi.o $(KOBJDIR)/libc/itoa.o # Kernel sources -KernSources = kernel/ke/cpuid.c \ - kernel/ke/idt.c kernel/init/init.c \ +KernSources = kernel/ke/cpuid.c kernel/mm/paging.c \ + kernel/ke/idt.c kernel/init/init.c \ kernel/init/table.c kernel/io/cursor.c \ kernel/ke/log.c kernel/io/vga.c \ kernel/ke/panic.c kernel/mm/map.c \ @@ -161,6 +161,15 @@ $(KOBJDIR)/kernel/ke/idt.o: $(KALEIDDIR)/kernel/ke/idt.c \ @rm -f $@.1 $@.2 @echo ${CL2}[$@] ${CL}Compiled.${CL3} +$(KOBJDIR)/kernel/mm/paging.o: $(KALEIDDIR)/kernel/mm/paging.c \ + $(KALEIDDIR)/kernel/mm/paging.asm | $(KOBJDIR) + @mkdir -p $(shell dirname $@) + @$(ASM) $(ASMFLAGS) $(KALEIDDIR)/kernel/mm/paging.asm -o $@.1 + @$(KCC) $< -o $@.2 + @$(LD) $(LDFLAGS) -r $@.1 $@.2 -o $@ + @rm -f $@.1 $@.2 + @echo ${CL2}[$@] ${CL}Compiled.${CL3} + $(KOBJDIR)/kernel/mm/gdt.o: $(KALEIDDIR)/kernel/mm/gdt.c \ $(KALEIDDIR)/kernel/mm/gdt.asm | $(KOBJDIR) @mkdir -p $(shell dirname $@) diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index 3d775d2..9cf71bf 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -24,6 +24,8 @@ #include "init.h" +void MmInitPaging(void); + // // Entry point of the Kaleid kernel // @@ -52,6 +54,7 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) KeEnableIRQs(); // Several inits + MmInitPaging(); MmInitHeap(); // Start drivers diff --git a/kaleid/kernel/mm/paging.asm b/kaleid/kernel/mm/paging.asm new file mode 100644 index 0000000..222a83d --- /dev/null +++ b/kaleid/kernel/mm/paging.asm @@ -0,0 +1,24 @@ + +global MmEnableWriteProtect +global MmDisableWriteProtect +global MmLoadPML4 + +MmEnableWriteProtect: + push rax + mov rax, cr0 + or rax, 1<<16 + mov cr0, rax + pop rax + ret + +MmDisableWriteProtect: + push rax + mov rax, cr0 + and rax, ~(1<<16) + mov cr0, rax + pop rax + ret + +MmLoadPML4: + mov cr3, rsi + ret diff --git a/kaleid/kernel/mm/paging.c b/kaleid/kernel/mm/paging.c new file mode 100644 index 0000000..aff8118 --- /dev/null +++ b/kaleid/kernel/mm/paging.c @@ -0,0 +1,65 @@ +#include + +#define PAGESIZE (4 * KB) +#define PAGEALIGNED __attribute__((__aligned__(4096))) + +// Page directory pointer offset +typedef uint pdpe_t; + +// Page directory offset +typedef uint pde_t; + +// Page table entry +typedef uint pte_t; + +// paging.asm +void MmLoadPML4(void *); +void MmEnableWriteProtect(void); +void MmDisableWriteProtect(void); + +enum +{ + MF_PRESENT = 1 << 0, + MF_READWRITE = 1 << 1, + MF_USERMODE = 1 << 2, + MF_WRITETHR = 1 << 3, + MF_CACHEDIS = 1 << 4, + MF_ACCESSED = 1 << 5, + MF_DIRTY = 1 << 6 +}; + +//----------- + +pdpe_t pml4[1024] ; + +// First PDPE of our pml4 +pde_t first_pdpe[1024] PAGEALIGNED; + +// First PDP of first_pdpe +pte_t first_pde[1024] PAGEALIGNED; + +// First PTE of first_pde +uint first_pte[1024] PAGEALIGNED; + +void MmInitPaging(void) +{ + size_t i; + + // Set all PDPEs to kernel-mode not present + for (i = 0; i < 1024; i++) pml4[i] = MF_READWRITE; + for (i = 0; i < 1024; i++) first_pdpe[i] = MF_READWRITE; + for (i = 0; i < 1024; i++) first_pde[i] = MF_READWRITE; + + // Set all pages in first_pte to kernel-mode present + for (i = 0; i < 1024; i++) { + first_pte[i] = (i * PAGESIZE) | (MF_READWRITE | MF_PRESENT); + } + + // Install the first PTE + first_pde[0] = (uint)(ulong)first_pte | (MF_READWRITE | MF_PRESENT); + first_pdpe[0] = (uint)(ulong)first_pde | (MF_READWRITE | MF_PRESENT); + pml4[0] = (uint)(ulong)first_pdpe | (MF_READWRITE | MF_PRESENT); + + MmLoadPML4(pml4); +} +