From a9ec673b24decf81f97ea413e2601c697448aa12 Mon Sep 17 00:00:00 2001 From: Xnoe Date: Wed, 1 Dec 2021 17:05:46 +0000 Subject: [PATCH] Implemented necessary changes for Process destruction. Processes clean up their memory when deleted. --- src/kernel/datatypes/linkedlist.h | 24 ++++++++++++++++++++++++ src/kernel/global.cpp | 4 ++++ src/kernel/global.h | 1 + src/kernel/idt.cpp | 17 ++++++----------- src/kernel/kernel.cpp | 7 +++++++ src/kernel/kernel.h | 1 + src/kernel/kmain.cpp | 3 ++- src/kernel/memory.cpp | 24 ++++++++++++++++++++++-- src/kernel/memory.h | 9 +++++++++ src/kernel/process.cpp | 15 ++++++++++++++- src/kernel/process.h | 2 ++ 11 files changed, 92 insertions(+), 15 deletions(-) diff --git a/src/kernel/datatypes/linkedlist.h b/src/kernel/datatypes/linkedlist.h index 6710a62..d72686e 100644 --- a/src/kernel/datatypes/linkedlist.h +++ b/src/kernel/datatypes/linkedlist.h @@ -95,6 +95,30 @@ namespace xnoe { current = current->next; } } + + void remove(T elem) { + linkedlistelem* current = start; + while (current) { + if (current->elem == elem) { + if (current->prev) + current->prev->next = current->next; + + if (current->next) + current->next->prev = current->prev; + + if (current == start) + start = current->next; + + if (current == end) + end = current->prev; + + delete current; + + return; + } + current = current->next; + } + } }; } diff --git a/src/kernel/global.cpp b/src/kernel/global.cpp index 4570113..5679b50 100644 --- a/src/kernel/global.cpp +++ b/src/kernel/global.cpp @@ -10,6 +10,10 @@ void* operator new (uint32_t size) { return Global::allocator->allocate(size); } +void* operator new (uint32_t size, void* ptr) { + return ptr; +} + void operator delete (void* ptr) { Global::allocator->deallocate((uint32_t)ptr); } diff --git a/src/kernel/global.h b/src/kernel/global.h index e6ed2f4..2a2f9c7 100644 --- a/src/kernel/global.h +++ b/src/kernel/global.h @@ -14,6 +14,7 @@ namespace Global { } void* operator new (uint32_t size); +void* operator new (uint32_t size, void* ptr); void operator delete (void* ptr); void operator delete (void* ptr, unsigned int size); diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index 44f5940..553fc1a 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -38,6 +38,7 @@ __attribute__((interrupt)) void gpf(interrupt_frame* frame, uint32_t err_code) { __attribute__((interrupt)) void context_switch(interrupt_frame* frame) { asm ("cli"); // Disable interrupts whilst handling the context switch. asm ("pusha"); // Push registers to the stack + //asm ("pushf"); // Push flags to the stack Process* currentProc = Global::currentProc; Process* nextProc = 0; @@ -90,20 +91,14 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) { asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr)); // Restore ESP of the new process. asm volatile ("mov %0, %%esp" : : "m" (Global::kernel->processes.start->elem->esp)); - // Restore registers - asm ("popa"); - // Restore the initial eax - asm ("mov -0xc(%ebp), %eax"); - + //asm ("popf"); // Pop flags + asm ("popa"); // Restore registers + asm ("mov -0xc(%ebp), %eax"); // Restore the initial eax // Clear the garbage that was on the stack from previous switch_context call. asm ("mov %ebp, %esp"); - - // Pop EBP - asm ("pop %ebp"); - - // Manually perform iret. - asm ("iret"); + asm ("pop %ebp"); // Pop EBP + asm ("iret"); // Manually perform iret. } } diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 14b8fac..698d880 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -24,4 +24,11 @@ Process* Kernel::createProcess(char* filename) { this->processes.append(p); return p; +} + +void Kernel::destroyProcess(Process* p) { + this->processes.remove(p); + this->pid_map->remove(p->PID, p); + delete p; + while (1); } \ No newline at end of file diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 94cf40e..68eff3c 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -20,6 +20,7 @@ public: void init_kernel(); Process* createProcess(char* filename); + void destroyProcess(Process* p); }; #endif \ No newline at end of file diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index 569169e..afe1354 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -47,7 +47,8 @@ int main() { Global::currentProc = &kernel; Process* p1 = kernel.createProcess("WORLD BIN"); - //Process* p2 = kernel.createProcess("HELLO BIN"); + Process* p2 = kernel.createProcess("HELLO BIN"); + kernel.destroyProcess(p2); init_keyboard(); diff --git a/src/kernel/memory.cpp b/src/kernel/memory.cpp index a576aa1..77dc9b1 100644 --- a/src/kernel/memory.cpp +++ b/src/kernel/memory.cpp @@ -19,6 +19,10 @@ PageMap::PageMap() { memset(this->pagemap, 131072, 0xff); } +PageMap::~PageMap() { + delete pagemap; +} + void PageMap::set_bit(uint32_t index) { uint32_t offset = index % 8; uint32_t i = index / 8; @@ -96,6 +100,10 @@ PageTable::PageTable(){ page_table = (PTE*)virt_addr; } +PageTable::~PageTable() { + delete page_table; +} + void PageTable::map_table(uint32_t index, uint32_t addr) { page_table[index] = (PTE){ .present = 1, @@ -139,7 +147,7 @@ PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t o 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); + new (page_tables + i) PageTable(table_phys_addr >> 12, table_phys_addr + offset); } } @@ -153,11 +161,18 @@ PageDirectory::PageDirectory() { this->phys_addr = Global::allocator->virtual_to_physical(this->page_directory); } +PageDirectory::~PageDirectory() { + for (int i=0; i<1024; i++) + if (page_tables[i].virt_addr) + page_tables[i].~PageTable(); + delete page_directory; +} + void PageDirectory::map(uint32_t phys, uint32_t virt) { split_addr* split = (split_addr*)&virt; if (!page_tables[split->pd_index].virt_addr) - page_tables[split->pd_index] = PageTable(); + new (page_tables + split->pd_index) PageTable(); page_directory[split->pd_index] = (PDE){ .present = 1, @@ -209,6 +224,11 @@ Allocator::Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt this->virt_alloc_base = virt_alloc_base; } +Allocator::~Allocator() { + delete virt; + delete PD; +} + void* Allocator::allocate(uint32_t size) { uint32_t count = (size + (4096 - size % 4096)) / 4096; diff --git a/src/kernel/memory.h b/src/kernel/memory.h index a57708c..b92cbee 100644 --- a/src/kernel/memory.h +++ b/src/kernel/memory.h @@ -22,6 +22,8 @@ public: PageMap(uint32_t map); PageMap(); + ~PageMap(); + void mark_unavailable(uint32_t address); void mark_unavailable(uint32_t address, uint32_t count); @@ -43,6 +45,8 @@ struct PageTable { PageTable(uint32_t phys, uint32_t virt); PageTable(); + ~PageTable(); // Delete page_table + void map_table(uint32_t index, uint32_t addr); void unmap_table(uint32_t index); @@ -62,6 +66,8 @@ public: PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset); PageDirectory(); + ~PageDirectory(); // Delete the page tables and page_directory + void map(uint32_t phys, uint32_t virt); void unmap(uint32_t virt); @@ -81,6 +87,9 @@ public: Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base); + + ~Allocator(); // Delete virt and PD + virtual void* allocate(uint32_t size); virtual void deallocate(uint32_t virt_addr); diff --git a/src/kernel/process.cpp b/src/kernel/process.cpp index d428013..04d7e3a 100644 --- a/src/kernel/process.cpp +++ b/src/kernel/process.cpp @@ -5,7 +5,7 @@ AllocTracker::AllocTracker(void* base, uint32_t size, uint32_t count) : page_bas xnoe::Maybe*> Process::get_alloc_tracker(uint32_t address) { xnoe::linkedlistelem* current = this->allocations.start; while (current) { - if (current->elem.page_base < address && (current->elem.page_base + 4096 * current->elem.page_size) > address) { + if (current->elem.page_base <= address && (current->elem.page_base + 4096 * current->elem.page_size) > address) { return xnoe::Maybe*>(current); } current = current->next; @@ -87,6 +87,19 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha asm ("mov %0, %%cr3" : : "r" (pCR3)); } +Process::~Process() { + xnoe::linkedlistelem* next = allocations.start; + while (next) { + xnoe::linkedlistelem* active = next; + next = next->next; + + printf("Deleted %x\n", active->elem.page_base); + + this->deallocate(active->elem.page_base+1); + } + this->deallocate(stack); +} + void* Process::allocate(uint32_t size) { bool switched_PD = false; uint32_t pCR3; diff --git a/src/kernel/process.h b/src/kernel/process.h index c2fd0ee..bbd2165 100644 --- a/src/kernel/process.h +++ b/src/kernel/process.h @@ -38,6 +38,8 @@ public: Process(uint32_t PID); Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename); + ~Process(); // Iterate through allocations and free those; delete stack + void* allocate(uint32_t size) override; void deallocate(uint32_t virt_addr) override;