Load TAR archive + run raw user program
This commit is contained in:
+44
-4
@@ -222,10 +222,6 @@ void process_jump_to_user(uintptr_t stack_top, uintptr_t user_code)
|
||||
" :: "r"(stack_top), "r"(user_code));
|
||||
}
|
||||
|
||||
// Kernel stack used for interrupts from userland process.
|
||||
// Should be set in TSS.RSP0 when switching to userland process.
|
||||
uint8_t interrupt_stack[0x8000];
|
||||
|
||||
extern struct tss tss;
|
||||
|
||||
/*
|
||||
@@ -276,6 +272,50 @@ void process_create_user(struct limine_file* file, char* name)
|
||||
memcpy((uint64_t*)code, exec_addr, exec_size);
|
||||
load_cr3(VIRT_TO_PHYS((uint64_t)kernel_pml4));
|
||||
|
||||
process_add(&processes_list, proc);
|
||||
DEBUG("user process '%s' (pid=%u) enqueued for scheduling", name, proc->pid);
|
||||
SET_INTERRUPTS;
|
||||
}
|
||||
|
||||
// Same as above but for a raw data pointer (pointing to raw binary, no ELF)
|
||||
void process_create_user_raw(char* file, int size, char* name)
|
||||
{
|
||||
CLEAR_INTERRUPTS;
|
||||
struct process* proc = (struct process*)kmalloc(sizeof(struct process));
|
||||
struct cpu_status* ctx = (struct cpu_status*)kmalloc(sizeof(struct cpu_status));
|
||||
|
||||
if (!proc || !ctx) panic(NULL, "out of memory while creating user process");
|
||||
|
||||
strncpy(proc->name, name, PROCESS_NAME_MAX);
|
||||
memset(ctx, 0, sizeof(struct cpu_status)); // set GP registers to zero
|
||||
proc->pid = next_free_pid++;
|
||||
proc->status = READY;
|
||||
proc->next = 0;
|
||||
proc->context = ctx;
|
||||
proc->context->iret_ss = USER_DATA_SEGMENT | 3;
|
||||
proc->context->iret_cs = USER_CODE_SEGMENT | 3;
|
||||
proc->context->iret_flags = 0x202; // Interrupt Flag set
|
||||
|
||||
void* exec_addr = (void*)file;
|
||||
uint64_t exec_size = size;
|
||||
|
||||
uint64_t* user_pml4 = vmm_create_address_space();
|
||||
if (!user_pml4) panic(NULL, "failed to create user address space");
|
||||
proc->root_page_table = user_pml4;
|
||||
|
||||
uintptr_t stack_top = vmm_alloc_user_stack(user_pml4);
|
||||
uint64_t code = vmm_alloc_user_code(user_pml4, exec_addr, exec_size);
|
||||
|
||||
proc->context->iret_rsp = stack_top;
|
||||
proc->context->iret_rip = code;
|
||||
proc->kernel_stack = kalloc_stack();
|
||||
if (!proc->kernel_stack) panic(NULL, "failed to allocate kernel stack");
|
||||
|
||||
// Copy code into user pages; for that we need to temporarily switch to the user pml4
|
||||
load_cr3(VIRT_TO_PHYS((uint64_t)user_pml4));
|
||||
memcpy((uint64_t*)code, exec_addr, exec_size);
|
||||
load_cr3(VIRT_TO_PHYS((uint64_t)kernel_pml4));
|
||||
|
||||
process_add(&processes_list, proc);
|
||||
DEBUG("user process '%s' (pid=%u) enqueued for scheduling", name, proc->pid);
|
||||
SET_INTERRUPTS;
|
||||
|
||||
Reference in New Issue
Block a user