⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	extern void ret_from_fork(void);	unsigned long sp = (unsigned long)p + sizeof(union task_union);	unsigned long childframe;	/* Copy registers */	sp -= sizeof(struct pt_regs);	childregs = (struct pt_regs *) sp;	*childregs = *regs;	if ((childregs->msr & MSR_PR) == 0) {		/* for kernel thread, set `current' and stackptr in new task */		childregs->gpr[1] = sp + sizeof(struct pt_regs);		childregs->gpr[2] = (unsigned long) p;		p->thread.regs = NULL;	/* no user register state */	} else		p->thread.regs = childregs;	childregs->gpr[3] = 0;  /* Result from fork() */	sp -= STACK_FRAME_OVERHEAD;	childframe = sp;	/*	 * The way this works is that at some point in the future	 * some task will call _switch to switch to the new task.	 * That will pop off the stack frame created below and start	 * the new task running at ret_from_fork.  The new task will	 * do some house keeping and then return from the fork or clone	 * system call, using the stack frame created above.	 */	sp -= sizeof(struct pt_regs);	kregs = (struct pt_regs *) sp;	sp -= STACK_FRAME_OVERHEAD;	p->thread.ksp = sp;	kregs->nip = (unsigned long)ret_from_fork;	/*	 * copy fpu info - assume lazy fpu switch now always	 *  -- Cort	 */	if (regs->msr & MSR_FP) {		giveup_fpu(current);		childregs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);	}	memcpy(&p->thread.fpr, &current->thread.fpr, sizeof(p->thread.fpr));	p->thread.fpscr = current->thread.fpscr;#ifdef CONFIG_ALTIVEC	/*	 * copy altiVec info - assume lazy altiVec switch	 * - kumar	 */	if (regs->msr & MSR_VEC)		giveup_altivec(current);	memcpy(&p->thread.vr, &current->thread.vr, sizeof(p->thread.vr));	p->thread.vscr = current->thread.vscr;	childregs->msr &= ~MSR_VEC;#endif /* CONFIG_ALTIVEC */	p->thread.last_syscall = -1;	return 0;}/* * Set up a thread for executing a new program */void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp){	set_fs(USER_DS);	memset(regs->gpr, 0, sizeof(regs->gpr));	memset(&regs->ctr, 0, 5 * sizeof(regs->ctr));	regs->nip = nip;	regs->gpr[1] = sp;	regs->msr = MSR_USER;	if (last_task_used_math == current)		last_task_used_math = 0;	if (last_task_used_altivec == current)		last_task_used_altivec = 0;	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));	current->thread.fpscr = 0;#ifdef CONFIG_ALTIVEC	memset(current->thread.vr, 0, sizeof(current->thread.vr));	memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));	current->thread.vrsave = 0;#endif /* CONFIG_ALTIVEC */}/* * Support for the PR_GET/SET_FPEXC prctl() calls. */static inline unsigned int __unpack_fe01(unsigned int msr_bits){	return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);}static inline unsigned int __pack_fe01(unsigned int fpmode){	return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);}int set_fpexc_mode(struct task_struct *tsk, unsigned int val){	struct pt_regs *regs = tsk->thread.regs;	if (val > PR_FP_EXC_PRECISE)		return -EINVAL;	tsk->thread.fpexc_mode = __pack_fe01(val);	if (regs != NULL && (regs->msr & MSR_FP) != 0)		regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))			| tsk->thread.fpexc_mode;	return 0;}int get_fpexc_mode(struct task_struct *tsk, unsigned long adr){	unsigned int val;	val = __unpack_fe01(tsk->thread.fpexc_mode);	return put_user(val, (unsigned int *) adr);}int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,	      struct pt_regs *regs){	return do_fork(p1, p2, regs, 0);}int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,	     struct pt_regs *regs){	return do_fork(SIGCHLD, regs->gpr[1], regs, 0);}int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,	      struct pt_regs *regs){	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0);}int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,	       unsigned long a3, unsigned long a4, unsigned long a5,	       struct pt_regs *regs){	int error;	char * filename;	filename = getname((char *) a0);	error = PTR_ERR(filename);	if (IS_ERR(filename))		goto out;	if (regs->msr & MSR_FP)		giveup_fpu(current);#ifdef CONFIG_ALTIVEC	if (regs->msr & MSR_VEC)		giveup_altivec(current);#endif /* CONFIG_ALTIVEC */ 	error = do_execve(filename, (char **) a1, (char **) a2, regs);	if (error == 0)		current->ptrace &= ~PT_DTRACE;	putname(filename);out:	return error;}voidprint_backtrace(unsigned long *sp){	int cnt = 0;	unsigned long i;	if (sp == NULL)		asm("mr %0,1" : "=r" (sp));	printk("Call backtrace: ");	while (sp) {		if (__get_user( i, &sp[1] ))			break;		if (cnt++ % 7 == 0)			printk("\n");		printk("%08lX ", i);		if (cnt > 32) break;		if (__get_user(sp, (unsigned long **)sp))			break;	}	printk("\n");}void show_trace_task(struct task_struct *tsk){	unsigned long stack_top = (unsigned long) tsk + THREAD_SIZE;	unsigned long sp, prev_sp;	int count = 0;	if (tsk == NULL)		return;	sp = (unsigned long) &tsk->thread.ksp;	do {		prev_sp = sp;		sp = *(unsigned long *)sp;		if (sp <= prev_sp || sp >= stack_top || (sp & 3) != 0)			break;		if (count > 0)			printk("[%08lx] ", *(unsigned long *)(sp + 4));	} while (++count < 16);	if (count > 1)		printk("\n");}#if 0/* * Low level print for debugging - Cort */int __init ll_printk(const char *fmt, ...){        va_list args;	char buf[256];        int i;        va_start(args, fmt);        i=vsprintf(buf,fmt,args);	ll_puts(buf);        va_end(args);        return i;}int lines = 24, cols = 80;int orig_x = 0, orig_y = 0;void puthex(unsigned long val){	unsigned char buf[10];	int i;	for (i = 7;  i >= 0;  i--)	{		buf[i] = "0123456789ABCDEF"[val & 0x0F];		val >>= 4;	}	buf[8] = '\0';	prom_print(buf);}void __init ll_puts(const char *s){	int x,y;	char *vidmem = (char *)/*(_ISA_MEM_BASE + 0xB8000) */0xD00B8000;	char c;	extern int mem_init_done;	if ( mem_init_done ) /* assume this means we can printk */	{		printk(s);		return;	}#if 0		if ( have_of )	{		prom_print(s);		return;	}#endif	/*	 * can't ll_puts on chrp without openfirmware yet.	 * vidmem just needs to be setup for it.	 * -- Cort	 */	if ( _machine != _MACH_prep )		return;	x = orig_x;	y = orig_y;	while ( ( c = *s++ ) != '\0' ) {		if ( c == '\n' ) {			x = 0;			if ( ++y >= lines ) {				/*scroll();*/				/*y--;*/				y = 0;			}		} else {			vidmem [ ( x + cols * y ) * 2 ] = c; 			if ( ++x >= cols ) {				x = 0;				if ( ++y >= lines ) {					/*scroll();*/					/*y--;*/					y = 0;				}			}		}	}	orig_x = x;	orig_y = y;}#endif/* * These bracket the sleeping functions.. */extern void scheduling_functions_start_here(void);extern void scheduling_functions_end_here(void);#define first_sched    ((unsigned long) scheduling_functions_start_here)#define last_sched     ((unsigned long) scheduling_functions_end_here)unsigned long get_wchan(struct task_struct *p){	unsigned long ip, sp;	unsigned long stack_page = (unsigned long) p;	int count = 0;	if (!p || p == current || p->state == TASK_RUNNING)		return 0;	sp = p->thread.ksp;	do {		sp = *(unsigned long *)sp;		if (sp < stack_page || sp >= stack_page + 8188)			return 0;		if (count > 0) {			ip = *(unsigned long *)(sp + 4);			if (ip < first_sched || ip >= last_sched)				return ip;		}	} while (count++ < 16);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -