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.

This commit is contained in:
Xnoe 2021-10-23 01:34:54 +01:00
parent 2a68860bef
commit 9c887a3a50
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
11 changed files with 283 additions and 21 deletions

View File

@ -5,7 +5,7 @@ LDFLAGS =
DISK_IMG_FILES = build/kernel/kernel.bin 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 \ 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/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 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 run: disk.img
@ -26,6 +26,7 @@ prepare:
mkdir -p build/boot mkdir -p build/boot
mkdir -p build/boot_stage2 mkdir -p build/boot_stage2
mkdir -p build/kernel mkdir -p build/kernel
mkdir -p build/kernel/datatypes
mountpoint img.d | grep not || umount img.d mountpoint img.d | grep not || umount img.d
clean: clean:

View File

@ -108,6 +108,7 @@ void main() {
// Page Directory // Page Directory
PDE* kernel_page_directory = bitmap + 0x20000; PDE* kernel_page_directory = bitmap + 0x20000;
// Clear the PD // Clear the PD
memset((uint8_t*)kernel_page_directory, 4096, 0); memset((uint8_t*)kernel_page_directory, 4096, 0);
@ -121,6 +122,23 @@ void main() {
PTE** kernel_page_tables = 0x521000; 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 unavailable bitmap to 0x522000
mark_unavailble(bitmap, 0x4000000); mark_unavailble(bitmap, 0x4000000);

View File

@ -68,4 +68,16 @@ void* dumb_alloc(uint32_t size) {
} }
return (void*)ptr; return (void*)ptr;
}
xnoe::tuple<uint32_t, void*> 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<uint32_t, void*>(phys_addr, (void*)ptr);
} }

View File

@ -2,6 +2,7 @@
#define ALLOCATE_H #define ALLOCATE_H
#include "paging.h" #include "paging.h"
#include "datatypes/tuple.h"
//void init_allocator(); //void init_allocator();
extern uint8_t* bitmap; extern uint8_t* bitmap;
@ -16,4 +17,6 @@ void mark_unavailble(uint32_t address, uint32_t size);
void* dumb_alloc(uint32_t size); void* dumb_alloc(uint32_t size);
xnoe::tuple<uint32_t, void*> alloc_page_with_phys();
#endif #endif

View File

@ -0,0 +1,45 @@
#ifndef TUPLE_H
#define TUPLE_H
#include "../types.h"
namespace xnoe {
template<int index, typename T>
class tupleGetHelper;
template<typename ... T>
class tuple {};
template<typename T, typename ... Tail>
class tuple<T, Tail ...> {
public:
T head;
tuple<Tail...> tail;
tuple(const T& head, const Tail& ... tail)
: head(head), tail(tail...) {}
template<int index>
auto get() {
return tupleGetHelper<index, tuple<T, Tail...>>::get(*this);
}
};
template<typename T, typename ... Tail>
class tupleGetHelper<0, tuple<T, Tail...>> {
public:
static T get(tuple<T, Tail...>& t) {
return t.head;
}
};
template<int index, typename T, typename ... Tail>
class tupleGetHelper<index, tuple<T, Tail...>> {
public:
static auto get(tuple<T, Tail...>& t) {
return tupleGetHelper<index - 1, tuple<Tail ...>>::get(t.tail);
}
};
}
#endif

View File

@ -8,9 +8,16 @@
#include "gdt.h" #include "gdt.h"
#include "paging.h" #include "paging.h"
#include "allocate.h" #include "allocate.h"
#include "memory.h"
int main() { int main() {
init_gdt(); init_gdt();
PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000);
kernel_pd.select();
kernel_pd.map(0x0, 0x400000);
//kernel_pd.unmap(0x8000);
init_idt(); init_idt();
init_term(); init_term();
@ -18,8 +25,6 @@ int main() {
printf("KERNEL OK!\n"); printf("KERNEL OK!\n");
unmap_4k_virt(0x8000, kernel_page_directory, kernel_page_tables);
init_keyboard(); init_keyboard();
enable_idt(); enable_idt();

View File

@ -10,5 +10,6 @@ SECTIONS {
build/kernel/entry.o(.text) build/kernel/entry.o(.text)
build/kernel/kernel.o(.text) build/kernel/kernel.o(.text)
build/kernel/*(.text) build/kernel/*(.text)
build/kernel/datatypes/*(.text)
} }
} }

91
src/kernel/memory.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "memory.h"
void memset(uint8_t* address, uint32_t count, uint8_t value) {
for (int i=0; i<count; i++)
address[i] = value;
}
void memcpy(uint8_t* src, uint8_t* dst, uint32_t count) {
for (int i = 0; i<count; i++)
dst[i] = src[i];
}
PageTable::PageTable(uint32_t phys, uint32_t virt) {
phys_addr = phys;
virt_addr = virt;
page_table = (PTE*)virt;
}
PageTable::PageTable(){}
void PageTable::map_table(uint32_t index, uint32_t addr) {
page_table[index] = (PTE){
.present = 1,
.read_write = 1,
.privilege = 0,
.write_through_cache = 0,
.disable_cache = 0,
.accessed = 0,
.dirty = 0,
.ignored = 0,
.global = 0,
.available = 0,
.address = addr
};
}
void PageTable::unmap_table(uint32_t index) {
page_table[index] = (PTE){
.present = 0,
.read_write = 0,
.privilege = 0,
.write_through_cache = 0,
.disable_cache = 0,
.accessed = 0,
.dirty = 0,
.ignored = 0,
.global = 0,
.available = 0,
.address = 0
};
}
PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t offset) {
this->page_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));
}

80
src/kernel/memory.h Normal file
View File

@ -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

View File

@ -1,11 +1,5 @@
#include "paging.h" #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) { void map_4k_phys_to_virt(uint32_t physical, uint32_t virt, PDE* page_directory, PTE** page_tables) {
split_addr* split = (split_addr*)&virt; 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, .available = 0,
.address = 0 .address = 0
}; };
}
uint32_t PDE::getPhysicalPTAddress() {
return this->address << 12;
} }

View File

@ -4,18 +4,10 @@
#include <stdbool.h> #include <stdbool.h>
#include "types.h" #include "types.h"
struct __attribute__((packed)) PDE { struct __attribute__((packed)) split_addr {
uint32_t present : 1; uint32_t page_offset : 12;
uint32_t read_write : 1; uint32_t pt_index : 10;
uint32_t privilege : 1; uint32_t pd_index : 10;
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)) PTE { struct __attribute__((packed)) PTE {
@ -32,6 +24,22 @@ struct __attribute__((packed)) PTE {
uint32_t address : 20; 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_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); void map_many_4k_phys_to_virt(uint32_t physical, uint32_t virt, PDE* page_directory, PTE** page_tables, uint32_t count);