Renamed Maybe to maybe. Moved tracking of filehandlers to be per-process rather than global. Various improvements to code.
This commit is contained in:
parent
da5fc52afe
commit
fdb77277a7
@ -25,3 +25,5 @@ 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);
|
63
src/kernel/datatypes/dynarray.h
Normal file
63
src/kernel/datatypes/dynarray.h
Normal 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
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
if (file.is_ok()) {
|
||||||
|
Process* p = Global::kernel->createProcess(file.get());
|
||||||
rval = p->PID;
|
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,15 +265,8 @@ 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 (!stdin)
|
|
||||||
break;
|
|
||||||
|
|
||||||
rval = stdin->read(frame->ebx, frame->edx);
|
|
||||||
} else {
|
|
||||||
xnoe::Maybe<ReadWriter*> fh = Global::FH->get(frame->ecx);
|
|
||||||
if (!fh.is_ok()) {
|
if (!fh.is_ok()) {
|
||||||
rval = 0;
|
rval = 0;
|
||||||
break;
|
break;
|
||||||
@ -273,19 +274,11 @@ void syscall(frame_struct* frame) {
|
|||||||
|
|
||||||
ReadWriter* rw = fh.get();
|
ReadWriter* rw = fh.get();
|
||||||
rval = rw->read(frame->ebx, frame->edx);
|
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 (!stdout)
|
|
||||||
break;
|
|
||||||
|
|
||||||
rval = stdout->write(frame->ebx, frame->edx);
|
|
||||||
} else {
|
|
||||||
xnoe::Maybe<ReadWriter*> fh = Global::FH->get(frame->ecx);
|
|
||||||
if (!fh.is_ok()) {
|
if (!fh.is_ok()) {
|
||||||
rval = 0;
|
rval = 0;
|
||||||
break;
|
break;
|
||||||
@ -293,11 +286,10 @@ void syscall(frame_struct* frame) {
|
|||||||
|
|
||||||
ReadWriter* rw = fh.get();
|
ReadWriter* rw = fh.get();
|
||||||
rval = rw->write(frame->ebx, frame->edx);
|
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,27 +350,36 @@ 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];
|
||||||
|
@ -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] = {
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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) {
|
|
||||||
worldbin->seek(0);
|
|
||||||
worldbin->read(512, buffer);
|
|
||||||
worldbin->seek(0);
|
|
||||||
enable_idt();
|
enable_idt();
|
||||||
}
|
|
||||||
|
|
||||||
while (1) asm ("hlt");
|
while (1) asm ("hlt");
|
||||||
}
|
}
|
@ -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,15 +48,16 @@ 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);
|
|
||||||
if (file.is_ok()) {
|
|
||||||
ReadWriter* filereader = file.get();
|
|
||||||
uint32_t filesize = filereader->size();
|
uint32_t filesize = filereader->size();
|
||||||
uint8_t* program_data = this->allocate(filesize + 12) + 12;
|
uint8_t* program_data = this->allocate(filesize + 12) + 12;
|
||||||
|
|
||||||
|
uint8_t* argenvarea = this->allocate(0x2000);
|
||||||
|
|
||||||
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->kernelStackPtrDefault = this->kernelStackPtr;
|
this->kernelStackPtrDefault = this->kernelStackPtr;
|
||||||
@ -64,14 +66,27 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uin
|
|||||||
asm ("mov %%cr3, %0" : "=a" (pCR3) :);
|
asm ("mov %%cr3, %0" : "=a" (pCR3) :);
|
||||||
this->PD->select();
|
this->PD->select();
|
||||||
|
|
||||||
|
uint32_t* stack = this->stack + 0x8000;
|
||||||
|
uint32_t argenv = argenvarea + 0x2000;
|
||||||
|
for (int i=argc; i>0; i--) {
|
||||||
|
char* s = argv[i-1];
|
||||||
|
uint32_t c = 0;
|
||||||
|
while (*(c++, s++));
|
||||||
|
memcpy((uint8_t*)argv[i-1], (uint8_t*)(argenv -= c), c);
|
||||||
|
*(--stack) = argenv;
|
||||||
|
}
|
||||||
|
*(--stack) = ((uint32_t)stack);
|
||||||
|
|
||||||
|
*(--stack) = argc;
|
||||||
|
|
||||||
// We also need to initialise ESP and the stack
|
// We also need to initialise ESP and the stack
|
||||||
uint32_t* stack32 = ((uint32_t)this->kernelStackPtr);
|
uint32_t* stack32 = ((uint32_t)this->kernelStackPtr);
|
||||||
*(--stack32) = 0x23; // SS
|
*(--stack32) = 0x23; // SS
|
||||||
*(--stack32) = ((uint32_t)this->stack + 0x8000); // ESP
|
*(--stack32) = ((uint32_t)stack); // ESP
|
||||||
*(--stack32) = 0x200; // EFLAGS
|
*(--stack32) = 0x200; // EFLAGS
|
||||||
*(--stack32) = 27; // CS
|
*(--stack32) = 27; // CS
|
||||||
*(--stack32) = (uint32_t)program_data; // EIP
|
*(--stack32) = (uint32_t)program_data; // EIP
|
||||||
*(--stack32) = ((uint32_t)this->stack + 0x8000); // EBP
|
*(--stack32) = ((uint32_t)stack); // EBP
|
||||||
|
|
||||||
uint32_t rEBP = stack32;
|
uint32_t rEBP = stack32;
|
||||||
|
|
||||||
@ -91,7 +106,6 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uin
|
|||||||
|
|
||||||
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Process::~Process() {
|
Process::~Process() {
|
||||||
uint32_t pCR3;
|
uint32_t pCR3;
|
||||||
@ -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;
|
||||||
|
}
|
@ -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
|
9
src/kernel/processstate.h
Normal file
9
src/kernel/processstate.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef PROCESSSTATE_H
|
||||||
|
#define PROCESSSTATE_H
|
||||||
|
|
||||||
|
enum ProcessState {
|
||||||
|
Running=0,
|
||||||
|
Suspended=1
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user