Updated kernel to now have its stack past 0xc0000000. Implemented context switching.
This commit is contained in:
parent
2dd799b406
commit
ed67adc9c9
@ -167,7 +167,7 @@ void main() {
|
|||||||
mark_unavailble(0xc0502000, 0x1000, vm_bitmap);
|
mark_unavailble(0xc0502000, 0x1000, vm_bitmap);
|
||||||
mark_unavailble(0xc0600000, 0x20000, vm_bitmap);
|
mark_unavailble(0xc0600000, 0x20000, vm_bitmap);
|
||||||
mark_unavailble(0xc0620000, 0x20000, vm_bitmap);
|
mark_unavailble(0xc0620000, 0x20000, vm_bitmap);
|
||||||
mark_unavailble(0x8a000, 0x6000, vm_bitmap);
|
mark_unavailble(0xc1000000, 0x6000, vm_bitmap);
|
||||||
|
|
||||||
// Map the bitmap
|
// Map the bitmap
|
||||||
map_many_4k_phys_to_virt(0x100000, 0xc0600000, kernel_page_directory, kernel_page_tables, 32);
|
map_many_4k_phys_to_virt(0x100000, 0xc0600000, kernel_page_directory, kernel_page_tables, 32);
|
||||||
@ -175,7 +175,9 @@ void main() {
|
|||||||
map_many_4k_phys_to_virt(0x522000, 0xc0620000, kernel_page_directory, kernel_page_tables, 32);
|
map_many_4k_phys_to_virt(0x522000, 0xc0620000, kernel_page_directory, kernel_page_tables, 32);
|
||||||
|
|
||||||
map_4k_phys_to_virt(0x8000, 0x8000, kernel_page_directory, kernel_page_tables);
|
map_4k_phys_to_virt(0x8000, 0x8000, kernel_page_directory, kernel_page_tables);
|
||||||
|
// Map the stack
|
||||||
map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 6);
|
map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 6);
|
||||||
|
map_many_4k_phys_to_virt(0x8a000, 0xc1000000, kernel_page_directory, kernel_page_tables, 6);
|
||||||
|
|
||||||
load_file("KERNEL BIN", kernel_location);
|
load_file("KERNEL BIN", kernel_location);
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
[BITS 32]
|
[BITS 32]
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
|
mov esp, 0xc1005ffc
|
||||||
jmp main
|
jmp main
|
||||||
|
|
||||||
extern main
|
extern main
|
@ -3,6 +3,7 @@
|
|||||||
namespace Global {
|
namespace Global {
|
||||||
Allocator* allocator = 0;
|
Allocator* allocator = 0;
|
||||||
Kernel* kernel = 0;
|
Kernel* kernel = 0;
|
||||||
|
Process* currentProc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size) {
|
void* operator new (uint32_t size) {
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
class Kernel;
|
class Kernel;
|
||||||
class Allocator;
|
class Allocator;
|
||||||
|
class Process;
|
||||||
|
|
||||||
namespace Global {
|
namespace Global {
|
||||||
extern Allocator* allocator;
|
extern Allocator* allocator;
|
||||||
extern Kernel* kernel;
|
extern Kernel* kernel;
|
||||||
|
extern Process* currentProc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size);
|
void* operator new (uint32_t size);
|
||||||
|
@ -22,14 +22,89 @@ __attribute__((interrupt)) void interrupt_20(interrupt_frame* frame) {
|
|||||||
__attribute__((interrupt)) void page_fault(interrupt_frame* frame, uint32_t err_code) {
|
__attribute__((interrupt)) void page_fault(interrupt_frame* frame, uint32_t err_code) {
|
||||||
uint32_t problem_address;
|
uint32_t problem_address;
|
||||||
asm("mov %%cr2, %0" : "=a" (problem_address) :);
|
asm("mov %%cr2, %0" : "=a" (problem_address) :);
|
||||||
printf("Page Fault at %x\n", problem_address);
|
printf("(EIP %x): Page Fault at %x\n", frame->eip, problem_address);
|
||||||
asm("hlt");
|
while (1) asm("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void ignore_interrupt(interrupt_frame* frame) {
|
__attribute__((interrupt)) void ignore_interrupt(interrupt_frame* frame) {
|
||||||
outb(0x20, 0x20);
|
outb(0x20, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((interrupt)) void gpf(interrupt_frame* frame, uint32_t err_code) {
|
||||||
|
printf("General Protection Fault %d\n", err_code);
|
||||||
|
while (1) asm("hlt");
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
|
||||||
|
asm ("cli"); // Disable interrupts whilst handling the context switch.
|
||||||
|
asm ("pusha"); // Push registers to the stack
|
||||||
|
|
||||||
|
Process* currentProc = Global::currentProc;
|
||||||
|
Process* nextProc = 0;
|
||||||
|
if (currentProc) {
|
||||||
|
xnoe::linkedlist<Process*>* processes = &Global::kernel->processes;
|
||||||
|
|
||||||
|
// This cursed bit of code first determines if the processes list is longer than 1 and if it is
|
||||||
|
// - Determines if it has 2 or more elements
|
||||||
|
// - If it has two, swap the first and last, update prev and next of each to be null or the other item
|
||||||
|
// - If it has more than two, swap the first and last, then swap their next and prevs, and set the
|
||||||
|
// other value to null
|
||||||
|
if (processes->start->next != 0) {
|
||||||
|
if (processes->end->prev == processes->start) {
|
||||||
|
xnoe::linkedlistelem<Process*>* tmp = processes->start;
|
||||||
|
processes->start = processes->end;
|
||||||
|
processes->end = tmp;
|
||||||
|
|
||||||
|
processes->start->prev = 0;
|
||||||
|
processes->end->next = 0;
|
||||||
|
processes->end->prev = processes->start;
|
||||||
|
processes->start->next = processes->end;
|
||||||
|
} else {
|
||||||
|
xnoe::linkedlistelem<Process*>* tmp = processes->start;
|
||||||
|
processes->start = processes->end;
|
||||||
|
processes->end = tmp;
|
||||||
|
|
||||||
|
processes->start->next = processes->end->next;
|
||||||
|
processes->end->prev = processes->start->prev;
|
||||||
|
|
||||||
|
processes->start->prev = 0;
|
||||||
|
processes->end->next = 0;
|
||||||
|
|
||||||
|
processes->start->next->prev = processes->start;
|
||||||
|
processes->end->prev->next = processes->end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next process.
|
||||||
|
nextProc = processes->start->elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
Global::currentProc = nextProc;
|
||||||
|
|
||||||
|
uint32_t cESP;
|
||||||
|
asm volatile ("mov %%esp, %0" : "=a" (cESP) :);
|
||||||
|
currentProc->esp = cESP; // Store the current ESP of the current process process.
|
||||||
|
|
||||||
|
// Select the next processes page directory
|
||||||
|
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");
|
||||||
|
|
||||||
|
// Clear the garbage that was on the stack from previous switch_context call.
|
||||||
|
asm ("add $44, %esp");
|
||||||
|
|
||||||
|
// Pop EBP
|
||||||
|
asm ("pop %ebp");
|
||||||
|
|
||||||
|
// Re-enable interrupts.
|
||||||
|
asm ("sti");
|
||||||
|
|
||||||
|
// Manually perform iret.
|
||||||
|
asm ("iret");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void init_idt() {
|
void init_idt() {
|
||||||
idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt};
|
idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt};
|
||||||
asm volatile("lidt %0" : : "m" (desc));
|
asm volatile("lidt %0" : : "m" (desc));
|
||||||
@ -37,7 +112,9 @@ void init_idt() {
|
|||||||
set_entry(i, 0x08, &ignore_interrupt, 0x8E);
|
set_entry(i, 0x08, &ignore_interrupt, 0x8E);
|
||||||
|
|
||||||
set_entry(0x20, 0x08, &interrupt_20, 0x8E);
|
set_entry(0x20, 0x08, &interrupt_20, 0x8E);
|
||||||
|
set_entry(0xD, 0x08, &gpf, 0x8E);
|
||||||
set_entry(0xE, 0x08, &page_fault, 0x8E);
|
set_entry(0xE, 0x08, &page_fault, 0x8E);
|
||||||
|
set_entry(0x80, 0x08, &context_switch, 0x8E);
|
||||||
|
|
||||||
outb(0x20, 0x11);
|
outb(0x20, 0x11);
|
||||||
outb(0xA0, 0x11);
|
outb(0xA0, 0x11);
|
||||||
|
@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "screenstuff.h"
|
#include "screenstuff.h"
|
||||||
|
#include "global.h"
|
||||||
|
#include "kernel.h"
|
||||||
|
|
||||||
struct interrupt_frame {
|
struct interrupt_frame {
|
||||||
uint16_t ip;
|
uint32_t eip;
|
||||||
uint16_t cs;
|
uint16_t cs;
|
||||||
uint16_t flags;
|
uint16_t _ignored0;
|
||||||
uint16_t sp;
|
uint32_t eflags;
|
||||||
uint16_t ss;
|
|
||||||
};
|
};
|
||||||
extern void load_idt();
|
extern void load_idt();
|
||||||
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type);
|
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type);
|
||||||
|
@ -6,6 +6,10 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint
|
|||||||
this->currentPID = 1;
|
this->currentPID = 1;
|
||||||
Global::allocator = this;
|
Global::allocator = this;
|
||||||
Global::kernel = this;
|
Global::kernel = this;
|
||||||
|
|
||||||
|
Global::currentProc = 0;
|
||||||
|
|
||||||
|
this->processes.append(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::init_kernel() {
|
void Kernel::init_kernel() {
|
||||||
@ -13,8 +17,11 @@ void Kernel::init_kernel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Process* Kernel::createProcess() {
|
Process* Kernel::createProcess() {
|
||||||
Process* p = new Process(currentPID);
|
Process* p = new Process(currentPID, this->PD, 0xc0000000);
|
||||||
this->pid_map->set(currentPID, p);
|
this->pid_map->set(currentPID, p);
|
||||||
currentPID++;
|
currentPID++;
|
||||||
|
|
||||||
|
this->processes.append(p);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
@ -6,12 +6,12 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
class Kernel : public Process {
|
class Kernel : public Process {
|
||||||
private:
|
public:
|
||||||
uint32_t currentPID;
|
uint32_t currentPID;
|
||||||
|
|
||||||
public:
|
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s
|
||||||
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s
|
|
||||||
uint32_t current_PID;
|
xnoe::linkedlist<Process*> processes;
|
||||||
|
|
||||||
Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
|
Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
|
||||||
|
|
||||||
|
@ -47,10 +47,15 @@ int main() {
|
|||||||
|
|
||||||
term->printf("KERNEL OK!\n");
|
term->printf("KERNEL OK!\n");
|
||||||
|
|
||||||
kernel.createProcess();
|
Process* p = kernel.createProcess();
|
||||||
|
|
||||||
term->deactivate();
|
//term->deactivate();
|
||||||
term2->activate();
|
//term2->activate();
|
||||||
|
|
||||||
|
Global::currentProc = &kernel;
|
||||||
|
asm ("int $0x80");
|
||||||
|
|
||||||
|
term->printf("\n\nIf you are reading this, the XnoeOS kernel successfully switched contexts to another process, and then switched contexts back to the kernel. Therefore we can conclude that context switching works.");
|
||||||
|
|
||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
|
@ -88,8 +88,10 @@ PageTable::PageTable(uint32_t phys, uint32_t virt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PageTable::PageTable(){
|
PageTable::PageTable(){
|
||||||
virt_addr = new PTE[1024];
|
virt_addr = new PTE[2048];
|
||||||
phys_addr = Global::allocator->virtual_to_physical(virt_addr);
|
while ((uint32_t)this->virt_addr & 0xfff || (uint32_t)this->virt_addr % 0x4)
|
||||||
|
this->virt_addr++;
|
||||||
|
phys_addr = (Global::allocator->virtual_to_physical(virt_addr)) >> 12;
|
||||||
|
|
||||||
page_table = (PTE*)virt_addr;
|
page_table = (PTE*)virt_addr;
|
||||||
}
|
}
|
||||||
@ -143,8 +145,11 @@ PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t o
|
|||||||
|
|
||||||
PageDirectory::PageDirectory() {
|
PageDirectory::PageDirectory() {
|
||||||
this->page_tables = (PageTable*)this->__page_tables;
|
this->page_tables = (PageTable*)this->__page_tables;
|
||||||
this->page_directory = new PDE[1024];
|
this->page_directory = new PDE[2048];
|
||||||
|
while ((uint32_t)this->page_directory & 0xfff || (uint32_t)this->page_directory % 0x4)
|
||||||
|
this->page_directory++;
|
||||||
memset((uint8_t*)this->page_tables, sizeof(PageTable) * 1024, 0);
|
memset((uint8_t*)this->page_tables, sizeof(PageTable) * 1024, 0);
|
||||||
|
memset((uint8_t*)this->page_directory, sizeof(PDE) * 1024, 0);
|
||||||
this->phys_addr = Global::allocator->virtual_to_physical(this->page_directory);
|
this->phys_addr = Global::allocator->virtual_to_physical(this->page_directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,11 +185,11 @@ void PageDirectory::unmap(uint32_t virt) {
|
|||||||
|
|
||||||
uint32_t PageDirectory::virtual_to_physical(uint32_t virt) {
|
uint32_t PageDirectory::virtual_to_physical(uint32_t virt) {
|
||||||
split_addr* split = (split_addr*)&virt;
|
split_addr* split = (split_addr*)&virt;
|
||||||
return page_tables[split->pd_index].get_physical_address(split->pt_index);
|
return page_tables[split->pd_index].get_physical_address(split->pt_index) + split->page_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageDirectory::select() {
|
void PageDirectory::select() {
|
||||||
asm volatile("mov %0, %%eax; mov %%eax, %%cr3" : : "m" (phys_addr));
|
asm volatile("mov %0, %%cr3" : : "r" (phys_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
PageMap* Allocator::phys;
|
PageMap* Allocator::phys;
|
||||||
@ -205,7 +210,6 @@ Allocator::Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -214,7 +218,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,13 +51,14 @@ struct PageTable {
|
|||||||
|
|
||||||
class PageDirectory {
|
class PageDirectory {
|
||||||
private:
|
private:
|
||||||
PDE* page_directory;
|
|
||||||
uint8_t __page_tables[sizeof(PageTable) * 1024];
|
uint8_t __page_tables[sizeof(PageTable) * 1024];
|
||||||
PageTable* page_tables;
|
PageTable* page_tables;
|
||||||
|
|
||||||
|
public:
|
||||||
uint32_t phys_addr;
|
uint32_t phys_addr;
|
||||||
|
|
||||||
public:
|
PDE* page_directory;
|
||||||
|
|
||||||
PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset);
|
PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset);
|
||||||
PageDirectory();
|
PageDirectory();
|
||||||
|
|
||||||
@ -74,10 +75,10 @@ protected:
|
|||||||
static PageMap* phys;
|
static PageMap* phys;
|
||||||
PageMap* virt;
|
PageMap* virt;
|
||||||
|
|
||||||
PageDirectory* PD;
|
|
||||||
|
|
||||||
uint32_t virt_alloc_base;
|
uint32_t virt_alloc_base;
|
||||||
public:
|
public:
|
||||||
|
PageDirectory* PD;
|
||||||
|
|
||||||
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);
|
Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base);
|
||||||
virtual void* allocate(uint32_t size);
|
virtual void* allocate(uint32_t size);
|
||||||
|
@ -26,11 +26,80 @@ Process::Process(uint32_t PID)
|
|||||||
: Allocator(new PageDirectory, new PageMap, 0) {
|
: Allocator(new PageDirectory, new PageMap, 0) {
|
||||||
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 = 0;
|
||||||
this->stack = new uint8_t[0x8000];
|
this->stack = this->allocate(0x8000);
|
||||||
|
}
|
||||||
|
|
||||||
|
Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase)
|
||||||
|
: Allocator(new PageDirectory, new PageMap, 0) {
|
||||||
|
this->PID = PID;
|
||||||
|
this->page_remaining = 0;
|
||||||
|
this->last_page_pointer = 0;
|
||||||
|
|
||||||
|
for (int index = inheritBase >> 22; index < 1024; index++)
|
||||||
|
this->PD->page_directory[index] = inherit->page_directory[index];
|
||||||
|
|
||||||
|
this->stack = this->allocate(0x8000);
|
||||||
|
|
||||||
|
uint32_t pCR3;
|
||||||
|
asm ("mov %%cr3, %0" : "=a" (pCR3) :);
|
||||||
|
this->PD->select();
|
||||||
|
|
||||||
|
// We also need to initialise ESP and the stack
|
||||||
|
uint32_t* stack32 = ((uint32_t)this->stack + 0x8000);
|
||||||
|
printf("stack32: %x\n", stack32);
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 0x0; // EFLAGS
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 8; // CS 0x08
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 0x14; // Execution will begin from 0x14
|
||||||
|
|
||||||
|
stack32--;
|
||||||
|
*stack32 = ((uint32_t)this->stack + 0x8000); // EBP
|
||||||
|
|
||||||
|
stack32 -= 11;
|
||||||
|
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 0; // EAX
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 0; // ECX
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 0; // EDX
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 0; // EBX
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 0; // ESP
|
||||||
|
stack32--;
|
||||||
|
*stack32 = (uint32_t)this->stack + 0x7ffc; // EBP
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 0; // ESI
|
||||||
|
stack32--;
|
||||||
|
*stack32 = 0; // EDI
|
||||||
|
|
||||||
|
this->esp = stack32;
|
||||||
|
printf("this->esp: %x\n", stack32);
|
||||||
|
|
||||||
|
/*((uint8_t*)this->stack)[0] = 0xe9;
|
||||||
|
((uint8_t*)this->stack)[1] = 0xfb;
|
||||||
|
((uint8_t*)this->stack)[2] = 0xff;
|
||||||
|
((uint8_t*)this->stack)[3] = 0xff;
|
||||||
|
((uint8_t*)this->stack)[4] = 0xff;*/
|
||||||
|
|
||||||
|
((uint8_t*)this->stack)[0] = 0xcd;
|
||||||
|
((uint8_t*)this->stack)[1] = 0x80;
|
||||||
|
|
||||||
|
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Process::allocate(uint32_t size) {
|
void* Process::allocate(uint32_t size) {
|
||||||
|
bool switched_PD = false;
|
||||||
|
uint32_t pCR3;
|
||||||
|
asm ("mov %%cr3, %0" : "=a" (pCR3) :);
|
||||||
|
if (Global::currentProc != this) {
|
||||||
|
switched_PD = true;
|
||||||
|
this->PD->select();
|
||||||
|
}
|
||||||
void* ptr;
|
void* ptr;
|
||||||
// Determine if there's enough space to just allocate what's been requested
|
// Determine if there's enough space to just allocate what's been requested
|
||||||
if (size < this->page_remaining) {
|
if (size < this->page_remaining) {
|
||||||
@ -46,7 +115,7 @@ void* Process::allocate(uint32_t size) {
|
|||||||
uint32_t pages = size / 4096;
|
uint32_t pages = size / 4096;
|
||||||
uint32_t remainder = 4096 - (size % 4096);
|
uint32_t remainder = 4096 - (size % 4096);
|
||||||
|
|
||||||
ptr = Allocator::allocate(size);
|
ptr = this->Allocator::allocate(size);
|
||||||
|
|
||||||
// Update local values
|
// Update local values
|
||||||
this->last_page_pointer = ptr + pages * 4096;
|
this->last_page_pointer = ptr + pages * 4096;
|
||||||
@ -61,6 +130,9 @@ void* Process::allocate(uint32_t size) {
|
|||||||
|
|
||||||
ptr += elem_size;
|
ptr += elem_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +140,7 @@ void Process::deallocate(uint32_t virt_addr) {
|
|||||||
xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> alloc_tracker = this->get_alloc_tracker(virt_addr);
|
xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> alloc_tracker = this->get_alloc_tracker(virt_addr);
|
||||||
if (alloc_tracker.is_ok()) {
|
if (alloc_tracker.is_ok()) {
|
||||||
AllocTracker* ac = &alloc_tracker.get()->elem;
|
AllocTracker* ac = &alloc_tracker.get()->elem;
|
||||||
ac->alloc_count -= 1;
|
ac->alloc_count--;
|
||||||
if (ac->alloc_count == 0) {
|
if (ac->alloc_count == 0) {
|
||||||
void* base = ac->page_base;
|
void* base = ac->page_base;
|
||||||
uint32_t count = ac->page_size;
|
uint32_t count = ac->page_size;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
struct AllocTracker {
|
struct AllocTracker {
|
||||||
void* page_base;
|
void* page_base;
|
||||||
uint32_t page_size;
|
uint32_t page_size;
|
||||||
uint32_t alloc_count;
|
uint32_t alloc_count;
|
||||||
|
|
||||||
@ -32,8 +32,11 @@ 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:
|
||||||
|
uint32_t esp;
|
||||||
|
|
||||||
Process(uint32_t PID, void* stack, 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);
|
Process(uint32_t PID);
|
||||||
|
Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase);
|
||||||
|
|
||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user