示例#1
0
int
mon_start_user (int argc, char **argv, struct Trapframe *tf)
{
	if (CID != 0)
	{
		dprintf(
			"The process is already running. If you want to run the program again, please restart qemu.\n");
		return 0;
	}
	uint8_t * exe = _binary___obj_proc_dummy_dummy_start;

	CID = alloc_mem_quota (0, 1024 * 1024);

	elf_load (exe, CID);

	dprintf("Program 0x%08x is loaded.\n", exe);

	set_pdir_base (CID);

	entry_t entry = (entry_t) elf_entry (exe);

	entry();

	return 0;
}
示例#2
0
unsigned int proc_create(void *elf_addr, unsigned int quota)
{
  unsigned int pid, id;

  id = get_curid();
  pid = thread_spawn((void *) proc_start_user, id, quota);

  elf_load(elf_addr, pid);

  uctx_pool[pid].es = CPU_GDT_UDATA | 3;
  uctx_pool[pid].ds = CPU_GDT_UDATA | 3;
  uctx_pool[pid].cs = CPU_GDT_UCODE | 3;
  uctx_pool[pid].ss = CPU_GDT_UDATA | 3;
  uctx_pool[pid].esp = VM_USERHI;
  uctx_pool[pid].eflags = FL_IF;
  uctx_pool[pid].eip = elf_entry(elf_addr);

  seg_init_proc(get_pcpu_idx(), pid);
  
  return pid;
}
示例#3
0
文件: exec.c 项目: OXKernel/ox
int kexecve(const char *filename, char *const argv[],
                  char *const envp[])
{
    // If first line is #! exec interpreter and feed
    // it the command line options and the file.
    // Otherwise, load the entire file into RAM,
    // and call image_load.
    // On error, return -1 and set errno.
    // On success, no return (0).
    // The latter implies we have to setup the process context
    // and free prior RAM.
    char        *image      = NULL;
    unsigned int image_size = 0;
    unsigned int i          = 0;
    unsigned int j          = 0;
    unsigned int start      = 0;
    unsigned int end        = 0;
    unsigned int len        = 0;
    int argc                = 0;
    char interpreter[MAX_PATH]  = {0};
    char args[MAX_PATH]         = {0};
    char *arg               = NULL;
    char **argv2            = NULL;
    static int nr_recursion = 0;
    int delete_argv2        = 0;
    start_t elf_entry       = NULL;
    unsigned char *exec     = NULL;
    unsigned int exec_size  = 0;

    asm_disable_interrupt();

    if(!file_load(filename, &image, &image_size)) {
        printk("execve:: error loading file\n");
        asm_enable_interrupt();
        return -1;
    }

    // TODO - We should store argv2 in the process and
    //        and mark if it should be free'd on exit.

    // Handle interpreter invocation.
    if(image[0] == '#' && image[1] == '!') {
#ifdef _TEST_EXEC
        printk("execve:: image = [%s]\n", image);
#endif
        for(i = 2; i < image_size; ++i) {
            if(!isspace(image[i])) {
                start = i;
                break;
            }
        }
        for(i = start + 1; i < image_size; ++i) {
            if(isspace(image[i])) {
                end = i;
                break;
            }
        }
        for(i = start,j=0; i < end; ++i,++j) {
            if(j >= MAX_PATH) {
                printk("execve:: interpreter name too long\n");
                asm_enable_interrupt();
                return -1;
            }
            interpreter[j] = image[i];
        }
        for(i = end,j=0; i < image_size; ++i,++j) {
            if(image[i]=='\n') {
                break;
            }
            args[j]=image[i];
        }
        arg = strtok(args," \t");
        i   = 0;
        while(arg) {
            if(!argv2) {
                argv2 = (char **)malloc(sizeof(char *) * MAX_PATH + 1);
            }
            if(i >= MAX_PATH) {
                free((void *)argv2);
                printk("execve:: error processing interpreter args\n");
                asm_enable_interrupt();
                return -1;
            }
            len = strlen(arg);
            argv2[i] = (char *)malloc(len + 1);
            strcpy(argv2[i],arg);
            argv2[i][len]='\0';
            ++i;
            arg = strtok(NULL," \t");
        }
        /* Now get the rest of the args. */
        j = 0;
        while(i < MAX_PATH && argv[j]) {
            len = strnlen(argv[j],1024);
            argv2[i] = (char *)malloc(len + 1);
            strncpy(argv2[i],argv[j],1024);
            argv2[i][len] = '\0';
            ++i;
            ++j;
        }

        if(argv[j] != NULL) {
            free((void *)argv2);
            printk("execve:: error argv[j] != NULL\n");
            asm_enable_interrupt();
            return -1;
        }

        /* Now copy the script filename. */
        if(i >= MAX_PATH) {
            free((void *)argv2);
            printk("execve:: error i >= MAX_PATH\n");
            asm_enable_interrupt();
            return -1;
        }
#if 0
        /* argv[0] should be the filename */
        len = strlen(filename);
        argv2[i] = (char *)malloc(len + 1);
        strcpy(argv2[i],filename);
        argv2[i][len]='\0';
        ++i;
        if(i >= MAX_PATH) {
            free((void *)argv2);
            printk("execve:: error i >= MAX_PATH[2]\n");
            return -1;
        }
#endif
        argv2[i]='\0';
        // Free the original file loaded.
        if(!file_unload(&image)) {
            free((void *)argv2);
            printk("execve:: error unloading file [%s]\n",filename);
            asm_enable_interrupt();
            return -1;
        }

#ifdef _TEST_EXEC
        printk("interpreter [%s]\n",interpreter);
        for(i = 0; argv2[i]; ++i) {
            printk("argv2[%d]=[%s]\n",i,argv2[i]);
        }
        for(i = 0; envp[i]; ++i) {
            printk("envp[%d]=[%s]\n",i,envp[i]);
        }
        return 0;
#else
        // Call ourselves with the proper paramters.
        if(nr_recursion > EXEC_MAX_RECURSION) {
            printk("execve:: error nr_recursion > EXEC_MAX_RECURSION\n");
            asm_enable_interrupt();
            return -1;
        }
        nr_recursion++;
        asm_enable_interrupt();
        return kexecve(interpreter, argv2, envp);
#endif
    }

    // If we are in a recursive call, then we
    // allocated argv2 and it must be free'd.
    if(nr_recursion) {
        delete_argv2 = 1;
    } else {
        delete_argv2 = 0;
        argv2 = (char **)argv;
    }
    for(i = 0; argv2[i]; ++i) {
        argc++;
    }
    nr_recursion--;
    // At this point, the ELF image is in RAM.
    // Parse it out and jump to it.
    LINE();
    elf_entry = image_load(image, image_size, &exec, &exec_size);
    LINE();

    // TODO - Do we put envp into the process struct
    //        and make it accessible via getenv() ?
#ifdef _TEST_EXEC
    printk("elf_entry=[%x]\n",elf_entry);
    LINE();
    i = elf_entry();
    printk("returns =[%d]\n",i);
#endif
    LINE();

    if(!file_unload(&image)) {
        if(nr_recursion) {
            for(i = 0; i < argc; ++i) {
                free((void *)argv2[i]);
            }
            free((void *)argv2);
        }
#ifdef _TEST_EXEC
        munmap(elf_entry, image_size);
#endif
        printk("execve:: error unloading file [%s]\n",filename);
        return -1;
    }
#ifdef _TEST_EXEC
        munmap(exec,exec_size);
#else // Kernel
    //
    // - Set up the entry point and args
    // into the process structure...
    // Mark flag for first time execution
    // as we need to call into the entry point
    // when we schedule the process.
    // - Free the old process image...
    //
    // We have:-
    //
    // exec         - memory image to free 
    // exec_size    - size of image
    // elf_entry    - pointer to the start method
    // argc         - argument count
    // argv2        - arguments
    // envp         - environment
    // delete_argv2 - flag to indicate if argv2 should be free'd
    //
    // Free up prior memory.
    // Should also happen in exit.c.
    if(current_process->p_exec) {
        mem_unset_read_only(current_process->p_exec,
                            current_process->p_exec_size);
        free((void *)current_process->p_exec);
    }
    if(current_process->p_delete_argv) {
        for(i = 0; i < current_process->p_argc; ++i) {
            free((void *)current_process->p_argv[i]);
        }
        free((void *)current_process->p_argv);
    }
    // Close all open files.
    for(i = 0; i < MAX_FILES; ++i) {
        for(j = 0; j < MAX_FILES; ++j) {
            if(current_process->file_desc[i] == 
               &(current_process->file_tab[j])) {
                kclose(i);
            }
        }
    }
    // Close all open directories.
    for(i = 0; i < MAX_DIR; ++i) {
        if(current_process->dir_tab[i].__allocation == DEV_BLOCK_SIZE) {
            kclosedir(&(current_process->dir_tab[i])); 
        }
    }
    // Setup our new image.
    current_process->p_exec         = exec;
    current_process->p_exec_size    = exec_size;
    current_process->p_elf_entry    = elf_entry;
    current_process->p_argc         = argc;
    current_process->p_argv         = argv2;
    current_process->p_envp         = envp;
    current_process->p_delete_argv  = delete_argv2;
    current_process->p_first_exec   = 1;
    asm_enable_interrupt();
    schedule();
#endif
    return 0;

}/* kexecve */