Scheduler: add a load_user_task function that directly loads a file from the initrd

This commit is contained in:
apio 2022-10-01 12:28:32 +02:00
parent 1c4383dea4
commit 66bee86a8b
3 changed files with 38 additions and 7 deletions

View File

@ -10,6 +10,8 @@ namespace Scheduler
void add_kernel_task(void (*task)(void));
void add_user_task(void* task);
void load_user_task(const char* filename);
void task_exit(Context* context);
void task_misbehave(Context* context);

View File

@ -126,13 +126,7 @@ extern "C" void _start()
}
});
void* elf_start_address = ELFLoader::load_elf_from_initrd("bin/init");
if (!elf_start_address) kerrorln("failed to load /bin/init from initrd");
else
{
kinfoln("loaded /bin/init at %lx", (uint64_t)elf_start_address);
Scheduler::add_user_task(elf_start_address);
}
Scheduler::load_user_task("bin/init");
kinfoln("Prepared scheduler tasks");

View File

@ -10,6 +10,7 @@
#include "panic/Panic.h"
#include "std/stdlib.h"
#include "std/string.h"
#include "sys/elf/ELFLoader.h"
#include "thread/PIT.h"
#include "thread/Task.h"
@ -110,6 +111,40 @@ void Scheduler::add_user_task(void* task)
new_task->id, new_task->regs.rsp, task_num);
}
void Scheduler::load_user_task(const char* filename)
{
kinfoln("Loading user task: %s", filename);
Task* new_task = new Task;
ASSERT(new_task);
new_task->id = free_tid++;
new_task->regs.rip = (uint64_t)ELFLoader::load_elf_from_initrd(filename);
if (!new_task->regs.rip)
{
kwarnln("Failed to load user task %s", filename);
delete new_task;
return;
}
new_task->allocated_stack = (uint64_t)MemoryManager::get_pages(
TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right?
new_task->regs.rsp = new_task->allocated_stack + (4096 * 4) - sizeof(uintptr_t);
new_task->regs.cs = 0x18 | 0x03;
new_task->regs.ss = 0x20 | 0x03;
new_task->regs.ds = 0x20 | 0x03;
new_task->regs.rflags = (1 << 21) | (1 << 9); // enable interrupts
new_task->task_sleep = 0;
new_task->task_time = 0;
new_task->cpu_time = 0;
end_task->next_task = new_task;
new_task->prev_task = end_task;
base_task->prev_task = new_task;
new_task->next_task = base_task;
end_task = new_task;
new_task->state = new_task->Running;
task_num++;
kinfoln("Adding user task: loaded at %lx, tid %ld, stack at %lx, total tasks: %ld", new_task->regs.rip,
new_task->id, new_task->regs.rsp, task_num);
}
void Scheduler::reap_task(Task* task)
{
ASSERT(!Interrupts::is_in_handler());