diff --git a/src/kernel/lib/memory/alloc.c b/src/kernel/lib/memory/alloc.c index 0dd6081..aedcbad 100644 --- a/src/kernel/lib/memory/alloc.c +++ b/src/kernel/lib/memory/alloc.c @@ -12,7 +12,7 @@ firstBlock->size = -1; } -void* malloc(uint32_t size) { +void* mallocTask(uint32_t size, Task* task) { MemoryBlock* current = firstBlock; while (! (current->next == 0x00 || current->state == FREE && current->size >= size)) { current = current->next; @@ -44,9 +44,14 @@ } } current->state = IN_USE; + current->task = task; return (void*) (current + 1); } +void* malloc(uint32_t size) { + return mallocTask(size, (Task*) getCurrentTask()); +} + void mergeNextIfPossible(MemoryBlock* current) { if (current->next != 0x00 && current->next->state == FREE) { current->size = current->size + sizeof(MemoryBlock) + current->next->size; @@ -55,13 +60,14 @@ } } -void mfree(void* location) { +void free(void* location) { MemoryBlock* current = ((MemoryBlock*) location) - 1; current->state = FREE; + mergeNextIfPossible(current); if (current->last != 0x00 && current->last->state == FREE) { current = current->last; } - mergeNextIfPossible(current); // call this function 2 times in case a used block between 2 free blocks is freed + mergeNextIfPossible(current); // call this function twice in case a used block between 2 free blocks is freed mergeNextIfPossible(current); } @@ -72,4 +78,17 @@ current = current->next; } printf("AT: %x size: %x next: %x last: %x, state: %x\n", current, current->size, current->next, current->last, current->state); +} + +void freeTaskAllocations(Task* task) { + MemoryBlock* current = firstBlock; + while (current->next != 0x00) { + if (current->task == task) { + free(current); + } + current = current->next; + } + if (current->task == task) { + free(current); + } } \ No newline at end of file diff --git a/src/kernel/lib/memory/alloc.c b/src/kernel/lib/memory/alloc.c index 0dd6081..aedcbad 100644 --- a/src/kernel/lib/memory/alloc.c +++ b/src/kernel/lib/memory/alloc.c @@ -12,7 +12,7 @@ firstBlock->size = -1; } -void* malloc(uint32_t size) { +void* mallocTask(uint32_t size, Task* task) { MemoryBlock* current = firstBlock; while (! (current->next == 0x00 || current->state == FREE && current->size >= size)) { current = current->next; @@ -44,9 +44,14 @@ } } current->state = IN_USE; + current->task = task; return (void*) (current + 1); } +void* malloc(uint32_t size) { + return mallocTask(size, (Task*) getCurrentTask()); +} + void mergeNextIfPossible(MemoryBlock* current) { if (current->next != 0x00 && current->next->state == FREE) { current->size = current->size + sizeof(MemoryBlock) + current->next->size; @@ -55,13 +60,14 @@ } } -void mfree(void* location) { +void free(void* location) { MemoryBlock* current = ((MemoryBlock*) location) - 1; current->state = FREE; + mergeNextIfPossible(current); if (current->last != 0x00 && current->last->state == FREE) { current = current->last; } - mergeNextIfPossible(current); // call this function 2 times in case a used block between 2 free blocks is freed + mergeNextIfPossible(current); // call this function twice in case a used block between 2 free blocks is freed mergeNextIfPossible(current); } @@ -72,4 +78,17 @@ current = current->next; } printf("AT: %x size: %x next: %x last: %x, state: %x\n", current, current->size, current->next, current->last, current->state); +} + +void freeTaskAllocations(Task* task) { + MemoryBlock* current = firstBlock; + while (current->next != 0x00) { + if (current->task == task) { + free(current); + } + current = current->next; + } + if (current->task == task) { + free(current); + } } \ No newline at end of file diff --git a/src/kernel/lib/memory/alloc.h b/src/kernel/lib/memory/alloc.h index aac7846..42910ce 100644 --- a/src/kernel/lib/memory/alloc.h +++ b/src/kernel/lib/memory/alloc.h @@ -2,6 +2,7 @@ #define ALLOC_H #include +#include typedef enum MemoryState { FREE = 0, @@ -13,11 +14,15 @@ struct MemoryBlock* next; MemoryState state; uint32_t size; + Task* task; } MemoryBlock; extern void initMemoryAllocation(uint32_t kernelEnd); extern void* malloc(uint32_t size); -extern void mfree(void* location); +extern void* mallocTask(uint32_t size, Task* task); +extern void free(void* location); extern void printMemoryStack(); +extern void freeTaskAllocations(Task* task); +extern Task* getCurrentTask(); #endif \ No newline at end of file diff --git a/src/kernel/lib/memory/alloc.c b/src/kernel/lib/memory/alloc.c index 0dd6081..aedcbad 100644 --- a/src/kernel/lib/memory/alloc.c +++ b/src/kernel/lib/memory/alloc.c @@ -12,7 +12,7 @@ firstBlock->size = -1; } -void* malloc(uint32_t size) { +void* mallocTask(uint32_t size, Task* task) { MemoryBlock* current = firstBlock; while (! (current->next == 0x00 || current->state == FREE && current->size >= size)) { current = current->next; @@ -44,9 +44,14 @@ } } current->state = IN_USE; + current->task = task; return (void*) (current + 1); } +void* malloc(uint32_t size) { + return mallocTask(size, (Task*) getCurrentTask()); +} + void mergeNextIfPossible(MemoryBlock* current) { if (current->next != 0x00 && current->next->state == FREE) { current->size = current->size + sizeof(MemoryBlock) + current->next->size; @@ -55,13 +60,14 @@ } } -void mfree(void* location) { +void free(void* location) { MemoryBlock* current = ((MemoryBlock*) location) - 1; current->state = FREE; + mergeNextIfPossible(current); if (current->last != 0x00 && current->last->state == FREE) { current = current->last; } - mergeNextIfPossible(current); // call this function 2 times in case a used block between 2 free blocks is freed + mergeNextIfPossible(current); // call this function twice in case a used block between 2 free blocks is freed mergeNextIfPossible(current); } @@ -72,4 +78,17 @@ current = current->next; } printf("AT: %x size: %x next: %x last: %x, state: %x\n", current, current->size, current->next, current->last, current->state); +} + +void freeTaskAllocations(Task* task) { + MemoryBlock* current = firstBlock; + while (current->next != 0x00) { + if (current->task == task) { + free(current); + } + current = current->next; + } + if (current->task == task) { + free(current); + } } \ No newline at end of file diff --git a/src/kernel/lib/memory/alloc.h b/src/kernel/lib/memory/alloc.h index aac7846..42910ce 100644 --- a/src/kernel/lib/memory/alloc.h +++ b/src/kernel/lib/memory/alloc.h @@ -2,6 +2,7 @@ #define ALLOC_H #include +#include typedef enum MemoryState { FREE = 0, @@ -13,11 +14,15 @@ struct MemoryBlock* next; MemoryState state; uint32_t size; + Task* task; } MemoryBlock; extern void initMemoryAllocation(uint32_t kernelEnd); extern void* malloc(uint32_t size); -extern void mfree(void* location); +extern void* mallocTask(uint32_t size, Task* task); +extern void free(void* location); extern void printMemoryStack(); +extern void freeTaskAllocations(Task* task); +extern Task* getCurrentTask(); #endif \ No newline at end of file diff --git a/src/kernel/lib/task/osTasks.c b/src/kernel/lib/task/osTasks.c index 3ddeddd..74d70f6 100644 --- a/src/kernel/lib/task/osTasks.c +++ b/src/kernel/lib/task/osTasks.c @@ -10,7 +10,7 @@ printf("Hello from another task!\n"); yields(); printf("wait. . . Hello again\n"); - yield(); + destroyCurrentTask(); } void initOSTasks() { diff --git a/src/kernel/lib/memory/alloc.c b/src/kernel/lib/memory/alloc.c index 0dd6081..aedcbad 100644 --- a/src/kernel/lib/memory/alloc.c +++ b/src/kernel/lib/memory/alloc.c @@ -12,7 +12,7 @@ firstBlock->size = -1; } -void* malloc(uint32_t size) { +void* mallocTask(uint32_t size, Task* task) { MemoryBlock* current = firstBlock; while (! (current->next == 0x00 || current->state == FREE && current->size >= size)) { current = current->next; @@ -44,9 +44,14 @@ } } current->state = IN_USE; + current->task = task; return (void*) (current + 1); } +void* malloc(uint32_t size) { + return mallocTask(size, (Task*) getCurrentTask()); +} + void mergeNextIfPossible(MemoryBlock* current) { if (current->next != 0x00 && current->next->state == FREE) { current->size = current->size + sizeof(MemoryBlock) + current->next->size; @@ -55,13 +60,14 @@ } } -void mfree(void* location) { +void free(void* location) { MemoryBlock* current = ((MemoryBlock*) location) - 1; current->state = FREE; + mergeNextIfPossible(current); if (current->last != 0x00 && current->last->state == FREE) { current = current->last; } - mergeNextIfPossible(current); // call this function 2 times in case a used block between 2 free blocks is freed + mergeNextIfPossible(current); // call this function twice in case a used block between 2 free blocks is freed mergeNextIfPossible(current); } @@ -72,4 +78,17 @@ current = current->next; } printf("AT: %x size: %x next: %x last: %x, state: %x\n", current, current->size, current->next, current->last, current->state); +} + +void freeTaskAllocations(Task* task) { + MemoryBlock* current = firstBlock; + while (current->next != 0x00) { + if (current->task == task) { + free(current); + } + current = current->next; + } + if (current->task == task) { + free(current); + } } \ No newline at end of file diff --git a/src/kernel/lib/memory/alloc.h b/src/kernel/lib/memory/alloc.h index aac7846..42910ce 100644 --- a/src/kernel/lib/memory/alloc.h +++ b/src/kernel/lib/memory/alloc.h @@ -2,6 +2,7 @@ #define ALLOC_H #include +#include typedef enum MemoryState { FREE = 0, @@ -13,11 +14,15 @@ struct MemoryBlock* next; MemoryState state; uint32_t size; + Task* task; } MemoryBlock; extern void initMemoryAllocation(uint32_t kernelEnd); extern void* malloc(uint32_t size); -extern void mfree(void* location); +extern void* mallocTask(uint32_t size, Task* task); +extern void free(void* location); extern void printMemoryStack(); +extern void freeTaskAllocations(Task* task); +extern Task* getCurrentTask(); #endif \ No newline at end of file diff --git a/src/kernel/lib/task/osTasks.c b/src/kernel/lib/task/osTasks.c index 3ddeddd..74d70f6 100644 --- a/src/kernel/lib/task/osTasks.c +++ b/src/kernel/lib/task/osTasks.c @@ -10,7 +10,7 @@ printf("Hello from another task!\n"); yields(); printf("wait. . . Hello again\n"); - yield(); + destroyCurrentTask(); } void initOSTasks() { diff --git a/src/kernel/lib/task/task.c b/src/kernel/lib/task/task.c index b112c2b..7f4518f 100644 --- a/src/kernel/lib/task/task.c +++ b/src/kernel/lib/task/task.c @@ -2,9 +2,12 @@ #include #include -Task *runningTask; +#define STACK_SIZE 0xF000 + +Task *currentTask; void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir) { + void* stack = mallocTask(STACK_SIZE, task); task->registers.eax = 0; task->registers.ebx = 0; task->registers.ecx = 0; @@ -14,25 +17,26 @@ task->registers.eflags = flags; task->registers.eip = mainFunction; task->registers.cr3 = (uint32_t) pagedir; - task->registers.esp = 0xF000 + (uint32_t) malloc(0x1000); + task->registers.esp = STACK_SIZE + (uint32_t) stack; task->nextTask = 0; + task->stack = stack; } void yield() { - Task* last = runningTask; - runningTask = runningTask->nextTask; - if (runningTask == 0x00) { + Task* last = currentTask; + currentTask = currentTask->nextTask; + if (currentTask == 0x00) { printf("No more tasks to run, halting . . .\n"); while (1) { asm("hlt"); } } last->nextTask = 0x00; - switchTask(&(last->registers), &(runningTask->registers)); + switchTask(&(last->registers), &(currentTask->registers)); } void schedule(Task* task) { - Task* test = runningTask; + Task* test = currentTask; while (test->nextTask != 0x0) { test = test->nextTask; if (test->nextTask == task) { @@ -43,10 +47,19 @@ } void setRunningTask(Task* task) { - runningTask = task; + currentTask = task; } void yields() { - schedule(runningTask); + schedule(currentTask); yield(); +} + +void destroyCurrentTask() { + freeTaskAllocations(currentTask); + yield(); +} + +Task* getCurrentTask() { + return currentTask; } \ No newline at end of file diff --git a/src/kernel/lib/memory/alloc.c b/src/kernel/lib/memory/alloc.c index 0dd6081..aedcbad 100644 --- a/src/kernel/lib/memory/alloc.c +++ b/src/kernel/lib/memory/alloc.c @@ -12,7 +12,7 @@ firstBlock->size = -1; } -void* malloc(uint32_t size) { +void* mallocTask(uint32_t size, Task* task) { MemoryBlock* current = firstBlock; while (! (current->next == 0x00 || current->state == FREE && current->size >= size)) { current = current->next; @@ -44,9 +44,14 @@ } } current->state = IN_USE; + current->task = task; return (void*) (current + 1); } +void* malloc(uint32_t size) { + return mallocTask(size, (Task*) getCurrentTask()); +} + void mergeNextIfPossible(MemoryBlock* current) { if (current->next != 0x00 && current->next->state == FREE) { current->size = current->size + sizeof(MemoryBlock) + current->next->size; @@ -55,13 +60,14 @@ } } -void mfree(void* location) { +void free(void* location) { MemoryBlock* current = ((MemoryBlock*) location) - 1; current->state = FREE; + mergeNextIfPossible(current); if (current->last != 0x00 && current->last->state == FREE) { current = current->last; } - mergeNextIfPossible(current); // call this function 2 times in case a used block between 2 free blocks is freed + mergeNextIfPossible(current); // call this function twice in case a used block between 2 free blocks is freed mergeNextIfPossible(current); } @@ -72,4 +78,17 @@ current = current->next; } printf("AT: %x size: %x next: %x last: %x, state: %x\n", current, current->size, current->next, current->last, current->state); +} + +void freeTaskAllocations(Task* task) { + MemoryBlock* current = firstBlock; + while (current->next != 0x00) { + if (current->task == task) { + free(current); + } + current = current->next; + } + if (current->task == task) { + free(current); + } } \ No newline at end of file diff --git a/src/kernel/lib/memory/alloc.h b/src/kernel/lib/memory/alloc.h index aac7846..42910ce 100644 --- a/src/kernel/lib/memory/alloc.h +++ b/src/kernel/lib/memory/alloc.h @@ -2,6 +2,7 @@ #define ALLOC_H #include +#include typedef enum MemoryState { FREE = 0, @@ -13,11 +14,15 @@ struct MemoryBlock* next; MemoryState state; uint32_t size; + Task* task; } MemoryBlock; extern void initMemoryAllocation(uint32_t kernelEnd); extern void* malloc(uint32_t size); -extern void mfree(void* location); +extern void* mallocTask(uint32_t size, Task* task); +extern void free(void* location); extern void printMemoryStack(); +extern void freeTaskAllocations(Task* task); +extern Task* getCurrentTask(); #endif \ No newline at end of file diff --git a/src/kernel/lib/task/osTasks.c b/src/kernel/lib/task/osTasks.c index 3ddeddd..74d70f6 100644 --- a/src/kernel/lib/task/osTasks.c +++ b/src/kernel/lib/task/osTasks.c @@ -10,7 +10,7 @@ printf("Hello from another task!\n"); yields(); printf("wait. . . Hello again\n"); - yield(); + destroyCurrentTask(); } void initOSTasks() { diff --git a/src/kernel/lib/task/task.c b/src/kernel/lib/task/task.c index b112c2b..7f4518f 100644 --- a/src/kernel/lib/task/task.c +++ b/src/kernel/lib/task/task.c @@ -2,9 +2,12 @@ #include #include -Task *runningTask; +#define STACK_SIZE 0xF000 + +Task *currentTask; void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir) { + void* stack = mallocTask(STACK_SIZE, task); task->registers.eax = 0; task->registers.ebx = 0; task->registers.ecx = 0; @@ -14,25 +17,26 @@ task->registers.eflags = flags; task->registers.eip = mainFunction; task->registers.cr3 = (uint32_t) pagedir; - task->registers.esp = 0xF000 + (uint32_t) malloc(0x1000); + task->registers.esp = STACK_SIZE + (uint32_t) stack; task->nextTask = 0; + task->stack = stack; } void yield() { - Task* last = runningTask; - runningTask = runningTask->nextTask; - if (runningTask == 0x00) { + Task* last = currentTask; + currentTask = currentTask->nextTask; + if (currentTask == 0x00) { printf("No more tasks to run, halting . . .\n"); while (1) { asm("hlt"); } } last->nextTask = 0x00; - switchTask(&(last->registers), &(runningTask->registers)); + switchTask(&(last->registers), &(currentTask->registers)); } void schedule(Task* task) { - Task* test = runningTask; + Task* test = currentTask; while (test->nextTask != 0x0) { test = test->nextTask; if (test->nextTask == task) { @@ -43,10 +47,19 @@ } void setRunningTask(Task* task) { - runningTask = task; + currentTask = task; } void yields() { - schedule(runningTask); + schedule(currentTask); yield(); +} + +void destroyCurrentTask() { + freeTaskAllocations(currentTask); + yield(); +} + +Task* getCurrentTask() { + return currentTask; } \ No newline at end of file diff --git a/src/kernel/lib/task/task.h b/src/kernel/lib/task/task.h index 50c4de2..f7bfd9e 100644 --- a/src/kernel/lib/task/task.h +++ b/src/kernel/lib/task/task.h @@ -5,13 +5,14 @@ extern void initTasking(); -typedef struct { +typedef struct __attribute__ ((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; typedef struct Task { Registers registers; // the register states for the task struct Task *nextTask; // linked list of tasks that need to be done + void* stack; } Task; extern void initTasking(); @@ -21,6 +22,7 @@ extern void yields(); // yield, but schedule the currently running task extern void switchTask(Registers *old, Registers *new); // swicht from the old to the new task extern void schedule(Task* task); // schedule a task to be run in the future +extern void destroyCurrentTask(); extern void setRunningTask(Task* task); // set the task currently executed diff --git a/src/kernel/lib/memory/alloc.c b/src/kernel/lib/memory/alloc.c index 0dd6081..aedcbad 100644 --- a/src/kernel/lib/memory/alloc.c +++ b/src/kernel/lib/memory/alloc.c @@ -12,7 +12,7 @@ firstBlock->size = -1; } -void* malloc(uint32_t size) { +void* mallocTask(uint32_t size, Task* task) { MemoryBlock* current = firstBlock; while (! (current->next == 0x00 || current->state == FREE && current->size >= size)) { current = current->next; @@ -44,9 +44,14 @@ } } current->state = IN_USE; + current->task = task; return (void*) (current + 1); } +void* malloc(uint32_t size) { + return mallocTask(size, (Task*) getCurrentTask()); +} + void mergeNextIfPossible(MemoryBlock* current) { if (current->next != 0x00 && current->next->state == FREE) { current->size = current->size + sizeof(MemoryBlock) + current->next->size; @@ -55,13 +60,14 @@ } } -void mfree(void* location) { +void free(void* location) { MemoryBlock* current = ((MemoryBlock*) location) - 1; current->state = FREE; + mergeNextIfPossible(current); if (current->last != 0x00 && current->last->state == FREE) { current = current->last; } - mergeNextIfPossible(current); // call this function 2 times in case a used block between 2 free blocks is freed + mergeNextIfPossible(current); // call this function twice in case a used block between 2 free blocks is freed mergeNextIfPossible(current); } @@ -72,4 +78,17 @@ current = current->next; } printf("AT: %x size: %x next: %x last: %x, state: %x\n", current, current->size, current->next, current->last, current->state); +} + +void freeTaskAllocations(Task* task) { + MemoryBlock* current = firstBlock; + while (current->next != 0x00) { + if (current->task == task) { + free(current); + } + current = current->next; + } + if (current->task == task) { + free(current); + } } \ No newline at end of file diff --git a/src/kernel/lib/memory/alloc.h b/src/kernel/lib/memory/alloc.h index aac7846..42910ce 100644 --- a/src/kernel/lib/memory/alloc.h +++ b/src/kernel/lib/memory/alloc.h @@ -2,6 +2,7 @@ #define ALLOC_H #include +#include typedef enum MemoryState { FREE = 0, @@ -13,11 +14,15 @@ struct MemoryBlock* next; MemoryState state; uint32_t size; + Task* task; } MemoryBlock; extern void initMemoryAllocation(uint32_t kernelEnd); extern void* malloc(uint32_t size); -extern void mfree(void* location); +extern void* mallocTask(uint32_t size, Task* task); +extern void free(void* location); extern void printMemoryStack(); +extern void freeTaskAllocations(Task* task); +extern Task* getCurrentTask(); #endif \ No newline at end of file diff --git a/src/kernel/lib/task/osTasks.c b/src/kernel/lib/task/osTasks.c index 3ddeddd..74d70f6 100644 --- a/src/kernel/lib/task/osTasks.c +++ b/src/kernel/lib/task/osTasks.c @@ -10,7 +10,7 @@ printf("Hello from another task!\n"); yields(); printf("wait. . . Hello again\n"); - yield(); + destroyCurrentTask(); } void initOSTasks() { diff --git a/src/kernel/lib/task/task.c b/src/kernel/lib/task/task.c index b112c2b..7f4518f 100644 --- a/src/kernel/lib/task/task.c +++ b/src/kernel/lib/task/task.c @@ -2,9 +2,12 @@ #include #include -Task *runningTask; +#define STACK_SIZE 0xF000 + +Task *currentTask; void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir) { + void* stack = mallocTask(STACK_SIZE, task); task->registers.eax = 0; task->registers.ebx = 0; task->registers.ecx = 0; @@ -14,25 +17,26 @@ task->registers.eflags = flags; task->registers.eip = mainFunction; task->registers.cr3 = (uint32_t) pagedir; - task->registers.esp = 0xF000 + (uint32_t) malloc(0x1000); + task->registers.esp = STACK_SIZE + (uint32_t) stack; task->nextTask = 0; + task->stack = stack; } void yield() { - Task* last = runningTask; - runningTask = runningTask->nextTask; - if (runningTask == 0x00) { + Task* last = currentTask; + currentTask = currentTask->nextTask; + if (currentTask == 0x00) { printf("No more tasks to run, halting . . .\n"); while (1) { asm("hlt"); } } last->nextTask = 0x00; - switchTask(&(last->registers), &(runningTask->registers)); + switchTask(&(last->registers), &(currentTask->registers)); } void schedule(Task* task) { - Task* test = runningTask; + Task* test = currentTask; while (test->nextTask != 0x0) { test = test->nextTask; if (test->nextTask == task) { @@ -43,10 +47,19 @@ } void setRunningTask(Task* task) { - runningTask = task; + currentTask = task; } void yields() { - schedule(runningTask); + schedule(currentTask); yield(); +} + +void destroyCurrentTask() { + freeTaskAllocations(currentTask); + yield(); +} + +Task* getCurrentTask() { + return currentTask; } \ No newline at end of file diff --git a/src/kernel/lib/task/task.h b/src/kernel/lib/task/task.h index 50c4de2..f7bfd9e 100644 --- a/src/kernel/lib/task/task.h +++ b/src/kernel/lib/task/task.h @@ -5,13 +5,14 @@ extern void initTasking(); -typedef struct { +typedef struct __attribute__ ((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; typedef struct Task { Registers registers; // the register states for the task struct Task *nextTask; // linked list of tasks that need to be done + void* stack; } Task; extern void initTasking(); @@ -21,6 +22,7 @@ extern void yields(); // yield, but schedule the currently running task extern void switchTask(Registers *old, Registers *new); // swicht from the old to the new task extern void schedule(Task* task); // schedule a task to be run in the future +extern void destroyCurrentTask(); extern void setRunningTask(Task* task); // set the task currently executed diff --git a/src/kernel/lib/task/task.s b/src/kernel/lib/task/task.s index bb6d076..88357cd 100644 --- a/src/kernel/lib/task/task.s +++ b/src/kernel/lib/task/task.s @@ -14,7 +14,7 @@ mov 36(%esp), %ebx #EAX mov 40(%esp), %ecx #IP mov 20(%esp), %edx #ESP - add $4, %edx #Remove the return value ;) + add $4, %edx #Remove the return value mov 16(%esp), %esi #EBP mov 4(%esp), %edi #EFLAGS mov %ebx, (%eax) @@ -24,7 +24,7 @@ mov %edi, 36(%eax) pop %ebx #CR3 mov %ebx, 40(%eax) - push %ebx #Goodbye again ;) + push %ebx #Goodbye again mov 48(%esp), %eax #Now it is the new object mov 4(%eax), %ebx #EBX mov 8(%eax), %ecx #ECX @@ -44,6 +44,6 @@ pop %eax push %eax mov 32(%eax), %eax #EIP - xchg (%esp), %eax #We do not have any more registers to use as tmp storage + xchg (%esp), %eax mov (%eax), %eax #EAX ret diff --git a/src/kernel/lib/memory/alloc.c b/src/kernel/lib/memory/alloc.c index 0dd6081..aedcbad 100644 --- a/src/kernel/lib/memory/alloc.c +++ b/src/kernel/lib/memory/alloc.c @@ -12,7 +12,7 @@ firstBlock->size = -1; } -void* malloc(uint32_t size) { +void* mallocTask(uint32_t size, Task* task) { MemoryBlock* current = firstBlock; while (! (current->next == 0x00 || current->state == FREE && current->size >= size)) { current = current->next; @@ -44,9 +44,14 @@ } } current->state = IN_USE; + current->task = task; return (void*) (current + 1); } +void* malloc(uint32_t size) { + return mallocTask(size, (Task*) getCurrentTask()); +} + void mergeNextIfPossible(MemoryBlock* current) { if (current->next != 0x00 && current->next->state == FREE) { current->size = current->size + sizeof(MemoryBlock) + current->next->size; @@ -55,13 +60,14 @@ } } -void mfree(void* location) { +void free(void* location) { MemoryBlock* current = ((MemoryBlock*) location) - 1; current->state = FREE; + mergeNextIfPossible(current); if (current->last != 0x00 && current->last->state == FREE) { current = current->last; } - mergeNextIfPossible(current); // call this function 2 times in case a used block between 2 free blocks is freed + mergeNextIfPossible(current); // call this function twice in case a used block between 2 free blocks is freed mergeNextIfPossible(current); } @@ -72,4 +78,17 @@ current = current->next; } printf("AT: %x size: %x next: %x last: %x, state: %x\n", current, current->size, current->next, current->last, current->state); +} + +void freeTaskAllocations(Task* task) { + MemoryBlock* current = firstBlock; + while (current->next != 0x00) { + if (current->task == task) { + free(current); + } + current = current->next; + } + if (current->task == task) { + free(current); + } } \ No newline at end of file diff --git a/src/kernel/lib/memory/alloc.h b/src/kernel/lib/memory/alloc.h index aac7846..42910ce 100644 --- a/src/kernel/lib/memory/alloc.h +++ b/src/kernel/lib/memory/alloc.h @@ -2,6 +2,7 @@ #define ALLOC_H #include +#include typedef enum MemoryState { FREE = 0, @@ -13,11 +14,15 @@ struct MemoryBlock* next; MemoryState state; uint32_t size; + Task* task; } MemoryBlock; extern void initMemoryAllocation(uint32_t kernelEnd); extern void* malloc(uint32_t size); -extern void mfree(void* location); +extern void* mallocTask(uint32_t size, Task* task); +extern void free(void* location); extern void printMemoryStack(); +extern void freeTaskAllocations(Task* task); +extern Task* getCurrentTask(); #endif \ No newline at end of file diff --git a/src/kernel/lib/task/osTasks.c b/src/kernel/lib/task/osTasks.c index 3ddeddd..74d70f6 100644 --- a/src/kernel/lib/task/osTasks.c +++ b/src/kernel/lib/task/osTasks.c @@ -10,7 +10,7 @@ printf("Hello from another task!\n"); yields(); printf("wait. . . Hello again\n"); - yield(); + destroyCurrentTask(); } void initOSTasks() { diff --git a/src/kernel/lib/task/task.c b/src/kernel/lib/task/task.c index b112c2b..7f4518f 100644 --- a/src/kernel/lib/task/task.c +++ b/src/kernel/lib/task/task.c @@ -2,9 +2,12 @@ #include #include -Task *runningTask; +#define STACK_SIZE 0xF000 + +Task *currentTask; void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir) { + void* stack = mallocTask(STACK_SIZE, task); task->registers.eax = 0; task->registers.ebx = 0; task->registers.ecx = 0; @@ -14,25 +17,26 @@ task->registers.eflags = flags; task->registers.eip = mainFunction; task->registers.cr3 = (uint32_t) pagedir; - task->registers.esp = 0xF000 + (uint32_t) malloc(0x1000); + task->registers.esp = STACK_SIZE + (uint32_t) stack; task->nextTask = 0; + task->stack = stack; } void yield() { - Task* last = runningTask; - runningTask = runningTask->nextTask; - if (runningTask == 0x00) { + Task* last = currentTask; + currentTask = currentTask->nextTask; + if (currentTask == 0x00) { printf("No more tasks to run, halting . . .\n"); while (1) { asm("hlt"); } } last->nextTask = 0x00; - switchTask(&(last->registers), &(runningTask->registers)); + switchTask(&(last->registers), &(currentTask->registers)); } void schedule(Task* task) { - Task* test = runningTask; + Task* test = currentTask; while (test->nextTask != 0x0) { test = test->nextTask; if (test->nextTask == task) { @@ -43,10 +47,19 @@ } void setRunningTask(Task* task) { - runningTask = task; + currentTask = task; } void yields() { - schedule(runningTask); + schedule(currentTask); yield(); +} + +void destroyCurrentTask() { + freeTaskAllocations(currentTask); + yield(); +} + +Task* getCurrentTask() { + return currentTask; } \ No newline at end of file diff --git a/src/kernel/lib/task/task.h b/src/kernel/lib/task/task.h index 50c4de2..f7bfd9e 100644 --- a/src/kernel/lib/task/task.h +++ b/src/kernel/lib/task/task.h @@ -5,13 +5,14 @@ extern void initTasking(); -typedef struct { +typedef struct __attribute__ ((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; typedef struct Task { Registers registers; // the register states for the task struct Task *nextTask; // linked list of tasks that need to be done + void* stack; } Task; extern void initTasking(); @@ -21,6 +22,7 @@ extern void yields(); // yield, but schedule the currently running task extern void switchTask(Registers *old, Registers *new); // swicht from the old to the new task extern void schedule(Task* task); // schedule a task to be run in the future +extern void destroyCurrentTask(); extern void setRunningTask(Task* task); // set the task currently executed diff --git a/src/kernel/lib/task/task.s b/src/kernel/lib/task/task.s index bb6d076..88357cd 100644 --- a/src/kernel/lib/task/task.s +++ b/src/kernel/lib/task/task.s @@ -14,7 +14,7 @@ mov 36(%esp), %ebx #EAX mov 40(%esp), %ecx #IP mov 20(%esp), %edx #ESP - add $4, %edx #Remove the return value ;) + add $4, %edx #Remove the return value mov 16(%esp), %esi #EBP mov 4(%esp), %edi #EFLAGS mov %ebx, (%eax) @@ -24,7 +24,7 @@ mov %edi, 36(%eax) pop %ebx #CR3 mov %ebx, 40(%eax) - push %ebx #Goodbye again ;) + push %ebx #Goodbye again mov 48(%esp), %eax #Now it is the new object mov 4(%eax), %ebx #EBX mov 8(%eax), %ecx #ECX @@ -44,6 +44,6 @@ pop %eax push %eax mov 32(%eax), %eax #EIP - xchg (%esp), %eax #We do not have any more registers to use as tmp storage + xchg (%esp), %eax mov (%eax), %eax #EAX ret diff --git a/src/kernel/lib/textMode/stdio.c b/src/kernel/lib/textMode/stdio.c index 9a6de47..fbddfd0 100644 --- a/src/kernel/lib/textMode/stdio.c +++ b/src/kernel/lib/textMode/stdio.c @@ -11,7 +11,7 @@ *(framebuffer + position) = c; } -void putCharWithFormatAt(uint8_t x, uint8_t y, uint32_t c) { +void putCharWithFormatAtPosition(uint8_t x, uint8_t y, uint32_t c) { putCharWithFormatAtOffset(c, (x + y * VIDEO_WIDTH)); } @@ -53,9 +53,12 @@ void shiftUp() { for (int y = 1; y < VIDEO_HEIGHT; y++) { for (int x = 0; x < VIDEO_WIDTH; x++) { - putCharWithFormatAt(x, y-1, getCharWithFormatAt(x, y)); + putCharWithFormatAtPosition(x, y-1, getCharWithFormatAt(x, y)); } } + for (int x = 0; x < VIDEO_WIDTH; x++) { + putCharWithFormatAtPosition(x, VIDEO_HEIGHT-1, 0x00); + } } void newLine() { @@ -78,7 +81,7 @@ uint8_t alreadyWriting = 0; puts(HEX_PREFIX); for (int8_t i = 7; i >= 0; i--) { - uint8_t nibble = (x >> (i * 4)) & 0x0F; + uint8_t nibble = (x >> (i << 2)) & 0x0F; if (! alreadyWriting && nibble != 0x00) { alreadyWriting = 0x01; }