Initial work on dynamically creating Processes in preparation for implementing context switching

This commit is contained in:
Xnoe 2021-11-12 00:30:10 +00:00
parent 01fef9d947
commit bfa3f3030f
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
10 changed files with 96 additions and 22 deletions

View File

@ -6,7 +6,7 @@ DISK_IMG_FILES = build/kernel/kernel.bin hello.txt alpha.txt
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/kmain.o build/kernel/paging.o build/kernel/allocate.o \ build/kernel/strings.o build/kernel/atapio.o build/kernel/kmain.o build/kernel/paging.o build/kernel/allocate.o \
build/kernel/gdt.o build/kernel/memory.o build/kernel/process.o build/kernel/datatypes/hash.o \ build/kernel/gdt.o build/kernel/memory.o build/kernel/process.o build/kernel/datatypes/hash.o \
build/kernel/terminal.o build/kernel/global.o build/kernel/terminal.o build/kernel/global.o build/kernel/kernel.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

View File

@ -1,4 +1,5 @@
#include "global.h" #include "memory.h"
namespace Global { namespace Global {
Allocator* allocator = 0; Allocator* allocator = 0;
} }

View File

@ -1,7 +1,7 @@
#ifndef GLOBAL_H #ifndef GLOBAL_H
#define GLOBAL_H #define GLOBAL_H
#include "memory.h" class Allocator;
namespace Global { namespace Global {
extern Allocator* allocator; extern Allocator* allocator;

9
src/kernel/kernel.cpp Normal file
View File

@ -0,0 +1,9 @@
#include "kernel.h"
Kernel* Kernel::kernel;
Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base)
: Process(0, 0x8a000, page_directory, phys, virt, virt_alloc_base)
{
this->kernel = this;
}

15
src/kernel/kernel.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef KERNEL_H
#define KERNEL_H
#include "process.h"
class Kernel : public Process {
private:
static Kernel* kernel;
public:
Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
};
#endif

View File

@ -13,19 +13,21 @@
#include "global.h" #include "global.h"
#include "datatypes/hashtable.h" #include "datatypes/hashtable.h"
#include "terminal.h" #include "terminal.h"
#include "kernel.h"
int main() { int main() {
init_gdt(); init_gdt();
init_term(); init_term();
PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000); PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000);
kernel_pd.select(); kernel_pd.select();
kernel_pd.unmap(0x8000); kernel_pd.unmap(0x8000);
PageMap phys_pm(0xc0600000); PageMap phys_pm(0xc0600000);
PageMap virt_pm(0xc0620000); PageMap virt_pm(0xc0620000);
Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xd0000000); Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000);
Global::allocator = &kernel; Global::allocator = &kernel;
Terminal* current_term; Terminal* current_term;
@ -33,14 +35,22 @@ int main() {
TextModeTerminal* term = new TextModeTerminal(0xc0501000); TextModeTerminal* term = new TextModeTerminal(0xc0501000);
current_term = term; current_term = term;
TextModeTerminal* term2 = new TextModeTerminal(0xc0501000);
term2->printf("Balls");
init_idt(); init_idt();
term->activate();
term->clear_screen(); term->clear_screen();
term->printf("Hello, World!\n\nWe are running XnoeOS Code in C++ now, Protected Mode has been achieved (as well as Virtual Memory / Paging!!!) and everything is working super nicely!\n\nHow wonderful!\n\nNow I just need to hope my print function works properly too~~\n"); term->printf("Hello, World!\n\nWe are running XnoeOS Code in C++ now, Protected Mode has been achieved (as well as Virtual Memory / Paging!!!) and everything is working super nicely!\n\nHow wonderful!\n\nNow I just need to hope my print function works properly too~~\n");
term->printf("KERNEL OK!\n"); term->printf("KERNEL OK!\n");
term->activate();
Process* process = new Process(1);
term->deactivate();
term2->activate();
while (1); while (1);

View File

@ -1,5 +1,4 @@
#include "memory.h" #include "memory.h"
#include "screenstuff.h"
void memset(uint8_t* address, uint32_t count, uint8_t value) { void memset(uint8_t* address, uint32_t count, uint8_t value) {
for (int i=0; i<count; i++) for (int i=0; i<count; i++)
@ -15,6 +14,11 @@ PageMap::PageMap(uint32_t map) {
this->pagemap = (uint8_t*)map; this->pagemap = (uint8_t*)map;
} }
PageMap::PageMap() {
this->pagemap = new uint8_t[131072];
memset(this->pagemap, 131072, 0xff);
}
void PageMap::set_bit(uint32_t index) { void PageMap::set_bit(uint32_t index) {
uint32_t offset = index % 8; uint32_t offset = index % 8;
uint32_t i = index / 8; uint32_t i = index / 8;
@ -83,7 +87,12 @@ PageTable::PageTable(uint32_t phys, uint32_t virt) {
page_table = (PTE*)virt; page_table = (PTE*)virt;
} }
PageTable::PageTable(){} PageTable::PageTable(){
virt_addr = new PTE[1024];
phys_addr = Global::allocator->virtual_to_physical(virt_addr);
page_table = (PTE*)virt_addr;
}
void PageTable::map_table(uint32_t index, uint32_t addr) { void PageTable::map_table(uint32_t index, uint32_t addr) {
page_table[index] = (PTE){ page_table[index] = (PTE){
@ -122,6 +131,7 @@ uint32_t PageTable::get_physical_address(uint32_t index) {
} }
PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t offset) { PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t offset) {
this->page_tables = (PageTable*)this->__page_tables;
this->page_directory = page_directory; this->page_directory = page_directory;
this->phys_addr = phys_addr; this->phys_addr = phys_addr;
@ -131,9 +141,19 @@ PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t o
} }
} }
PageDirectory::PageDirectory() {
this->page_tables = (PageTable*)this->__page_tables;
this->page_directory = new PDE[1024];
memset((uint8_t*)this->page_tables, sizeof(PageTable) * 1024, 0);
this->phys_addr = Global::allocator->virtual_to_physical(this->page_directory);
}
void PageDirectory::map(uint32_t phys, uint32_t virt) { void PageDirectory::map(uint32_t phys, uint32_t virt) {
split_addr* split = (split_addr*)&virt; split_addr* split = (split_addr*)&virt;
if (!page_tables[split->pd_index].virt_addr)
page_tables[split->pd_index] = PageTable();
page_directory[split->pd_index] = (PDE){ page_directory[split->pd_index] = (PDE){
.present = 1, .present = 1,
.read_write = 1, .read_write = 1,
@ -177,7 +197,15 @@ Allocator::Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt
this->virt_alloc_base = virt_alloc_base; this->virt_alloc_base = virt_alloc_base;
} }
Allocator::Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base) {
this->PD = page_directory;
this->virt = virt;
this->virt_alloc_base = virt_alloc_base;
}
void* Allocator::allocate(uint32_t size) { void* Allocator::allocate(uint32_t size) {
asm("mov $0x0, 0x8a000");
uint32_t count = (size + (4096 - size % 4096)) / 4096; uint32_t count = (size + (4096 - size % 4096)) / 4096;
uint32_t virt_addr = virt->find_next_available_from(this->virt_alloc_base, count); uint32_t virt_addr = virt->find_next_available_from(this->virt_alloc_base, count);
@ -186,6 +214,7 @@ void* Allocator::allocate(uint32_t size) {
for (int i=0; i<count; i++) { for (int i=0; i<count; i++) {
uint32_t phys_addr = this->phys->find_next_available_from(0); uint32_t phys_addr = this->phys->find_next_available_from(0);
this->phys->mark_unavailable(phys_addr); this->phys->mark_unavailable(phys_addr);
asm("mov $0xdead, 0x8a000");
this->PD->map(phys_addr, virt_addr + 4096 * i); this->PD->map(phys_addr, virt_addr + 4096 * i);
} }
@ -199,4 +228,8 @@ void Allocator::deallocate(uint32_t virt_addr) {
phys->mark_available(phys_addr); phys->mark_available(phys_addr);
virt->mark_available(virt_addr); virt->mark_available(virt_addr);
}
uint32_t Allocator::virtual_to_physical(uint32_t virt) {
return PD->virtual_to_physical(virt);
} }

View File

@ -1,10 +1,10 @@
#ifndef MEMORY_H #ifndef MEMORY_H
#define MEMORY_H #define MEMORY_H
#include "datatypes/tuple.h"
#include "paging.h" #include "paging.h"
#include "allocate.h" #include "allocate.h"
#include "screenstuff.h" #include "screenstuff.h"
#include "global.h"
void memset(uint8_t* address, uint32_t count, uint8_t value); void memset(uint8_t* address, uint32_t count, uint8_t value);
void memcpy(uint8_t* src, uint8_t* dst, uint32_t count); void memcpy(uint8_t* src, uint8_t* dst, uint32_t count);
@ -20,6 +20,7 @@ private:
public: public:
PageMap(uint32_t map); PageMap(uint32_t map);
PageMap();
void mark_unavailable(uint32_t address); void mark_unavailable(uint32_t address);
void mark_unavailable(uint32_t address, uint32_t count); void mark_unavailable(uint32_t address, uint32_t count);
@ -51,12 +52,14 @@ struct PageTable {
class PageDirectory { class PageDirectory {
private: private:
PDE* page_directory; PDE* page_directory;
PageTable page_tables[1024]; uint8_t __page_tables[sizeof(PageTable) * 1024];
PageTable* page_tables;
uint32_t phys_addr; uint32_t phys_addr;
public: public:
PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset); PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset);
PageDirectory();
void map(uint32_t phys, uint32_t virt); void map(uint32_t phys, uint32_t virt);
void unmap(uint32_t virt); void unmap(uint32_t virt);
@ -76,8 +79,11 @@ protected:
uint32_t virt_alloc_base; uint32_t virt_alloc_base;
public: public:
Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base);
virtual void* allocate(uint32_t size); virtual void* allocate(uint32_t size);
virtual void deallocate(uint32_t virt_addr); virtual void deallocate(uint32_t virt_addr);
uint32_t virtual_to_physical(uint32_t virt);
}; };
#endif #endif

View File

@ -14,11 +14,20 @@ xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> Process::get_alloc_tracker(uint
return xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*>(); return xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*>();
} }
Process::Process(uint32_t PID, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base) Process::Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base)
: Allocator(page_directory, phys, virt, virt_alloc_base) { : Allocator(page_directory, phys, virt, virt_alloc_base) {
this->PID = PID; this->PID = PID;
this->page_remaining = 0; this->page_remaining = 0;
this->last_page_pointer = virt_alloc_base; this->last_page_pointer = virt_alloc_base;
this->stack = stack;
}
Process::Process(uint32_t PID)
: Allocator(new PageDirectory, new PageMap, 0) {
this->PID = PID;
this->page_remaining = 0;
this->last_page_pointer = virt_alloc_base;
this->stack = new uint8_t[0x8000];
} }
void* Process::allocate(uint32_t size) { void* Process::allocate(uint32_t size) {
@ -83,6 +92,3 @@ uint32_t Process::count_allocations(uint32_t address) {
return 0; return 0;
} }
Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base)
: Process(0, page_directory, phys, virt, virt_alloc_base)
{}

View File

@ -32,7 +32,8 @@ private:
xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> get_alloc_tracker(uint32_t address); xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> get_alloc_tracker(uint32_t address);
public: public:
Process(uint32_t PID, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
Process(uint32_t PID);
void* allocate(uint32_t size) override; void* allocate(uint32_t size) override;
void deallocate(uint32_t virt_addr) override; void deallocate(uint32_t virt_addr) override;
@ -40,11 +41,4 @@ public:
uint32_t count_allocations(uint32_t address); uint32_t count_allocations(uint32_t address);
}; };
class Kernel : public Process {
public:
static Allocator* global_allocator;
Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
};
#endif #endif