void manager_jenkins() { #ifdef CONFIG_KERNEL_TESTING printk("<-- BEGIN_KERNEL_TESTS -->\n"); run_registered_ktest_suites(); printk("<-- END_KERNEL_TESTS -->\n"); #endif // Run userspace tests (from config specified path). #ifdef CONFIG_USERSPACE_TESTING if (strlen(CONFIG_USERSPACE_TESTING_SCRIPT) != 0) { char exec[] = "/bin/ash"; char *p_argv[] = {exec, CONFIG_USERSPACE_TESTING_SCRIPT, 0}; struct file *program = do_file_open(exec, 0, 0); struct proc *p = proc_create(program, p_argv, NULL); proc_wakeup(p); proc_decref(p); /* let go of the reference created in proc_create() */ kref_put(&program->f_kref); run_scheduler(); // Need a way to wait for p to finish } else { printk("No user-space launcher file specified.\n"); } #endif smp_idle(); assert(0); }
int load_elf(struct proc* p, struct file* f) { elf_info_t ei, interp_ei; if (load_one_elf(p, f, 0,& ei)) return -1; if (ei.dynamic) { struct file *interp = do_file_open(ei.interp, 0, 0); if (!interp) return -1; /* careful, this could conflict with the mmap from the TLS up above */ int error = load_one_elf(p, interp, 2, &interp_ei); kref_put(&interp->f_kref); if (error) return -1; } // fill in auxiliary info for dynamic linker/runtime elf_aux_t auxp[] = {{ELF_AUX_PHDR, ei.phdr}, {ELF_AUX_PHENT, sizeof(proghdr_t)}, {ELF_AUX_PHNUM, ei.phnum}, {ELF_AUX_ENTRY, ei.entry}, #ifdef __sparc_v8__ {ELF_AUX_HWCAP, ELF_HWCAP_SPARC_FLUSH}, #endif {0, 0}}; // put auxp after argv, envp in procinfo int auxp_pos = -1; for (int i = 0, zeros = 0; i < PROCINFO_MAX_ARGP; i++) if (p->procinfo->argp[i] == NULL) if (++zeros == 2) auxp_pos = i + 1; if (auxp_pos == -1 || auxp_pos + sizeof(auxp) / sizeof(char*) >= PROCINFO_MAX_ARGP) return -1; memcpy(p->procinfo->argp+auxp_pos,auxp,sizeof(auxp)); uintptr_t core0_entry = ei.dynamic ? interp_ei.entry : ei.entry; proc_init_trapframe(&p->env_tf,0,core0_entry,USTACKTOP); p->env_entry = ei.entry; // map in stack using POPULATE (because SPARC requires it) uintptr_t stacksz = USTACK_NUM_PAGES*PGSIZE; if (do_mmap(p, USTACKTOP-stacksz, stacksz, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_POPULATE, NULL, 0) == MAP_FAILED) return -1; // Set the heap bottom and top to just past where the text // region has been loaded p->heap_top = (void*)ei.highest_addr; p->procinfo->heap_bottom = p->heap_top; return 0; }
/* TODO: consider making this only deal with the inode */ struct file *make_device(char *path, int mode, int type, struct file_operations *fop) { struct file *f_dev = do_file_open(path, O_CREAT | O_RDWR, mode); assert(f_dev); /* Overwrite the f_op with our own f_ops */ f_dev->f_dentry->d_inode->i_fop = fop; f_dev->f_op = fop; SET_FTYPE(f_dev->f_dentry->d_inode->i_mode, type); return f_dev; }