Multi-user multitasking
This commit is contained in:
parent
582f4b720f
commit
b87bb2f228
|
@ -49,7 +49,7 @@ void set_page_table_entry(size_t address, void* ptr)
|
||||||
struct x86_Page_Table create_table;
|
struct x86_Page_Table create_table;
|
||||||
|
|
||||||
void setup_paging() {
|
void setup_paging() {
|
||||||
struct x86_Page_Table* kernel = get_table(768);
|
struct x86_Page_Table* kernel = get_table(0x300);
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
while (kernel[i].present == 0) {
|
while (kernel[i].present == 0) {
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
void run_program(uint8_t* code, size_t code_length, uint8_t* data, size_t data_length);
|
void run_program(void* code, size_t code_length, void* data, size_t data_length, void* code_destination, void* data_destination);
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,23 @@
|
||||||
|
|
||||||
extern struct Heap_Metadata global_heap;
|
extern struct Heap_Metadata global_heap;
|
||||||
|
|
||||||
|
#ifndef __Heap_Metadata
|
||||||
|
#define __Heap_Metadata
|
||||||
struct Heap_Metadata {
|
struct Heap_Metadata {
|
||||||
struct Heap_Block* start;
|
struct Heap_Block* start;
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __Heap_Block
|
||||||
|
#define __Heap_Block
|
||||||
struct Heap_Block {
|
struct Heap_Block {
|
||||||
struct Heap_Block* next;
|
struct Heap_Block* next;
|
||||||
size_t size;
|
size_t size;
|
||||||
bool used;
|
bool used;
|
||||||
void* data;
|
void* data;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
void heap_init();
|
void heap_init();
|
||||||
void* malloc(size_t size);
|
void* malloc(size_t size);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <kernel/heap.h>
|
||||||
|
|
||||||
struct CPUState {
|
struct CPUState {
|
||||||
size_t eax;
|
size_t eax;
|
||||||
|
@ -18,6 +19,10 @@ struct CPUState {
|
||||||
|
|
||||||
struct Task {
|
struct Task {
|
||||||
struct CPUState state;
|
struct CPUState state;
|
||||||
|
size_t size;
|
||||||
|
struct Heap_Block* code;
|
||||||
|
struct Heap_Block* data;
|
||||||
|
bool needs_pages;
|
||||||
};
|
};
|
||||||
|
|
||||||
void switch_task(
|
void switch_task(
|
||||||
|
|
22
kernel/elf.c
22
kernel/elf.c
|
@ -14,21 +14,18 @@ static void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t s
|
||||||
return dstptr;
|
return dstptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_program(uint8_t* code, size_t code_length, uint8_t* data, size_t data_length)
|
void run_program(void* code, size_t code_length, void* data, size_t data_length, struct Heap_Block* code_block, struct Heap_Block* data_block)
|
||||||
{
|
{
|
||||||
// TODO: Replace following lines with malloc calls and paging calls
|
// TODO: Replace following lines with malloc calls and paging calls
|
||||||
uint8_t* userland_code = (uint8_t*) 0x00000000;
|
memcpy(code_block->data, code, code_length);
|
||||||
uint8_t* userland_data = (uint8_t*) 0x00400000;
|
memcpy(data_block->data, data, data_length);
|
||||||
|
|
||||||
memcpy(userland_code, code, code_length);
|
|
||||||
memcpy(userland_data, data, data_length);
|
|
||||||
|
|
||||||
struct CPUState target = {
|
struct CPUState target = {
|
||||||
.eip = (size_t) userland_code,
|
.eip = (size_t) 0x00400000,
|
||||||
.esp = 0x00400800,
|
.esp = (size_t) 0x00801000,
|
||||||
.eax = 0x00400000,
|
.eax = (size_t) 0x00800000,
|
||||||
.ebx = 0,
|
.ebx = data_length,
|
||||||
.ecx = 0,
|
.ecx = 0x00400000,
|
||||||
.edx = 0,
|
.edx = 0,
|
||||||
.cs = 0x18 | 0x3,
|
.cs = 0x18 | 0x3,
|
||||||
.ds = 0x20 | 0x3,
|
.ds = 0x20 | 0x3,
|
||||||
|
@ -40,6 +37,9 @@ void run_program(uint8_t* code, size_t code_length, uint8_t* data, size_t data_l
|
||||||
|
|
||||||
struct Task task = {
|
struct Task task = {
|
||||||
.state = target,
|
.state = target,
|
||||||
|
.needs_pages = true,
|
||||||
|
.code = code_block,
|
||||||
|
.data = data_block,
|
||||||
};
|
};
|
||||||
|
|
||||||
add_task(task);
|
add_task(task);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
|
|
||||||
#define HEAP_SIZE (1 << 16)
|
#define HEAP_SIZE (1 << 12)
|
||||||
#define NUM_PAGES (128)
|
#define NUM_PAGES (128)
|
||||||
|
|
||||||
uint8_t global_heap_data[HEAP_SIZE + sizeof(struct Heap_Block)];
|
uint8_t global_heap_data[HEAP_SIZE + sizeof(struct Heap_Block)];
|
||||||
|
@ -169,6 +169,9 @@ void free(void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
start->next = current;
|
start->next = current;
|
||||||
|
if (start->next == start) {
|
||||||
|
terminal_writestring("Woops");
|
||||||
|
}
|
||||||
start->size = (size_t)start->next - (size_t)start->data;
|
start->size = (size_t)start->next - (size_t)start->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,13 +18,15 @@ uint8_t program[] = {
|
||||||
0xff, 0xe1, // jmp *%ecx
|
0xff, 0xe1, // jmp *%ecx
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t data[] = "Hello From Userspace\n";
|
uint8_t data1[] = "Hello From Userspace 1\n\0";
|
||||||
|
uint8_t data2[] = "Hello 2\n\0";
|
||||||
|
|
||||||
uint8_t kernel_data[] = "Hello From Kernelspace\n";
|
uint8_t kernel_data[] = "Hello From Kernelspace\n\0";
|
||||||
// uint8_t data[] = {};
|
// uint8_t data[] = {};
|
||||||
|
|
||||||
void kernel_main(void)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
|
asm("cli");
|
||||||
/* Initialize terminal interface */
|
/* Initialize terminal interface */
|
||||||
terminal_initialize();
|
terminal_initialize();
|
||||||
terminal_writestring("Hello from Kernelspace\n");
|
terminal_writestring("Hello from Kernelspace\n");
|
||||||
|
@ -38,32 +40,32 @@ void kernel_main(void)
|
||||||
|
|
||||||
terminal_writestring("Woaw\n");
|
terminal_writestring("Woaw\n");
|
||||||
|
|
||||||
struct Heap_Block* block;
|
struct Heap_Block* code_block_1;
|
||||||
void* code_page = alloc_page(1, &block);
|
struct Heap_Block* data_block_1;
|
||||||
void* data_page = alloc_page(1, &block);
|
|
||||||
|
|
||||||
set_page_table_entry(0, code_page);
|
alloc_page(2, &code_block_1);
|
||||||
set_page_table_entry(0x00400000, data_page);
|
alloc_page(2, &data_block_1);
|
||||||
|
|
||||||
*(int*)0 = 1;
|
struct Heap_Block* code_block_2;
|
||||||
|
struct Heap_Block* data_block_2;
|
||||||
|
|
||||||
while (true) { }
|
alloc_page(2, &code_block_2);
|
||||||
|
alloc_page(2, &data_block_2);
|
||||||
|
|
||||||
/* asm("cli");
|
// set_page_table_entry(0, code_page);
|
||||||
|
// set_page_table_entry(0x00400000, data_page);
|
||||||
|
|
||||||
run_program(program, sizeof(program), data, sizeof(data));
|
run_program(program, sizeof(program), data1, sizeof(data1), code_block_1, data_block_1);
|
||||||
|
run_program(program, sizeof(program), data2, sizeof(data2), code_block_2, data_block_2);
|
||||||
|
|
||||||
asm("sti");
|
asm("sti");
|
||||||
asm("int $0x20");
|
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
i += 1;
|
i += 1;
|
||||||
if (i == 1 << 16) {
|
if (i == 1 << 1) {
|
||||||
asm("mov %0, %%eax" :: "r" (kernel_data) );
|
asm("mov $0, %%ecx; int $0x80" :: "a" (kernel_data), "b" (sizeof(kernel_data)));
|
||||||
asm("mov $0, %ecx");
|
|
||||||
asm("int $0x80");
|
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
} */
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
#include <kernel/io/keyboard.h>
|
#include <kernel/io/keyboard.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
|
#include <kernel/heap.h>
|
||||||
|
|
||||||
static void print(char* buffer)
|
static void print(char* buffer, size_t length)
|
||||||
{
|
{
|
||||||
terminal_writestring(buffer);
|
terminal_writestring(buffer);
|
||||||
}
|
}
|
||||||
|
@ -23,14 +24,14 @@ static void input(char* buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _syscall(uint32_t a, uint32_t b, uint32_t c)
|
void _syscall(size_t a, size_t b, size_t c)
|
||||||
{
|
{
|
||||||
switch (c) {
|
// switch (c) {
|
||||||
case 0x00:
|
// case 0x00:
|
||||||
print((char*) a);
|
print((char*) a, b);
|
||||||
break;
|
// break;
|
||||||
case 0x01:
|
// case 0x01:
|
||||||
input((char*) a);
|
// input((char*) a);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <kernel/heap.h>
|
#include <kernel/heap.h>
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
|
#include <kernel/paging.h>
|
||||||
|
|
||||||
struct Task* tasks;
|
struct Task* tasks;
|
||||||
size_t tasks_capacity;
|
size_t tasks_capacity;
|
||||||
|
@ -14,13 +15,14 @@ void setup_tasks()
|
||||||
tasks = malloc(sizeof(*tasks));
|
tasks = malloc(sizeof(*tasks));
|
||||||
tasks[0].state.cs = 8;
|
tasks[0].state.cs = 8;
|
||||||
tasks[0].state.ds = 16;
|
tasks[0].state.ds = 16;
|
||||||
|
tasks[0].needs_pages = false;
|
||||||
tasks_capacity = 1;
|
tasks_capacity = 1;
|
||||||
num_tasks = 1;
|
num_tasks = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_task(struct Task task)
|
void add_task(struct Task task)
|
||||||
{
|
{
|
||||||
asm("cli");
|
// asm("cli");
|
||||||
if (num_tasks == tasks_capacity) {
|
if (num_tasks == tasks_capacity) {
|
||||||
struct Task* temp = malloc(sizeof(*tasks) * tasks_capacity * 2);
|
struct Task* temp = malloc(sizeof(*tasks) * tasks_capacity * 2);
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ void add_task(struct Task task)
|
||||||
|
|
||||||
tasks[num_tasks] = task;
|
tasks[num_tasks] = task;
|
||||||
num_tasks++;
|
num_tasks++;
|
||||||
asm("sti");
|
// asm("sti");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ss;
|
size_t ss;
|
||||||
|
@ -104,7 +106,8 @@ static void save_state(
|
||||||
current_task %= num_tasks;
|
current_task %= num_tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void next_task() {
|
void next_task()
|
||||||
|
{
|
||||||
struct CPUState s = tasks[current_task].state;
|
struct CPUState s = tasks[current_task].state;
|
||||||
|
|
||||||
ss = s.ds;
|
ss = s.ds;
|
||||||
|
@ -116,6 +119,15 @@ void next_task() {
|
||||||
print_hex_bytes(&tasks[current_task].state.eip, 4);
|
print_hex_bytes(&tasks[current_task].state.eip, 4);
|
||||||
terminal_writestring("\n");
|
terminal_writestring("\n");
|
||||||
|
|
||||||
|
if (tasks[current_task].needs_pages) {
|
||||||
|
set_page_directory_entry(0x00400000, tasks[current_task].code->data + 4096);
|
||||||
|
set_page_directory_entry(0x00800000, tasks[current_task].data->data + 4096);
|
||||||
|
set_page_table_entry(0x00400000, tasks[current_task].code->data);
|
||||||
|
set_page_table_entry(0x00800000, tasks[current_task].data->data);
|
||||||
|
asm(" movl %cr3,%eax; \
|
||||||
|
movl %eax,%cr3;");
|
||||||
|
}
|
||||||
|
|
||||||
if ((cs & 3) == 0) {
|
if ((cs & 3) == 0) {
|
||||||
jump_kernel(
|
jump_kernel(
|
||||||
s.edi,
|
s.edi,
|
||||||
|
|
Loading…
Reference in a new issue