示例#1
0
sc_addr sc_generator::enter_system(const char *idtf,sc_type type,sc_segment *segment)
{
	sc_addr el = generate_find_internal(idtf,type,segment);
	if (!el)
		return 0;
	return enter_system(el);
}
示例#2
0
/* This is the C kernel entry point */
void kmain(struct multiboot *mboot_header, addr_t initial_stack)
{
	/* Store passed values, and initiate some early things
	 * We want serial log output as early as possible */
	kernel_state_flags=0;
	mtboot = mboot_header;
	i_stack = initial_stack;
	parse_kernel_elf(mboot_header, &kernel_elf);
#if CONFIG_MODULES
	init_kernel_symbols();
#endif
	init_serial();
	console_init_stage1();
	load_tables();
	puts("~ SeaOS Version ");	
	char ver[32];
	get_kernel_version(ver);
	puts(ver);
	puts(" Booting Up ~\n\r");
#if CONFIG_MODULES
	init_module_system();
#endif
	init_syscalls();
	load_initrd(mtboot);
	install_timer(1000);
	pm_init(placement, mtboot);
	init_main_cpu_1();

	/* Now get the management stuff going */
	printk(1, "[kernel]: Starting system management\n");
	init_memory(mtboot);
	init_main_cpu_2();
	console_init_stage2();
	parse_kernel_cmd((char *)(addr_t)mtboot->cmdline);
	init_multitasking();
	init_cache();
	init_dm();
	init_vfs();
	/* Load the rest... */
	process_initrd();
	init_kern_task();
	get_timed(&kernel_start_time);
	printk(KERN_MILE, "[kernel]: Kernel is setup (%2.2d:%2.2d:%2.2d, %s, kv=%d, ts=%d bytes: ok)\n", 
	       kernel_start_time.tm_hour, kernel_start_time.tm_min, 
	       kernel_start_time.tm_sec, kernel_name, KVERSION, sizeof(task_t));
	assert(!set_int(1));
	if(!fork())
		init();
	sys_setsid();
	enter_system(255);
	kernel_idle_task();
}
示例#3
0
int syscall_handler(volatile registers_t *regs)
{
	/* SYSCALL_NUM_AND_RET is defined to be the correct register in the syscall regs struct. */
	if(unlikely(SYSCALL_NUM_AND_RET >= num_syscalls))
		return -ENOSYS;
	if(unlikely(!syscall_table[SYSCALL_NUM_AND_RET]))
		return -ENOSYS;
	volatile long ret;
	if(!check_pointers(regs))
		return -EINVAL;
	if(kernel_state_flags & KSF_SHUTDOWN)
		for(;;);
	//if(got_signal(current_task) || (unsigned)(ticks-current_task->slice) > (unsigned)current_task->cur_ts)
	//	schedule();
	enter_system(SYSCALL_NUM_AND_RET);
	/* most syscalls are re-entrant, so we enable interrupts and
	 * expect handlers to disable them if needed */
	set_int(1);
	/* start accounting information! */
	current_task->freed = current_task->allocated=0;
	
	#ifdef SC_DEBUG
	if(current_task->tty == curcons->tty) 
		printk(SC_DEBUG, "syscall %d: enter %d\n", current_task->pid, SYSCALL_NUM_AND_RET);
	int or_t = ticks;
	#endif
	__do_syscall_jump(ret, syscall_table[SYSCALL_NUM_AND_RET], _E_, _D_, 
					  _C_, _B_, _A_);
	#ifdef SC_DEBUG
	if(current_task->tty == curcons->tty && (ticks - or_t >= 10 || 1) 
		&& (ret < 0 || 1) && (ret == -EINTR || 1))
		printk(SC_DEBUG, "syscall %d: %d ret %d, took %d ticks\n", 
			   current_task->pid, current_task->system, ret, ticks - or_t);
		#endif
		
	set_int(0);
	exit_system();
	__engage_idle();
	/* if we need to reschedule, or we have overused our timeslice
	 * then we need to reschedule. this prevents tasks that do a continuous call
	 * to write() from starving the resources of other tasks. syscall_count resets
	 * on each call to schedule() */
	if(current_task->flags & TF_SCHED 
		|| (unsigned)(ticks-current_task->slice) > (unsigned)current_task->cur_ts
		|| ++current_task->syscall_count > 2)
	{
		/* clear out the flag. Either way in the if statement, we've rescheduled. */
		lower_flag(TF_SCHED);
		schedule();
	}
	/* store the return value in the regs */
	SYSCALL_NUM_AND_RET = ret;
	/* if we're going to jump to a signal here, we need to back up our 
	 * return value so that when we return to the system we have the
	 * original systemcall returning the proper value.
	 */
	if((current_task->flags & TF_INSIG) && (current_task->flags & TF_JUMPIN)) {
#if CONFIG_ARCH == TYPE_ARCH_X86
		current_task->reg_b.eax=ret;
#elif CONFIG_ARCH == TYPE_ARCH_X86_64
		current_task->reg_b.rax=ret;
#endif
		lower_flag(TF_JUMPIN);
	}
	return ret;
}