Example #1
0
/** Load the previously selected program.
 *
 * @param rid
 * @param request
 * @return 0 on success, !0 on error.
 */
static int ldr_load(ipc_callid_t rid, ipc_call_t *request)
{
	int rc;
	
	rc = elf_load_file(pathname, 0, 0, &prog_info);
	if (rc != EE_OK) {
		DPRINTF("Failed to load executable '%s'.\n", pathname);
		async_answer_0(rid, EINVAL);
		return 1;
	}
	
	elf_create_pcb(&prog_info, &pcb);
	
	pcb.cwd = cwd;
	
	pcb.argc = argc;
	pcb.argv = argv;
	
	pcb.filc = filc;
	
	if (prog_info.interp == NULL) {
		/* Statically linked program */
		async_answer_0(rid, EOK);
		return 0;
	}
	
	DPRINTF("Binary is dynamically linked.\n");
#ifdef CONFIG_RTLD
	DPRINTF(" - pcb address: %p\n", &pcb);
	DPRINTF( "- prog dynamic: %p\n", prog_info.dynamic);

	rc = ldr_load_dyn_linked(&prog_info);
#else
	rc = ENOTSUP;
#endif
	async_answer_0(rid, rc);
	return 0;
}
Example #2
0
struct thread *init(struct multiboot *mboot, uint32_t mboot_magic) {
	struct process *idle, *init;
	struct module *module;
	struct memory_map *mem_map;
	size_t mem_map_count, i, addr;
	uintptr_t boot_image_size;
	void *boot_image;
	struct elf32_ehdr *init_image;
	struct elf32_ehdr *dl_image;

	/* initialize debugging output */
	debug_init();
	debug_printf("Rhombus Operating System Kernel v0.8a\n");

	/* check multiboot header */
	if (mboot_magic != 0x2BADB002) {
		debug_panic("bootloader is not multiboot compliant");
	}

	/* touch pages for the kernel heap */
	for (i = KSPACE; i < KERNEL_HEAP_END; i += SEGSZ) {
		page_touch(i);
	}

	/* identity map kernel boot frames */
	for (i = KSPACE + KERNEL_BOOT; i < KSPACE + KERNEL_BOOT_END; i += PAGESZ) {
		page_set(i, page_fmt(i - KSPACE, PF_PRES | PF_RW));
	}

	/* parse the multiboot memory map to find the size of memory */
	mem_map       = (void*) (mboot->mmap_addr + KSPACE);
	mem_map_count = mboot->mmap_length / sizeof(struct memory_map);

	for (i = 0; i < mem_map_count; i++) {
		if (mem_map[i].type == 1 && mem_map[i].base_addr_low <= 0x100000) {
			for (addr = 0; addr < mem_map[i].length_low; addr += PAGESZ) {
				frame_add(mem_map[i].base_addr_low + addr);
			}
		}
	}

	/* bootstrap process 0 (idle) */
	idle = process_alloc();
	idle->space = cpu_get_cr3();
	idle->user  = 0;

	/* fork process 1 (init) and switch */
	init = process_clone(idle, NULL);
	process_switch(init);

	/* get multiboot module information */
	if (mboot->mods_count < 3) {
		if (mboot->mods_count < 2) {
			if (mboot->mods_count < 1) {
				debug_panic("no boot or init or dl modules found");
			}
			else {
				debug_panic("no boot or dl modules found");
			}
		}
		else {
			debug_panic("no dl module found");
		}
	}
	module     = (void*) (mboot->mods_addr + KSPACE);
	init_image = (void*) (module[0].mod_start + KSPACE);
	boot_image = (void*) (module[1].mod_start + KSPACE);
	dl_image   = (void*) (module[2].mod_start + KSPACE);
	boot_image_size = module[1].mod_end - module[1].mod_start;

	/* move boot image to BOOT_IMAGE in userspace */
	mem_alloc(BOOT_IMAGE, boot_image_size, PF_PRES | PF_USER | PF_RW);
	memcpy((void*) BOOT_IMAGE, boot_image, boot_image_size);

	/* bootstrap thread 0 in init */
	thread_bind(init->thread[0], init);
	init->thread[0]->useresp = init->thread[0]->stack + SEGSZ;
	init->thread[0]->esp     = (uintptr_t) &init->thread[0]->num;
	init->thread[0]->ss      = 0x23;
	init->thread[0]->ds      = 0x23;
	init->thread[0]->cs      = 0x1B;
	init->thread[0]->eflags  = cpu_get_eflags() | 0x3200; /* IF, IOPL = 3 */

	/* bootstrap idle thread */
	idle->thread[0] = &__idle_thread;
	__idle_thread.proc = idle;

	/* load dl */
	if (elf_check_file(dl_image)) {
		debug_panic("dl.so is not a valid ELF executable");
	}
	elf_load_file(dl_image);

	/* execute init */
	if (elf_check_file(init_image)) {
		debug_panic("init is not a valid ELF executable");
	}
	elf_load_file(init_image);
	init->thread[0]->eip = init_image->e_entry;

	/* register system calls */
	int_set_handler(SYSCALL_SEND, syscall_send);
	int_set_handler(SYSCALL_DONE, syscall_done);
	int_set_handler(SYSCALL_WHEN, syscall_when);
	int_set_handler(SYSCALL_RIRQ, syscall_rirq);
	int_set_handler(SYSCALL_ALSO, syscall_also);
	int_set_handler(SYSCALL_STAT, syscall_stat);
	int_set_handler(SYSCALL_PAGE, syscall_page);
	int_set_handler(SYSCALL_PHYS, syscall_phys);
	int_set_handler(SYSCALL_FORK, syscall_fork);
	int_set_handler(SYSCALL_EXIT, syscall_exit);
	int_set_handler(SYSCALL_STOP, syscall_stop);
	int_set_handler(SYSCALL_WAKE, syscall_wake);
	int_set_handler(SYSCALL_GPID, syscall_gpid);
	int_set_handler(SYSCALL_TIME, syscall_time);
	int_set_handler(SYSCALL_USER, syscall_user);
	int_set_handler(SYSCALL_AUTH, syscall_auth);
	int_set_handler(SYSCALL_PROC, syscall_proc);
	int_set_handler(SYSCALL_KILL, syscall_kill);
	int_set_handler(SYSCALL_VM86, syscall_vm86);
	int_set_handler(SYSCALL_NAME, syscall_name);
	int_set_handler(SYSCALL_REAP, syscall_reap);

	/* register fault handlers */
	int_set_handler(FAULT_DE, fault_float);
	int_set_handler(FAULT_DB, fault_generic);
	int_set_handler(FAULT_NI, fault_generic);
	int_set_handler(FAULT_BP, fault_generic);
	int_set_handler(FAULT_OF, fault_generic);
	int_set_handler(FAULT_BR, fault_generic);
	int_set_handler(FAULT_UD, fault_generic);
	int_set_handler(FAULT_NM, fault_nomath);
	int_set_handler(FAULT_DF, fault_double);
	int_set_handler(FAULT_CO, fault_float);
	int_set_handler(FAULT_TS, fault_generic);
	int_set_handler(FAULT_NP, fault_generic);
	int_set_handler(FAULT_SS, fault_generic);
	int_set_handler(FAULT_GP, fault_gpf);
	int_set_handler(FAULT_PF, fault_page);
	int_set_handler(FAULT_MF, fault_float);
	int_set_handler(FAULT_AC, fault_generic);
	int_set_handler(FAULT_MC, fault_generic);
	int_set_handler(FAULT_XM, fault_nomath);

	/* start timer (for preemption) */
	timer_set_freq(64);

	/* initialize FPU/MMX/SSE */
	cpu_init_fpu();

	/* drop to usermode, scheduling the next thread */
	debug_printf("dropping to usermode\n");
	return thread_switch(NULL, schedule_next());
}