Renamed Maybe to maybe. Moved tracking of filehandlers to be per-process rather than global. Various improvements to code.

This commit is contained in:
Xnoe 2022-06-18 11:42:09 +01:00
parent da5fc52afe
commit fdb77277a7
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
16 changed files with 277 additions and 167 deletions

View File

@ -24,4 +24,6 @@ syscall_hdlr_0(uint32_t, getRemainingPages, "19");
syscall_hdlr_0(uint32_t, getInitPages, "20"); syscall_hdlr_0(uint32_t, getInitPages, "20");
syscall_hdlr_0(uint32_t, getCurrentTerminalWidth, "21"); syscall_hdlr_0(uint32_t, getCurrentTerminalWidth, "21");
syscall_hdlr_0(uint32_t, getCurrentTerminalHeight, "22"); syscall_hdlr_0(uint32_t, getCurrentTerminalHeight, "22");
syscall_hdlr_1(uint32_t, getProcessState, "23", uint32_t, PID);

View File

@ -0,0 +1,63 @@
#ifndef DYNARRAY_H
#define DYNARRAY_H
#include "../global.h"
#include "maybe.h"
#include "../spinlock.h"
namespace xnoe {
template<typename T>
class dynarray {
private:
uint32_t size = 128;
T* buffer;
uint32_t index = 0;
uint32_t start_index = 0;
Spinlock lock;
public:
dynarray(uint32_t start_index=0) {
this->buffer = new T[size];
this->index = this->start_index = start_index;
}
void push(T t) {
if (index == size) {
lock.lock();
uint32_t old_size = size;
size *= 2;
T* buffer_tmp = new T[size];
memcpy((uint8_t*)buffer, (uint8_t*)buffer_tmp, sizeof(T)*old_size);
delete buffer;
buffer = buffer_tmp;
lock.unlock();
}
buffer[index++] = t;
}
uint32_t length() {
return index;
}
xnoe::maybe<T> pop() {
if (index == start_index)
return xnoe::maybe<T>();
return xnoe::maybe<T>(buffer[--index]);
}
xnoe::maybe<T> get(uint32_t i) {
if (i>size)
return xnoe::maybe<T>();
return xnoe::maybe<T>(buffer[i]);
}
void set(uint32_t i, T t) {
if (i>size)
return;
buffer[i] = t;
}
};
}
#endif

View File

@ -39,19 +39,19 @@ namespace xnoe {
list->append(xnoe::tuple<key, value>(k, v)); list->append(xnoe::tuple<key, value>(k, v));
} }
xnoe::Maybe<value> get(key k) { xnoe::maybe<value> get(key k) {
xnoe::linkedlist<xnoe::tuple<key, value>>* list = &table[xnoe::hash<key>(k) % 4096]; xnoe::linkedlist<xnoe::tuple<key, value>>* list = &table[xnoe::hash<key>(k) % 4096];
xnoe::linkedlistelem<xnoe::tuple<key, value>>* current = list->start; xnoe::linkedlistelem<xnoe::tuple<key, value>>* current = list->start;
if (current) { if (current) {
while (current) { while (current) {
if (xnoe::get<0>(current->elem) == k) if (xnoe::get<0>(current->elem) == k)
return xnoe::Maybe<value>(xnoe::get<1>(current->elem)); return xnoe::maybe<value>(xnoe::get<1>(current->elem));
current = current->next; current = current->next;
} }
} }
return xnoe::Maybe<value>(); return xnoe::maybe<value>();
} }
void remove(key k) { void remove(key k) {

View File

@ -24,6 +24,7 @@ namespace xnoe {
xnoe::linkedlistelem<T>* start=0; xnoe::linkedlistelem<T>* start=0;
xnoe::linkedlistelem<T>* end=0; xnoe::linkedlistelem<T>* end=0;
Spinlock lock = Spinlock(); Spinlock lock = Spinlock();
uint32_t length = 0;
bool has(T t) { bool has(T t) {
xnoe::linkedlistelem<T>* current = this->start; xnoe::linkedlistelem<T>* current = this->start;
@ -61,6 +62,7 @@ namespace xnoe {
this->start = llelem; this->start = llelem;
this->end = llelem; this->end = llelem;
} }
length++;
lock.unlock(); lock.unlock();
} }
@ -80,6 +82,7 @@ namespace xnoe {
this->start = llelem; this->start = llelem;
this->end = llelem; this->end = llelem;
} }
length++;
lock.unlock(); lock.unlock();
} }
@ -90,6 +93,7 @@ namespace xnoe {
current->next->prev = ll->end; current->next->prev = ll->end;
current->next = ll->start; current->next = ll->start;
length += ll.length;
lock.unlock(); lock.unlock();
} }
@ -120,6 +124,7 @@ namespace xnoe {
if (current = end) if (current = end)
end = current->prev; end = current->prev;
length--;
lock.unlock(); lock.unlock();
return; return;
} }
@ -147,6 +152,7 @@ namespace xnoe {
delete current; delete current;
length--;
lock.unlock(); lock.unlock();
return; return;
} }

View File

@ -3,17 +3,17 @@
namespace xnoe { namespace xnoe {
template<typename T> template<typename T>
class Maybe { class maybe {
private: private:
T t; T t;
bool ok; bool ok;
public: public:
Maybe() { maybe() {
this->ok = false; this->ok = false;
} }
Maybe(T t) { maybe(T t) {
this->ok = true; this->ok = true;
this->t = t; this->t = t;
} }

View File

@ -6,7 +6,6 @@ namespace Global {
Process* currentProc = 0; Process* currentProc = 0;
tss_struct* tss = 0; tss_struct* tss = 0;
bool currentProcValid = false; bool currentProcValid = false;
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
uint32_t milliseconds_elapsed = 0; uint32_t milliseconds_elapsed = 0;
uint32_t resp = 0; uint32_t resp = 0;
} }

View File

@ -8,10 +8,6 @@ class Allocator;
class Process; class Process;
struct tss_struct; struct tss_struct;
class ReadWriter; class ReadWriter;
namespace xnoe {
template<class, class>
class hashtable;
}
namespace Global { namespace Global {
extern Allocator* allocator; extern Allocator* allocator;
@ -19,7 +15,6 @@ namespace Global {
extern Process* currentProc; extern Process* currentProc;
extern tss_struct* tss; extern tss_struct* tss;
extern bool currentProcValid; extern bool currentProcValid;
extern xnoe::hashtable<void*, ReadWriter*>* FH;
extern uint32_t milliseconds_elapsed; extern uint32_t milliseconds_elapsed;
extern uint32_t resp; extern uint32_t resp;
} }

View File

@ -98,7 +98,10 @@ void context_switch(frame_struct* frame) {
// - Determines if it has 2 or more elements // - 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 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, add the start to the end then set start to the second element // - If it has more than two, add the start to the end then set start to the second element
uint32_t count = 0;
do { do {
if (count++ == processes->length)
return;
if (Global::currentProc) { if (Global::currentProc) {
if (processes->start->next != 0) { if (processes->start->next != 0) {
if (processes->end->prev == processes->start) { if (processes->end->prev == processes->start) {
@ -215,39 +218,44 @@ void syscall(frame_struct* frame) {
Process* currentProc = Global::currentProc; Process* currentProc = Global::currentProc;
switch (frame->eax) { switch (frame->eax) {
case 0: case 0: // getDentsSize
rval = Global::kernel->rootfs->getDentsSize(createPathFromString(frame->ebx)); rval = Global::kernel->rootfs->getDentsSize(createPathFromString(frame->ebx));
break; break;
case 1: case 1: // getDents
Global::kernel->rootfs->getDents(createPathFromString(frame->ebx), frame->ecx); Global::kernel->rootfs->getDents(createPathFromString(frame->ebx), frame->ecx);
break; break;
case 2: case 2: // exists
rval = Global::kernel->rootfs->exists(createPathFromString(frame->ebx)); rval = Global::kernel->rootfs->exists(createPathFromString(frame->ebx));
break; break;
case 3: case 3: // type
rval = Global::kernel->rootfs->type(createPathFromString(frame->ebx)); rval = Global::kernel->rootfs->type(createPathFromString(frame->ebx));
break; break;
case 4: case 4: // malloc
rval = currentProc->allocate(frame->ebx); rval = currentProc->allocate(frame->ebx);
break; break;
case 5: case 5: // free
currentProc->deallocate(frame->ebx); currentProc->deallocate(frame->ebx);
break; break;
case 6: case 6: // getMillisecondsElapsed
rval = Global::milliseconds_elapsed; rval = Global::milliseconds_elapsed;
break; break;
case 7: { case 7: { // exec
asm("cli"); asm("cli");
Process* p = Global::kernel->createProcess(frame->ebx); xnoe::maybe<ReadWriter*> file = Global::currentProc->getFH(frame->ebx);
rval = p->PID; if (file.is_ok()) {
Process* p = Global::kernel->createProcess(file.get());
rval = p->PID;
} else {
rval = 0;
}
asm("sti"); asm("sti");
break; break;
} }
case 8: case 8: // getPID
rval = currentProc->PID; rval = currentProc->PID;
break; break;
case 9: case 9: // die
Global::kernel->PD->select(); Global::kernel->PD->select();
// We can now safely delete the current process // We can now safely delete the current process
@ -257,47 +265,31 @@ void syscall(frame_struct* frame) {
context_switch(frame); context_switch(frame);
break; break;
case 10: { case 10: { // read
if (frame->ecx == 1) { xnoe::maybe<ReadWriter*> fh = Global::currentProc->getFH(frame->ecx);
ReadWriter* stdin = currentProc->stdin; if (!fh.is_ok()) {
if (!stdin) rval = 0;
break; break;
rval = stdin->read(frame->ebx, frame->edx);
} else {
xnoe::Maybe<ReadWriter*> fh = Global::FH->get(frame->ecx);
if (!fh.is_ok()) {
rval = 0;
break;
}
ReadWriter* rw = fh.get();
rval = rw->read(frame->ebx, frame->edx);
} }
ReadWriter* rw = fh.get();
rval = rw->read(frame->ebx, frame->edx);
break; break;
} }
case 11: { case 11: { // write
if (frame->ecx == 0) { xnoe::maybe<ReadWriter*> fh = Global::currentProc->getFH(frame->ecx);
ReadWriter* stdout = currentProc->stdout; if (!fh.is_ok()) {
if (!stdout) rval = 0;
break; break;
rval = stdout->write(frame->ebx, frame->edx);
} else {
xnoe::Maybe<ReadWriter*> fh = Global::FH->get(frame->ecx);
if (!fh.is_ok()) {
rval = 0;
break;
}
ReadWriter* rw = fh.get();
rval = rw->write(frame->ebx, frame->edx);
} }
ReadWriter* rw = fh.get();
rval = rw->write(frame->ebx, frame->edx);
break; break;
} }
case 12: case 12: // bindToKeyboard
if (currentProc->stdin) if (currentProc->stdin)
break; break;
@ -305,51 +297,51 @@ void syscall(frame_struct* frame) {
Global::kernel->KBListeners.append(currentProc); Global::kernel->KBListeners.append(currentProc);
break; break;
case 13: { case 13: { // bindStdout
xnoe::Maybe<Process*> pm = Global::kernel->pid_map->get(frame->ebx); xnoe::maybe<Process*> pm = Global::kernel->pid_map->get(frame->ebx);
if (!pm.is_ok()) if (!pm.is_ok())
break; break;
Process* p = pm.get(); Process* p = pm.get();
if (!p->stdout) { if (!p->stdout) {
ReadWriter* buffer = new CircularRWBuffer(currentProc->PID, frame->ebx); ReadWriter* buffer = new CircularRWBuffer(currentProc->PID, frame->ebx);
p->stdout = buffer; p->stdout = buffer;
rval = Global::kernel->mapFH(buffer); rval = Global::currentProc->mapFH(buffer);
} }
break; break;
} }
case 14: { case 14: { // bindStdin
xnoe::Maybe<Process*> pm = Global::kernel->pid_map->get(frame->ebx); xnoe::maybe<Process*> pm = Global::kernel->pid_map->get(frame->ebx);
if (!pm.is_ok()) if (!pm.is_ok())
break; break;
Process* p = pm.get(); Process* p = pm.get();
if (!p->stdin) { if (!p->stdin) {
ReadWriter* buffer = new CircularRWBuffer(frame->ebx, currentProc->PID); ReadWriter* buffer = new CircularRWBuffer(frame->ebx, currentProc->PID);
p->stdin = buffer; p->stdin = buffer;
rval = Global::kernel->mapFH(buffer); rval = Global::currentProc->mapFH(buffer);
} }
break; break;
} }
case 15: { case 15: { // fopen
ReadWriter* file = Global::kernel->rootfs->open(createPathFromString(frame->ebx)); ReadWriter* file = Global::kernel->rootfs->open(createPathFromString(frame->ebx));
if (file) if (file)
rval = Global::kernel->mapFH(file); rval = Global::currentProc->mapFH(file);
break; break;
} }
case 16: { case 16: { // fclose
xnoe::Maybe<ReadWriter*> f = Global::FH->get(frame->ebx); xnoe::maybe<ReadWriter*> f = Global::currentProc->getFH(frame->ebx);
if (f.is_ok()) { if (f.is_ok()) {
delete f.get(); delete f.get();
Global::kernel->unmapFH(frame->ebx); Global::currentProc->unmapFH(frame->ebx);
} }
break; break;
} }
case 17: { case 17: { // kill
asm("cli"); asm("cli");
xnoe::Maybe<Process*> p = Global::kernel->pid_map->get(frame->ebx); xnoe::maybe<Process*> p = Global::kernel->pid_map->get(frame->ebx);
if (p.is_ok()) { if (p.is_ok()) {
Process* proc = p.get(); Process* proc = p.get();
Global::kernel->destroyProcess(proc); Global::kernel->destroyProcess(proc);
@ -358,26 +350,35 @@ void syscall(frame_struct* frame) {
break; break;
} }
case 18: { case 18: { // sleep
Global::currentProc->state = Suspended; Global::currentProc->state = Suspended;
Timer::register_event(frame->ebx, &awaken, (void*)Global::currentProc, true); Timer::register_event(frame->ebx, &awaken, (void*)Global::currentProc);
context_switch(frame); context_switch(frame);
break; break;
} }
case 19: case 19: // getRemainingPages
rval = Global::kernel->phys->remainingPages; rval = Global::kernel->phys->remainingPages;
break; break;
case 20: case 20: // getInitPages
rval = Global::kernel->phys->initPages; rval = Global::kernel->phys->initPages;
break; break;
case 21: case 21: // getTerminalWidth
rval = Global::kernel->terminal->width; rval = Global::kernel->terminal->width;
break; break;
case 22: case 22: // getTerminalHeight
rval = Global::kernel->terminal->height; rval = Global::kernel->terminal->height;
break; break;
case 23: { // getProcessState
xnoe::maybe<Process*> p = Global::kernel->pid_map->get(frame->ebx);
if (p.is_ok()) {
Process* proc = p.get();
rval = proc->state;
}
break;
}
default: default:
break; break;
@ -411,7 +412,7 @@ void v86_monitor(v8086_frame_struct* frame) {
*(--sp) = flags; *(--sp) = flags;
frame->eflags &= ~(0x00040300); frame->eflags &= ~(0x00040300);
*(--sp) = (uint16_t)frame->cs; *(--sp) = (uint16_t)frame->cs;
*(--sp) = (uint16_t)(frame->eip+2); *(--sp) = (uint16_t)(frame->eip);
uint16_t* vector = (uint16_t*)&vector_data; uint16_t* vector = (uint16_t*)&vector_data;
frame->cs = vector[1]; frame->cs = vector[1];
frame->eip = (uint32_t)vector[0]; frame->eip = (uint32_t)vector[0];

View File

@ -16,12 +16,12 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint
void Kernel::init_kernel() { void Kernel::init_kernel() {
this->pid_map = new xnoe::hashtable<uint32_t, Process*>(); this->pid_map = new xnoe::hashtable<uint32_t, Process*>();
Global::FH = new xnoe::hashtable<void*, ReadWriter*>();
this->globalISRStack = (new uint8_t[0x8000]) + 0x8000; this->globalISRStack = (new uint8_t[0x8000]) + 0x8000;
} }
Process* Kernel::createProcess(uint32_t fh) { Process* Kernel::createProcess(ReadWriter* file) {
Process* p = new Process(currentPID, this->PD, 0xc0000000, fh); char* name = "test";
Process* p = new Process(currentPID, this->PD, 0xc0000000, file, 1, &name);
this->pid_map->set(currentPID, p); this->pid_map->set(currentPID, p);
currentPID++; currentPID++;
@ -30,8 +30,8 @@ Process* Kernel::createProcess(uint32_t fh) {
return p; return p;
} }
Process* Kernel::createProcess(uint32_t fh, ReadWriter* stdout) { Process* Kernel::createProcess(ReadWriter* file, ReadWriter* stdout) {
Process* p = this->createProcess(fh); Process* p = this->createProcess(file);
p->stdout = stdout; p->stdout = stdout;
return p; return p;
} }
@ -44,15 +44,6 @@ void Kernel::destroyProcess(Process* p) {
delete p; delete p;
} }
int Kernel::mapFH(ReadWriter* fh) {
Global::FH->set(this->lastFH++, fh);
return this->lastFH - 1;
}
void Kernel::unmapFH(uint32_t fh) {
Global::FH->remove((void*)fh);
}
void Kernel::v86(uint16_t ax, uint16_t bx, uint16_t cx, uint16_t es, uint16_t di, uint8_t intn) { void Kernel::v86(uint16_t ax, uint16_t bx, uint16_t cx, uint16_t es, uint16_t di, uint8_t intn) {
// Create the payload to perform an interrupt. // Create the payload to perform an interrupt.
uint8_t payload[21] = { uint8_t payload[21] = {

View File

@ -28,13 +28,10 @@ public:
void init_kernel(); void init_kernel();
Process* createProcess(uint32_t fh); Process* createProcess(ReadWriter* file);
Process* createProcess(uint32_t fh, ReadWriter* stdout); Process* createProcess(ReadWriter* file, ReadWriter* stdout);
void destroyProcess(Process* p); void destroyProcess(Process* p);
int mapFH(ReadWriter* fh);
void unmapFH(uint32_t fh);
void v86(uint16_t ax, uint16_t bx, uint16_t cx, uint16_t es, uint16_t di, uint8_t intn); void v86(uint16_t ax, uint16_t bx, uint16_t cx, uint16_t es, uint16_t di, uint8_t intn);
}; };

View File

@ -56,32 +56,17 @@ int main(KernelInformationStruct kstruct) {
ReadWriter* atareadwriter = new ATAReadWriter(0, 0); ReadWriter* atareadwriter = new ATAReadWriter(0, 0);
uint8_t* buffer = new uint8_t[512];
for (int i=0;i<512;i++)
buffer[i]=0;
uint32_t size = atareadwriter->size();
atareadwriter->seek(268*512);
atareadwriter->read(512, buffer);
kernel.rootfs = new RootFSTree(); kernel.rootfs = new RootFSTree();
kernel.rootfs->mount(createPathFromString("/dev"), new DevFS()); kernel.rootfs->mount(createPathFromString("/dev"), new DevFS());
kernel.rootfs->mount(createPathFromString("/"), new FAT16FS(kernel.rootfs->open(createPathFromString("/dev/ata")))); kernel.rootfs->mount(createPathFromString("/"), new FAT16FS(kernel.rootfs->open(createPathFromString("/dev/ata"))));
ReadWriter* worldbin = kernel.rootfs->open(createPathFromString("/world.bin")); ReadWriter* worldbin = kernel.rootfs->open(createPathFromString("/world.bin"));
uint32_t fh = kernel.mapFH(worldbin);
Process* p1 = kernel.createProcess(fh, term); Process* p1 = kernel.createProcess(worldbin, term);
Global::tss->esp0 = (new uint8_t[8192]) + 8192; Global::tss->esp0 = (new uint8_t[8192]) + 8192;
//kernel.v86(0x4f00,0,0,0x0,0x8000,0x10);
init_keyboard(); init_keyboard();
if (worldbin) { enable_idt();
worldbin->seek(0);
worldbin->read(512, buffer);
worldbin->seek(0);
enable_idt();
}
while (1) asm ("hlt"); while (1) asm ("hlt");
} }

View File

@ -4,16 +4,16 @@ extern void(*catchall_return)();
AllocTracker::AllocTracker(void* base, uint32_t size, uint32_t count) : page_base(base), page_size(size), alloc_count(count) {} AllocTracker::AllocTracker(void* base, uint32_t size, uint32_t count) : page_base(base), page_size(size), alloc_count(count) {}
xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> Process::get_alloc_tracker(uint32_t address) { xnoe::maybe<xnoe::linkedlistelem<AllocTracker>*> Process::get_alloc_tracker(uint32_t address) {
xnoe::linkedlistelem<AllocTracker>* current = this->allocations.start; xnoe::linkedlistelem<AllocTracker>* current = this->allocations.start;
while (current) { 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<xnoe::linkedlistelem<AllocTracker>*>(current); return xnoe::maybe<xnoe::linkedlistelem<AllocTracker>*>(current);
} }
current = current->next; current = current->next;
} }
return xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*>(); return xnoe::maybe<xnoe::linkedlistelem<AllocTracker>*>();
} }
Process::Process(uint32_t PID, void* stack, 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)
@ -33,9 +33,10 @@ Process::Process(uint32_t PID)
this->stack = this->allocate(0x8000); this->stack = this->allocate(0x8000);
this->kernelStackPtr = (new uint8_t[0x4000]) + 0x4000; this->kernelStackPtr = (new uint8_t[0x4000]) + 0x4000;
this->state = Running; this->state = Running;
this->file_handlers = new xnoe::dynarray<ReadWriter*>(8);
} }
Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uint32_t fh) Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, ReadWriter* filereader, uint32_t argc, char** argv)
: Allocator(new PageDirectory, new PageMap, (uint32_t)0, 3) { : Allocator(new PageDirectory, new PageMap, (uint32_t)0, 3) {
this->stdout = 0; this->stdout = 0;
this->stdin = 0; this->stdin = 0;
@ -47,50 +48,63 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uin
this->last_page_pointer = 0; this->last_page_pointer = 0;
this->state = Running; this->state = Running;
this->file_handlers = new xnoe::dynarray<ReadWriter*>(8);
for (int index = inheritBase >> 22; index < 1024; index++) for (int index = inheritBase >> 22; index < 1024; index++)
this->PD->page_directory[index] = inherit->page_directory[index]; this->PD->page_directory[index] = inherit->page_directory[index];
xnoe::Maybe<ReadWriter*> file = Global::FH->get(fh); uint32_t filesize = filereader->size();
if (file.is_ok()) { uint8_t* program_data = this->allocate(filesize + 12) + 12;
ReadWriter* filereader = file.get();
uint32_t filesize = filereader->size();
uint8_t* program_data = this->allocate(filesize + 12) + 12;
this->stack = this->allocate(0x8000); uint8_t* argenvarea = this->allocate(0x2000);
this->kernelStackPtr = (new uint8_t[0x4000]) + 0x4000;
this->kernelStackPtrDefault = this->kernelStackPtr;
uint32_t pCR3; this->stack = this->allocate(0x8000);
asm ("mov %%cr3, %0" : "=a" (pCR3) :); this->kernelStackPtr = (new uint8_t[0x4000]) + 0x4000;
this->PD->select(); this->kernelStackPtrDefault = this->kernelStackPtr;
// We also need to initialise ESP and the stack uint32_t pCR3;
uint32_t* stack32 = ((uint32_t)this->kernelStackPtr); asm ("mov %%cr3, %0" : "=a" (pCR3) :);
*(--stack32) = 0x23; // SS this->PD->select();
*(--stack32) = ((uint32_t)this->stack + 0x8000); // ESP
*(--stack32) = 0x200; // EFLAGS
*(--stack32) = 27; // CS
*(--stack32) = (uint32_t)program_data; // EIP
*(--stack32) = ((uint32_t)this->stack + 0x8000); // EBP
uint32_t rEBP = stack32; uint32_t* stack = this->stack + 0x8000;
uint32_t argenv = argenvarea + 0x2000;
*(--stack32) = 0; // EAX for (int i=argc; i>0; i--) {
*(--stack32) = 0; // ECX char* s = argv[i-1];
*(--stack32) = 0; // EDX uint32_t c = 0;
*(--stack32) = 0; // EBX while (*(c++, s++));
*(--stack32) = 0; // ESP memcpy((uint8_t*)argv[i-1], (uint8_t*)(argenv -= c), c);
*(--stack32) = rEBP; // EBP *(--stack) = argenv;
*(--stack32) = 0; // ESI
*(--stack32) = 0; // EDI
this->kernelStackPtr = stack32;
filereader->seek(0);
filereader->read(filesize, program_data);
asm ("mov %0, %%cr3" : : "r" (pCR3));
} }
*(--stack) = ((uint32_t)stack);
*(--stack) = argc;
// We also need to initialise ESP and the stack
uint32_t* stack32 = ((uint32_t)this->kernelStackPtr);
*(--stack32) = 0x23; // SS
*(--stack32) = ((uint32_t)stack); // ESP
*(--stack32) = 0x200; // EFLAGS
*(--stack32) = 27; // CS
*(--stack32) = (uint32_t)program_data; // EIP
*(--stack32) = ((uint32_t)stack); // EBP
uint32_t rEBP = stack32;
*(--stack32) = 0; // EAX
*(--stack32) = 0; // ECX
*(--stack32) = 0; // EDX
*(--stack32) = 0; // EBX
*(--stack32) = 0; // ESP
*(--stack32) = rEBP; // EBP
*(--stack32) = 0; // ESI
*(--stack32) = 0; // EDI
this->kernelStackPtr = stack32;
filereader->seek(0);
filereader->read(filesize, program_data);
asm ("mov %0, %%cr3" : : "r" (pCR3));
} }
Process::~Process() { Process::~Process() {
@ -105,6 +119,14 @@ Process::~Process() {
this->deallocate(active->elem.page_base); this->deallocate(active->elem.page_base);
} }
asm ("mov %0, %%cr3" : : "r" (pCR3)); asm ("mov %0, %%cr3" : : "r" (pCR3));
for (int i=0; i<file_handlers->length();i++) {
xnoe::maybe<ReadWriter*> r;
if ((r=file_handlers->get(i)).is_ok())
if (r.get())
delete r.get();
}
delete kernelStackPtr; delete kernelStackPtr;
} }
@ -153,7 +175,7 @@ void* Process::allocate(uint32_t size) {
} }
void Process::deallocate(uint32_t virt_addr) { 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--; ac->alloc_count--;
@ -172,10 +194,41 @@ void Process::deallocate(uint32_t virt_addr) {
} }
uint32_t Process::count_allocations(uint32_t address) { uint32_t Process::count_allocations(uint32_t address) {
xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> alloc_tracker = this->get_alloc_tracker(address); xnoe::maybe<xnoe::linkedlistelem<AllocTracker>*> alloc_tracker = this->get_alloc_tracker(address);
if (alloc_tracker.is_ok()) if (alloc_tracker.is_ok())
return alloc_tracker.get()->elem.alloc_count; return alloc_tracker.get()->elem.alloc_count;
else else
return 0; return 0;
}
uint32_t Process::mapFH(ReadWriter* rw) {
file_handlers->push(rw);
return file_handlers->length()-1;
}
void Process::unmapFH(uint32_t file_handler) {
file_handlers->set(file_handler, 0);
}
xnoe::maybe<ReadWriter*> Process::getFH(uint32_t file_handler) {
if (file_handler == 1)
if (stdin)
return xnoe::maybe<ReadWriter*>(stdin);
else
return xnoe::maybe<ReadWriter*>();
if (file_handler == 0)
if (stdout)
return xnoe::maybe<ReadWriter*>(stdout);
else
return xnoe::maybe<ReadWriter*>();
xnoe::maybe<ReadWriter*> rw = file_handlers->get(file_handler);
if (!rw.is_ok())
return rw;
if (!rw.get())
return xnoe::maybe<ReadWriter*>();
return rw;
} }

View File

@ -7,9 +7,10 @@
#include "datatypes/hashtable.h" #include "datatypes/hashtable.h"
#include "datatypes/maybe.h" #include "datatypes/maybe.h"
#include "global.h" #include "global.h"
#include "ata.h" #include "processstate.h"
#include "stdio/readwriter.h" #include "stdio/readwriter.h"
#include "datatypes/dynarray.h"
#include "filesystem/fstree.h"
struct AllocTracker { struct AllocTracker {
void* page_base; void* page_base;
@ -19,11 +20,6 @@ struct AllocTracker {
AllocTracker(void* base, uint32_t size, uint32_t count); AllocTracker(void* base, uint32_t size, uint32_t count);
}; };
enum ProcessState {
Running,
Suspended
};
class Process : public Allocator { class Process : public Allocator {
private: private:
uint32_t last_page_pointer; uint32_t last_page_pointer;
@ -34,7 +30,11 @@ private:
// List of pages this process has allocated // List of pages this process has allocated
xnoe::linkedlist<AllocTracker> allocations; xnoe::linkedlist<AllocTracker> allocations;
xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> get_alloc_tracker(uint32_t address); xnoe::maybe<xnoe::linkedlistelem<AllocTracker>*> get_alloc_tracker(uint32_t address);
xnoe::dynarray<ReadWriter*>* file_handlers;
Path currentWorkingDirectory;
public: public:
uint32_t PID; uint32_t PID;
@ -52,7 +52,7 @@ public:
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, uint32_t fh); Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, ReadWriter* filereader, uint32_t argc=0, char** argv=0);
~Process(); // Iterate through allocations and free those; delete stack ~Process(); // Iterate through allocations and free those; delete stack
@ -60,6 +60,10 @@ public:
void deallocate(uint32_t virt_addr) override; void deallocate(uint32_t virt_addr) override;
uint32_t count_allocations(uint32_t address); uint32_t count_allocations(uint32_t address);
uint32_t mapFH(ReadWriter* rw);
void unmapFH(uint32_t file_handler);
xnoe::maybe<ReadWriter*> getFH(uint32_t file_handler);
}; };
#endif #endif

View File

@ -0,0 +1,9 @@
#ifndef PROCESSSTATE_H
#define PROCESSSTATE_H
enum ProcessState {
Running=0,
Suspended=1
};
#endif

View File

@ -25,7 +25,9 @@ void readline(int count, char* buffer) {
print("\n"); print("\n");
} }
int main() { int main(int argc, char** argv) {
printf("Hi, I am %s, running with PID %d!\n", argv[0], getPID());
print("Hello, World!\n"); print("Hello, World!\n");
char buffer[32]; char buffer[32];
while (1) { while (1) {

View File

@ -5,7 +5,10 @@ int main() {
while (1) { while (1) {
printf("Time Elapsed: %dms\n", getMillisecondsElapsed()); printf("Time Elapsed: %dms\n", getMillisecondsElapsed());
printf("Init. Pages: %d\nRemaining Pages: %d\n", getInitPages(), getRemainingPages()); printf("Init. Pages: %d\nRemaining Pages: %d\n", getInitPages(), getRemainingPages());
exec(crashBin);
printf("PID 2 State: %s\n", (!getProcessState(2))?"Running":"Suspended");
//exec(crashBin);
sleep(1000); sleep(1000);
} }
} }