From b4b30fbac6510efd65a9215074cc3356826c5b40 Mon Sep 17 00:00:00 2001 From: g1n Date: Wed, 2 Feb 2022 20:10:52 +0200 Subject: [PATCH] Add paging --- src/Makefile | 2 ++ src/early_kernel.c | 2 ++ src/include/paging.h | 9 ++++++++ src/paging.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 src/include/paging.h create mode 100644 src/paging.c diff --git a/src/Makefile b/src/Makefile index 0a6b83e..28f589f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -22,6 +22,7 @@ build/early_kernel.o \ build/kernel.o \ build/vga.o \ build/idt.o \ +build/paging.o \ $(CRTEND_OBJ) $(CRTN_OBJ) KERNELFILE = build/orion.bin @@ -41,6 +42,7 @@ all: i686-elf-gcc -c vga.c -o build/vga.o $(CFLAGS) i686-elf-gcc -c idt.c -o build/idt.o $(CFLAGS) + i686-elf-gcc -c paging.c -o build/paging.o $(CFLAGS) i686-elf-gcc -c kernel.c -o build/kernel.o $(CFLAGS) i686-elf-gcc -c early_kernel.c -o build/early_kernel.o $(CFLAGS) diff --git a/src/early_kernel.c b/src/early_kernel.c index 5335954..f0ec313 100644 --- a/src/early_kernel.c +++ b/src/early_kernel.c @@ -1,9 +1,11 @@ #include #include +#include #include #include void early_kernel_main() { terminal_initialize(); idt_init(); + paging_init(); } diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c12ac83 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,9 @@ +#ifndef PAGING_H +#define PAGING_H + +#include + +void paging_init(); +void page_fault(registers_t regs); + +#endif diff --git a/src/paging.c b/src/paging.c new file mode 100644 index 0000000..014add4 --- /dev/null +++ b/src/paging.c @@ -0,0 +1,50 @@ +#include +#include +#include + +uint32_t page_directory[1024] __attribute__((aligned(4096))); +uint32_t first_page_table[1024] __attribute__((aligned(4096))); + +void page_fault(registers_t regs) { + uint32_t faulting_address; + __asm__ volatile("mov %%cr2, %0" : "=r" (faulting_address)); + + // The error code gives us details of what happened. + int present = !(regs.err_code & 0x1); // Page not present + int rw = regs.err_code & 0x2; // Write operation? + int us = regs.err_code & 0x4; // Processor was in user-mode? + int reserved = regs.err_code & 0x8; // Overwritten CPU-reserved bits of page entry? + //int id = regs.err_code & 0x10; // Caused by an instruction fetch? + + kprintf("Page fault: ( "); + if (present) {kprintf("present ");} + if (rw) {kprintf("read-only ");} + if (us) {kprintf("user-mode ");} + if (reserved) {kprintf("reserved ");} + kprintf(") at 0x%x\n", faulting_address); + kprintf("PAGE FAULT\n"); +} + +void enable_paging(uint32_t *dir) { + __asm__ volatile("mov %0, %%cr3":: "r"(dir)); + uint32_t cr0; + __asm__ volatile("mov %%cr0, %0": "=r"(cr0)); + cr0 |= 0x80000001; // Enable paging! + __asm__ volatile("mov %0, %%cr0":: "r"(cr0)); +} + +void paging_init() { + int i; + for(i = 0; i < 1024; i++) { + page_directory[i] = 0x00000002; + } + + for(i = 0; i < 1024; i++) { + first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present. + } + + page_directory[0] = ((unsigned int)first_page_table) | 3; + + register_interrupt_handler(14, &page_fault); + enable_paging(page_directory); +}