Multi-user multitasking

This commit is contained in:
vanten-s 2025-07-02 13:35:14 +02:00
parent 582f4b720f
commit b87bb2f228
Signed by: vanten-s
GPG key ID: DE3060396884D3F2
9 changed files with 73 additions and 44 deletions

View file

@ -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++;

View file

@ -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);

View file

@ -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);

View file

@ -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(

View file

@ -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);

View file

@ -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;
} }

View file

@ -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;
} }
} */ }
} }

View file

@ -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;
} // }
} }

View file

@ -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,