void create_kernel_process(uint64_t *proc_addr) { process_t *proc = allocate_process(-1); if (!proc) { #ifdef LOG printf("Error: No free slot in process list \n"); #endif return; } proc->page_table_base = (uint64_t*)phys_kernel_level4; proc->registers.rsp = (uint64_t)dummyStack + PGSIZE - 8; proc->registers.rip = (uint64_t)proc_addr; proc->registers.fs = GDT_KERNEL_DS; proc->registers.ds = GDT_KERNEL_DS; proc->registers.es = GDT_KERNEL_DS; proc->registers.gs = GDT_KERNEL_DS; proc->registers.ss = GDT_KERNEL_DS; proc->registers.cs = GDT_KERNEL_CS; proc->registers.rflags = FLAG_IF; proc->entry_point = proc_addr; }
ProcStruct* create_process(uint64_t* binary, enum ProcType type) { ProcStruct *NewProc=NULL; if((NewProc=allocate_process(0)) != NULL) { //printf("Allcated"); // uint64_t i=499999999; // while(i--); if(load_elf(NewProc,binary)==0) { // printf("Loaded"); NewProc->type =type; return NewProc; } } return NULL; }
//Initializes a process with its binary its argument process_t* create_process_new(void* binary, pid_t ppid, int new_pid, const char *proc_name, char * const argv[], size_t argv_count, char * const envp[], size_t envp_count) { uint64_t old_cr3 = 0; int32_t rc = 0; process_t *proc = allocate_process(new_pid); if (!proc) { #ifdef LOG printf("Failed to allocate memory for process\n"); #endif return NULL; } // First process will be foreground... Need to change this logic // May be this will work fine when we will be running just shell if (foreground_proc == NULL) { proc->flags |= FOREGROUND_PROCESS; foreground_proc = proc; } strncpy(proc->name, proc_name, sizeof(proc->name)); proc->kernel_stack = kmalloc(USER_KERNEL_STACK_SIZE); if(proc->kernel_stack == NULL) { reclaim_process_resources(proc); kfree(proc); #if LOG printf("failed to allocate memory for user-kern stack\n"); #endif return NULL; } rc = setup_pagetable_proc(proc); if (rc) { reclaim_process_resources(proc); kfree(proc); #ifdef LOG printf("setup_pagetable_proc failed\n"); #endif return NULL; } if (binary != NULL) { //If the process is child of some parent //So we don't need any binary rc = init_vmas_proc(proc, binary, argv_count, envp_count); } if (rc) { reclaim_process_resources(proc); kfree(proc); #ifdef LOG printf("init_vmas_proc failed\n"); #endif return NULL; } //Setup registers for the process setup_registers_proc(proc); // Allocate a page for stack // Why we are not going for demand paging? // We need to push env variables' addresses on stack while we are in kernel // and it's not a good idea to have a page fault in kernel if (binary != NULL) { //Don't allocate page for stack because it's a child. allocate_memory((uint64_t)proc->page_table_base, USER_STACK_TOP - PGSIZE, PGSIZE, PTE_P | PTE_U | PTE_W); } // This function should be last in this sequence since it uses rsp // which we set in setup_registers_proc if (binary != NULL) { if (argv_count > 0) { allocate_memory((uint64_t)proc->page_table_base, USER_ARGV_START, argv_count * sizeof(execve_argv[0]), PTE_P | PTE_U | PTE_W); old_cr3 = getcr3(); setcr3((uint64_t)proc->page_table_base); memcpy((void *)USER_ARGV_START, argv, argv_count * sizeof(execve_argv[0])); setcr3(old_cr3); } if (envp_count > 0) { allocate_memory((uint64_t)proc->page_table_base, USER_ENV_VARIABLE_START, envp_count * sizeof(execve_envp[0]), PTE_P | PTE_U | PTE_W); old_cr3 = getcr3(); setcr3((uint64_t)proc->page_table_base); memcpy((void *)USER_ENV_VARIABLE_START, envp, envp_count * sizeof(execve_envp[0])); setcr3(old_cr3); } setup_stack(proc, argv_count, envp_count); } add_process_to_queue(proc, PROCESS_RUNNABLE_QUEUE); proc->ppid = ppid; //printf("New process PID = %d\n", proc->pid); return proc; }