114 lines
2.7 KiB
C
114 lines
2.7 KiB
C
#include <process.h>
|
|
#include <utils.h>
|
|
#include <errcode.h>
|
|
#include <logger.h>
|
|
#include <thread.h>
|
|
#include <kmalloc.h>
|
|
#include <mman.h>
|
|
#include <exec.h>
|
|
#include <initrd.h>
|
|
#include <string.h>
|
|
#include <interrupt.h>
|
|
|
|
int32_t global_pid_counter = 0;
|
|
|
|
static inline
|
|
process_t *_make_process(const char *filename)
|
|
{
|
|
process_t *ret = kmalloc(sizeof(process_t));
|
|
|
|
file_node_t *file = initrd_get(initrd_root, filename);
|
|
if (file == 0x0)
|
|
panic(ERR_NOT_EXIST);
|
|
|
|
*ret = (process_t){
|
|
.pid = global_pid_counter++,
|
|
.th = 0x0,
|
|
|
|
.exitcode = 0,
|
|
|
|
.stack = allocate_page(256),
|
|
.stack_size = 256 << 12,
|
|
|
|
.mem = allocate_page(256),
|
|
.mem_size = 256 << 12,
|
|
|
|
.regs = kmalloc(sizeof(trapframe_t)),
|
|
};
|
|
memcpy(ret->mem, file->filecontent, file->filesize);
|
|
memset(ret->regs, 0x0, sizeof(trapframe_t));
|
|
*ret->regs = (trapframe_t){
|
|
.spsr_el1 = 0x0, // enable all interrupt
|
|
.elr_el1 = (uint64_t)ret->mem,
|
|
.sp_el0 = ((uint64_t)ret->stack + ret->stack_size - 64),
|
|
};
|
|
|
|
return ret;
|
|
}
|
|
|
|
// void run_process_by_name(const char *filename)
|
|
int32_t run_process_by_name(uint64_t param)
|
|
{
|
|
const char *filename = (void *)param;
|
|
thread_t *th = get_current();
|
|
|
|
th->process = _make_process(filename);
|
|
th->process->th = th;
|
|
LOG("Run process by name"); DEBUG_THREAD(filename);
|
|
LOG(th->process->stack); DEBUG_THREAD(th->process->regs->sp_el0);
|
|
LOG(th->process->mem); DEBUG_THREAD(th->process->regs->elr_el1);
|
|
|
|
disable_interrupt();
|
|
user_exec(th->process->regs);
|
|
|
|
__builtin_unreachable();
|
|
return 0;
|
|
}
|
|
|
|
// void run_process(process_t *)
|
|
int32_t run_process(uint64_t param)
|
|
{
|
|
process_t *process = (void *)param;
|
|
thread_t *th = get_current();
|
|
|
|
th->process = process;
|
|
th->process->th = th;
|
|
LOG("Run process"); DEBUG_THREAD(process->pid);
|
|
|
|
disable_interrupt();
|
|
user_exec(th->process->regs);
|
|
|
|
__builtin_unreachable();
|
|
return 0;
|
|
}
|
|
|
|
process_t *fork_process(const process_t *from)
|
|
{
|
|
process_t *ret = kmalloc(sizeof(process_t));
|
|
*ret = (process_t){
|
|
.pid = global_pid_counter++,
|
|
.th = 0x0,
|
|
|
|
.exitcode = from->exitcode,
|
|
|
|
.stack = allocate_page(256),
|
|
.stack_size = 256 << 12,
|
|
|
|
.mem = allocate_page(256),
|
|
.mem_size = 256 << 12,
|
|
|
|
.regs = kmalloc(sizeof(trapframe_t)),
|
|
};
|
|
memcpy(ret->stack, from->stack, from->stack_size);
|
|
memcpy(ret->mem, from->mem, from->mem_size);
|
|
*ret->regs = (trapframe_t){
|
|
.x0 = 0, // fork return value
|
|
.fp = from->regs->fp - (uint64_t)from->stack + (uint64_t)ret->stack,
|
|
.lr = from->regs->lr - (uint64_t)from->mem + (uint64_t)ret->mem,
|
|
.sp_el0 = from->regs->sp_el0 - (uint64_t)from->stack + (uint64_t)ret->stack,
|
|
.elr_el1 = from->regs->elr_el1 - (uint64_t)from->mem + (uint64_t)ret->mem,
|
|
};
|
|
|
|
return ret;
|
|
}
|