From 2d54f6f129cedad272084f4cfe3731309f4c462e Mon Sep 17 00:00:00 2001 From: Nic Gaffney Date: Wed, 28 Feb 2024 06:46:04 -0600 Subject: Enabled paging --- src/boot/boot.s | 15 +++++++++- src/include/exceptions.h | 2 +- src/include/paging.h | 13 ++++++++ src/include/print.h | 2 ++ src/kernel/exceptions.c | 9 ++++-- src/kernel/kernel.c | 11 +++++-- src/kernel/paging/mmap.c | 3 ++ src/kernel/paging/page_alloc.c | 5 ++++ src/kernel/paging/paging.c | 67 ++++++++++++++++++++++++++++++++++++++++++ src/kernel/print.c | 19 +++++++----- src/kernel/tables/gdt.c | 4 +-- src/linker.ld | 13 ++++---- 12 files changed, 141 insertions(+), 22 deletions(-) create mode 100644 src/include/paging.h create mode 100644 src/kernel/paging/mmap.c create mode 100644 src/kernel/paging/page_alloc.c create mode 100644 src/kernel/paging/paging.c (limited to 'src') diff --git a/src/boot/boot.s b/src/boot/boot.s index dbb4052..51bef8f 100644 --- a/src/boot/boot.s +++ b/src/boot/boot.s @@ -30,6 +30,10 @@ idtr: dw 0 dd 0 +global page_ptr +page_ptr: + dd 0 + global _start:function (_start.end - _start) _start: mov esp, stack_top @@ -37,7 +41,7 @@ _start: extern get_gdtr call get_gdtr cli - lgdt [gdtr] + lgdt [gdtr] mov eax, cr0 or al, 1 mov cr0, eax @@ -50,6 +54,15 @@ _start: sti xchg bx, bx + extern genDirs + extern page_dir + call genDirs + mov eax, page_dir + mov cr3, eax + mov eax, cr0 + or eax, 0x80000001 + mov cr0, eax + [bits 32] extern kernel_main call kernel_main diff --git a/src/include/exceptions.h b/src/include/exceptions.h index 1da8348..fddc66e 100644 --- a/src/include/exceptions.h +++ b/src/include/exceptions.h @@ -1,2 +1,2 @@ #pragma once -__attribute__((noreturn)) void panic(const char *msg); +__attribute__((noreturn)) void panic(const char *msg, ...); diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..11578c2 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,13 @@ +#ifndef __PAGING_H +#define __PAGING_H +#include +typedef uint32_t Page_Directory; +typedef uint32_t Page_Table; + +Page_Directory make_pagedir(Page_Table *addr, uint8_t flags); +Page_Directory make_pagetable(uint32_t addr, uint8_t flags); +void *get_physaddr(void *virtualaddr); +void map_page(void *physaddr, void *virtualaddr, uint8_t flags); +void genDirs(); +void *kalloc_init(); +#endif // !__PAGING_H diff --git a/src/include/print.h b/src/include/print.h index 7ef7fa3..63f5724 100644 --- a/src/include/print.h +++ b/src/include/print.h @@ -1,5 +1,6 @@ #pragma once +#include #include // Define colors for printing @@ -30,3 +31,4 @@ void print_char(char); int print_str(char *); void print_set_color(uint8_t, uint8_t); int printf(const char *, ...); +int printf_logic(const char *, va_list args); diff --git a/src/kernel/exceptions.c b/src/kernel/exceptions.c index 11e45fb..bd81c08 100644 --- a/src/kernel/exceptions.c +++ b/src/kernel/exceptions.c @@ -1,9 +1,14 @@ #include "print.h" +#include -__attribute__((noreturn)) void panic(const char *msg) { +__attribute__((noreturn)) void panic(const char *msg, ...) { + va_list args; + va_start(args, msg); print_set_color(PRINT_COLOR_BLACK, PRINT_COLOR_RED); print_clear(); - printf("PANIC!!\n\t%s", msg); + printf("PANIC!!\n\t"); + printf_logic(msg, args); + va_end(args); __asm__ volatile("cli; hlt"); while (1) ; diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index d960c20..c103476 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,9 +1,8 @@ +#include "exceptions.h" #include "gdt.h" #include "isr.h" +#include "paging.h" #include "print.h" -extern GDTR_t idtr; -extern GDTR_t gdtr; - #if defined(__linux__) #error "Not using cross compiler!" #endif @@ -14,6 +13,9 @@ extern GDTR_t gdtr; #endif void motd() { printf("Welcome to gftos!\n=================\n"); } +extern Page_Table pgtable[1024]; +extern Page_Directory page_dir[1024]; +extern GDT_t table; void kernel_main(void) { PIC_init(0x20, 0xA0); @@ -22,6 +24,9 @@ void kernel_main(void) { print_set_color(PRINT_COLOR_PINK, PRINT_COLOR_DARK_GRAY); print_clear(); motd(); + printf("Page Directory: %x\n", (Page_Directory *)page_dir[1023]); + printf("Page Table: %x\n", (Page_Table *)pgtable); + printf("GDT: %x\n", table); for (;;) { update_cursor(); asm("hlt"); diff --git a/src/kernel/paging/mmap.c b/src/kernel/paging/mmap.c new file mode 100644 index 0000000..662c2cd --- /dev/null +++ b/src/kernel/paging/mmap.c @@ -0,0 +1,3 @@ +#include "paging.h" +// TODO: write a frame page allocator to allocate page tables into virtual +// memory diff --git a/src/kernel/paging/page_alloc.c b/src/kernel/paging/page_alloc.c new file mode 100644 index 0000000..3c3e28f --- /dev/null +++ b/src/kernel/paging/page_alloc.c @@ -0,0 +1,5 @@ +#include "paging.h" +#include +#include +extern uint32_t endkernel; +// TODO: diff --git a/src/kernel/paging/paging.c b/src/kernel/paging/paging.c new file mode 100644 index 0000000..6a482c8 --- /dev/null +++ b/src/kernel/paging/paging.c @@ -0,0 +1,67 @@ +#include "paging.h" +#include "exceptions.h" +#include +extern uint32_t endkernel; + +Page_Directory make_pagedir(Page_Table *addr, uint8_t flags) { + return ((uint32_t)addr & 0xFFFFF000) | flags; +} + +Page_Table make_pagetable(uint32_t addr, uint8_t flags) { + return ((uint32_t)addr & 0xFFFFF000) | flags; +} + +Page_Directory page_dir[1024] __attribute__((aligned(4096))); +Page_Table pgtable[1024] __attribute__((aligned(4096))); + +void idpaging(uint32_t *first_pte, uint32_t from, int size) { + for (; size > 0; from += 4096, size -= 4096, first_pte++) { + *first_pte = make_pagetable(from, 3); // mark page present. + } +} + +void genDirs() { + for (int i = 0; i < 1024; i++) { + page_dir[i] = make_pagedir(0x0, 2); + for (int j = 0; j < 1024; j++) + ((uint32_t *)(page_dir[i] & 0xFFFFF000))[j] &= 0xFFFFFFFE; + } + + page_dir[1023] = make_pagetable((uint32_t)page_dir, 3); + + idpaging(&pgtable[0], 0x0, 1024 * 0x800); + page_dir[0] = make_pagedir(pgtable, 3); +} + +void *get_physaddr(void *virtualaddr) { + unsigned long pdindex = (unsigned long)virtualaddr >> 22; + unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF; + + unsigned long *pd = (unsigned long *)page_dir; + if (!(pd[pdindex] & 1)) + panic("Unimplemented - getphysaddr - pd[%d]", pdindex); + + unsigned long *pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex); + if (!(pt[ptindex] & 1)) + panic("Unimplemented - getphysaddr - pt[%d]", ptindex); + + return (void *)((pt[ptindex] & ~0xFFF) + + ((unsigned long)virtualaddr & 0xFFF)); +} + +void map_page(void *physaddr, void *virtualaddr, uint8_t flags) { + unsigned long pdindex = (unsigned long)virtualaddr >> 22; + unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF; + + unsigned long *pd = (unsigned long *)page_dir; + if (!(pd[pdindex] & 1)) { + pd[pdindex] = + make_pagedir((uint32_t *)0xFFC00000 + (0x400 * pdindex), 3); + } + + unsigned long *pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex); + if (pt[ptindex] & 1) + panic("Unimplemented - map_page - pt[%d]", ptindex); + + pt[ptindex] = ((unsigned long)physaddr) | (flags & 0xFFF) | 0x01; // Present +} diff --git a/src/kernel/print.c b/src/kernel/print.c index f635fe5..937a8aa 100644 --- a/src/kernel/print.c +++ b/src/kernel/print.c @@ -129,14 +129,10 @@ void print_set_color(uint8_t foreground, uint8_t background) { color = foreground + (background << 4); } -int printf(const char *str, ...) { - va_list args; - va_start(args, str); - char temp_str[256] = ""; +int printf_logic(const char *str, va_list args) { int len = 0; - - size_t i; - for (i = 0; str[i] != '\0'; ++i) { + char temp_str[256] = ""; + for (int i = 0; str[i] != '\0'; ++i) { if (str[i] == '%') { switch (str[++i]) { case 'i': @@ -164,6 +160,13 @@ int printf(const char *str, ...) { } print_char(str[i]); } + return len; +} + +int printf(const char *str, ...) { + va_list args; + va_start(args, str); + int len = printf_logic(str, args); va_end(args); - return i; + return len; } diff --git a/src/kernel/tables/gdt.c b/src/kernel/tables/gdt.c index 9c65152..6cd05a8 100644 --- a/src/kernel/tables/gdt.c +++ b/src/kernel/tables/gdt.c @@ -7,8 +7,8 @@ void get_gdtr() { uint32_t base = (uint32_t)table; table[0] = make_descriptor(base, 0, 0); - table[1] = make_descriptor(base, 0x3FFFF, make_code(0, 0, 1)); - table[2] = make_descriptor(base, 0x3FFFF, make_data(0, 0, 1)); + table[1] = make_descriptor(base, 0xFFFFF, make_code(0, 0, 1)); + table[2] = make_descriptor(base, 0xFFFFF, make_data(0, 0, 1)); gdtr.size = sizeof(Segment_Descriptor_t) * 3 - 1; gdtr.offset = base; diff --git a/src/linker.ld b/src/linker.ld index 8a9d5f8..770b955 100644 --- a/src/linker.ld +++ b/src/linker.ld @@ -10,15 +10,16 @@ ENTRY (_start) */ SECTIONS { - /* Put sections at 1MiB, the conventional place for kernels to be + /* Put sections at 1MiB, the conventional place for kernels to be * loaded at by the bootloader. */ . = 1M; - /* First, put the multiboot header. It is required to be put - * VERY early in the image or the bootloader wont recognize the file + /* First, put the multiboot header. It is required to be put + * VERY early in the image or the bootloader wont recognize the file * format. Next, we will put the .text section*/ .text BLOCK(4K) : ALIGN(4K) { + text_start = .; *(.multiboot) *(.text) } @@ -31,14 +32,16 @@ SECTIONS .data BLOCK(4K) : ALIGN(4K) { *(.data) + end_data = .; } /* Read write data (uninitialized) and stack */ .bss BLOCK(4K) : ALIGN(4K) { + sbss = .; *(COMMON) *(.bss) + ebss = .; + endkernel = .; } - /* The compiler may produce other sections, but they will be put in - * a section with the same name by default. Add stuff here as needed */ } -- cgit v1.2.3