Load TAR archive + run raw user program

This commit is contained in:
2026-05-04 20:24:18 +02:00
parent e399ec6a46
commit ccb6ca89f1
10 changed files with 157 additions and 17 deletions
+44 -4
View File
@@ -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;