From 9c887a3a50111d0b8875949e28cd6ae2d32176ad Mon Sep 17 00:00:00 2001 From: Xnoe Date: Sat, 23 Oct 2021 01:34:54 +0100 Subject: [PATCH] Began the process of moving XnoeOS to using more OOP constructs. Added PageDirectory class. Added PageTable class. Added tuple data type. Added beginnings of the skeleton for Allocator and Process. --- Makefile | 3 +- src/boot_stage2/main.c | 18 +++++++ src/kernel/allocate.cpp | 12 +++++ src/kernel/allocate.h | 3 ++ src/kernel/datatypes/tuple.h | 45 ++++++++++++++++++ src/kernel/kernel.cpp | 9 +++- src/kernel/kernel.ld | 1 + src/kernel/memory.cpp | 91 ++++++++++++++++++++++++++++++++++++ src/kernel/memory.h | 80 +++++++++++++++++++++++++++++++ src/kernel/paging.cpp | 10 ++-- src/kernel/paging.h | 32 ++++++++----- 11 files changed, 283 insertions(+), 21 deletions(-) create mode 100644 src/kernel/datatypes/tuple.h create mode 100644 src/kernel/memory.cpp create mode 100644 src/kernel/memory.h diff --git a/Makefile b/Makefile index 21e9be7..1a786cb 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ LDFLAGS = DISK_IMG_FILES = build/kernel/kernel.bin KERNEL_OBJS = build/kernel/entry.o build/kernel/screenstuff.o build/kernel/io.o build/kernel/idt.o build/kernel/keyboard.o \ build/kernel/strings.o build/kernel/atapio.o build/kernel/kernel.o build/kernel/paging.o build/kernel/allocate.o \ - build/kernel/gdt.o + build/kernel/gdt.o build/kernel/memory.o STAGE2_OBS = build/c_code_entry.o build/boot_stage2/io.o build/boot_stage2/atapio.o build/boot_stage2/strings.o build/boot_stage2/screenstuff.o build/boot_stage2/stage2.o build/boot_stage2/paging.o run: disk.img @@ -26,6 +26,7 @@ prepare: mkdir -p build/boot mkdir -p build/boot_stage2 mkdir -p build/kernel + mkdir -p build/kernel/datatypes mountpoint img.d | grep not || umount img.d clean: diff --git a/src/boot_stage2/main.c b/src/boot_stage2/main.c index e8de959..3181807 100644 --- a/src/boot_stage2/main.c +++ b/src/boot_stage2/main.c @@ -108,6 +108,7 @@ void main() { // Page Directory PDE* kernel_page_directory = bitmap + 0x20000; + // Clear the PD memset((uint8_t*)kernel_page_directory, 4096, 0); @@ -121,6 +122,23 @@ void main() { PTE** kernel_page_tables = 0x521000; + for (int i = 0; i < 1023; i++) { + kernel_page_directory[i] = (PDE){ + .address = (uint32_t)(kernel_page_tables[i]) >> 12, + .available = 0, + .page_4mb = 0, + .accessed = 0, + .disable_cache = 0, + .write_through_cache = 0, + .privilege = 0, + .present = 1, + .read_write = 1, + + .ignored = 0, + .ignored2 = 0 + }; + } + // Mark unavailable bitmap to 0x522000 mark_unavailble(bitmap, 0x4000000); diff --git a/src/kernel/allocate.cpp b/src/kernel/allocate.cpp index 37eda1c..da65390 100644 --- a/src/kernel/allocate.cpp +++ b/src/kernel/allocate.cpp @@ -68,4 +68,16 @@ void* dumb_alloc(uint32_t size) { } return (void*)ptr; +} + +xnoe::tuple alloc_page_with_phys() { + uint32_t ptr = kernel_allocate_area; + + for (; get_bit(last_free_page, bitmap) == 0; last_free_page++); + uint32_t phys_addr = last_free_page * 4096; + mark_unavailble(phys_addr, 4096); + map_4k_phys_to_virt(phys_addr, kernel_allocate_area, kernel_page_directory, kernel_page_tables); + kernel_allocate_area += 4096; + + return xnoe::tuple(phys_addr, (void*)ptr); } \ No newline at end of file diff --git a/src/kernel/allocate.h b/src/kernel/allocate.h index 1c293aa..3e7d36e 100644 --- a/src/kernel/allocate.h +++ b/src/kernel/allocate.h @@ -2,6 +2,7 @@ #define ALLOCATE_H #include "paging.h" +#include "datatypes/tuple.h" //void init_allocator(); extern uint8_t* bitmap; @@ -16,4 +17,6 @@ void mark_unavailble(uint32_t address, uint32_t size); void* dumb_alloc(uint32_t size); +xnoe::tuple alloc_page_with_phys(); + #endif \ No newline at end of file diff --git a/src/kernel/datatypes/tuple.h b/src/kernel/datatypes/tuple.h new file mode 100644 index 0000000..e12495b --- /dev/null +++ b/src/kernel/datatypes/tuple.h @@ -0,0 +1,45 @@ +#ifndef TUPLE_H +#define TUPLE_H + +#include "../types.h" + +namespace xnoe { + template + class tupleGetHelper; + + template + class tuple {}; + + template + class tuple { + public: + T head; + tuple tail; + + tuple(const T& head, const Tail& ... tail) + : head(head), tail(tail...) {} + + template + auto get() { + return tupleGetHelper>::get(*this); + } + }; + + template + class tupleGetHelper<0, tuple> { + public: + static T get(tuple& t) { + return t.head; + } + }; + + template + class tupleGetHelper> { + public: + static auto get(tuple& t) { + return tupleGetHelper>::get(t.tail); + } + }; +} + +#endif \ No newline at end of file diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 46483e7..63b945a 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -8,9 +8,16 @@ #include "gdt.h" #include "paging.h" #include "allocate.h" +#include "memory.h" int main() { init_gdt(); + + PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000); + kernel_pd.select(); + kernel_pd.map(0x0, 0x400000); + //kernel_pd.unmap(0x8000); + init_idt(); init_term(); @@ -18,8 +25,6 @@ int main() { printf("KERNEL OK!\n"); - unmap_4k_virt(0x8000, kernel_page_directory, kernel_page_tables); - init_keyboard(); enable_idt(); diff --git a/src/kernel/kernel.ld b/src/kernel/kernel.ld index 2a37cd5..7d03cbe 100644 --- a/src/kernel/kernel.ld +++ b/src/kernel/kernel.ld @@ -10,5 +10,6 @@ SECTIONS { build/kernel/entry.o(.text) build/kernel/kernel.o(.text) build/kernel/*(.text) + build/kernel/datatypes/*(.text) } } \ No newline at end of file diff --git a/src/kernel/memory.cpp b/src/kernel/memory.cpp new file mode 100644 index 0000000..9fc62c8 --- /dev/null +++ b/src/kernel/memory.cpp @@ -0,0 +1,91 @@ +#include "memory.h" + +void memset(uint8_t* address, uint32_t count, uint8_t value) { + for (int i=0; ipage_directory = page_directory; + this->phys_addr = phys_addr; + + for (int i=0; i<1024; i++) { + uint32_t table_phys_addr = page_directory[i].getPhysicalPTAddress(); + page_tables[i] = PageTable(table_phys_addr >> 12, table_phys_addr + offset); + } +} + +void PageDirectory::map(uint32_t phys, uint32_t virt) { + split_addr* split = (split_addr*)&virt; + + page_directory[split->pd_index] = (PDE){ + .present = 1, + .read_write = 1, + .privilege = 0, + .write_through_cache = 0, + .disable_cache = 0, + .accessed = 0, + .ignored2 = 0, + .page_4mb = 0, + .ignored = 0, + .available = 0, + .address = page_tables[split->pd_index].phys_addr + }; + + page_tables[split->pd_index].map_table(split->pt_index, phys >> 12); +} + +void PageDirectory::unmap(uint32_t virt) { + split_addr* split = (split_addr*)&virt; + page_tables[split->pd_index].unmap_table(split->pt_index); +} + +void PageDirectory::select() { + asm volatile("mov %0, %%eax; mov %%eax, %%cr3" : : "m" (phys_addr)); +} \ No newline at end of file diff --git a/src/kernel/memory.h b/src/kernel/memory.h new file mode 100644 index 0000000..b81c7e1 --- /dev/null +++ b/src/kernel/memory.h @@ -0,0 +1,80 @@ +#ifndef MEMORY_H +#define MEMORY_H + +#include "datatypes/tuple.h" +#include "paging.h" +#include "allocate.h" +#include "screenstuff.h" + +void memset(uint8_t* address, uint32_t count, uint8_t value); +void memcpy(uint8_t* src, uint8_t* dst, uint32_t count); + +class __attribute__((packed)) PageMap { +private: + uint8_t pagemap[1024^2 / 8]; + + void set_bit(uint32_t index); + void unset_bit(uint32_t index); + +public: + PageMap(uint8_t* map); + + void mark_unavailble(uint32_t page); + void mark_available(uint32_t page); +}; + +struct PageTable { + PTE* page_table; + + uint32_t phys_addr; + uint32_t virt_addr; + + PageTable(uint32_t phys, uint32_t virt); + PageTable(); + + void map_table(uint32_t index, uint32_t addr); + void unmap_table(uint32_t index); +}; + +class PageDirectory { +private: + PDE* page_directory; + PageTable page_tables[1024]; + + uint32_t phys_addr; + +public: + PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset); + + void map(uint32_t phys, uint32_t virt); + + void unmap(uint32_t virt); + + void select(); +}; + +class Allocator { +protected: + static PageMap phys; + PageMap virt; + + PageDirectory PD; + + uint32_t current_page_index; + uint32_t remaining; +public: + Allocator(); + Allocator(PageDirectory page_directory, PageMap phys, PageMap virt); + void* allocate(); + void deallocate(); +}; + +class Process : protected Allocator { +private: + uint32_t PID; + +public: + Process(uint32_t PID); +}; + +#endif \ No newline at end of file diff --git a/src/kernel/paging.cpp b/src/kernel/paging.cpp index 37b9b73..8a30005 100644 --- a/src/kernel/paging.cpp +++ b/src/kernel/paging.cpp @@ -1,11 +1,5 @@ #include "paging.h" -struct __attribute__((packed)) split_addr { - uint32_t page_offset : 12; - uint32_t pt_index : 10; - uint32_t pd_index : 10; -}; - void map_4k_phys_to_virt(uint32_t physical, uint32_t virt, PDE* page_directory, PTE** page_tables) { split_addr* split = (split_addr*)&virt; @@ -59,4 +53,8 @@ void unmap_4k_virt(uint32_t virt, PDE* page_directory, PTE** page_tables) { .available = 0, .address = 0 }; +} + +uint32_t PDE::getPhysicalPTAddress() { + return this->address << 12; } \ No newline at end of file diff --git a/src/kernel/paging.h b/src/kernel/paging.h index cd1e47a..b3bed31 100644 --- a/src/kernel/paging.h +++ b/src/kernel/paging.h @@ -4,18 +4,10 @@ #include #include "types.h" -struct __attribute__((packed)) PDE { - uint32_t present : 1; - uint32_t read_write : 1; - uint32_t privilege : 1; - uint32_t write_through_cache : 1; - uint32_t disable_cache : 1; - uint32_t accessed : 1; - uint32_t ignored2 : 1; - uint32_t page_4mb : 1; - uint32_t ignored : 1; - uint32_t available : 3; - uint32_t address : 20; +struct __attribute__((packed)) split_addr { + uint32_t page_offset : 12; + uint32_t pt_index : 10; + uint32_t pd_index : 10; }; struct __attribute__((packed)) PTE { @@ -32,6 +24,22 @@ struct __attribute__((packed)) PTE { uint32_t address : 20; }; +struct __attribute__((packed)) PDE { + uint32_t present : 1; + uint32_t read_write : 1; + uint32_t privilege : 1; + uint32_t write_through_cache : 1; + uint32_t disable_cache : 1; + uint32_t accessed : 1; + uint32_t ignored2 : 1; + uint32_t page_4mb : 1; + uint32_t ignored : 1; + uint32_t available : 3; + uint32_t address : 20; + + uint32_t getPhysicalPTAddress(); +}; + void map_4k_phys_to_virt(uint32_t physical, uint32_t virt, PDE* page_directory, PTE** page_tables); void map_many_4k_phys_to_virt(uint32_t physical, uint32_t virt, PDE* page_directory, PTE** page_tables, uint32_t count);