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

📄 vm86.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	: "r" (base), "q" (val), "0" (ptr))#define pushl(base, ptr, val) \__asm__ __volatile__( \	"decw %w0\n\t" \	"rorl $16,%2\n\t" \	"movb %h2,0(%1,%0)\n\t" \	"decw %w0\n\t" \	"movb %b2,0(%1,%0)\n\t" \	"decw %w0\n\t" \	"rorl $16,%2\n\t" \	"movb %h2,0(%1,%0)\n\t" \	"decw %w0\n\t" \	"movb %b2,0(%1,%0)" \	: "=r" (ptr) \	: "r" (base), "q" (val), "0" (ptr))#define popb(base, ptr) \({ unsigned long __res; \__asm__ __volatile__( \	"movb 0(%1,%0),%b2\n\t" \	"incw %w0" \	: "=r" (ptr), "=r" (base), "=q" (__res) \	: "0" (ptr), "1" (base), "2" (0)); \__res; })#define popw(base, ptr) \({ unsigned long __res; \__asm__ __volatile__( \	"movb 0(%1,%0),%b2\n\t" \	"incw %w0\n\t" \	"movb 0(%1,%0),%h2\n\t" \	"incw %w0" \	: "=r" (ptr), "=r" (base), "=q" (__res) \	: "0" (ptr), "1" (base), "2" (0)); \__res; })#define popl(base, ptr) \({ unsigned long __res; \__asm__ __volatile__( \	"movb 0(%1,%0),%b2\n\t" \	"incw %w0\n\t" \	"movb 0(%1,%0),%h2\n\t" \	"incw %w0\n\t" \	"rorl $16,%2\n\t" \	"movb 0(%1,%0),%b2\n\t" \	"incw %w0\n\t" \	"movb 0(%1,%0),%h2\n\t" \	"incw %w0\n\t" \	"rorl $16,%2" \	: "=r" (ptr), "=r" (base), "=q" (__res) \	: "0" (ptr), "1" (base)); \__res; })static void do_int(struct kernel_vm86_regs *regs, int i, unsigned char * ssp, unsigned long sp){	unsigned long *intr_ptr, segoffs;	if (regs->cs == BIOSSEG)		goto cannot_handle;	if (is_revectored(i, &KVM86->int_revectored))		goto cannot_handle;	if (i==0x21 && is_revectored(AH(regs),&KVM86->int21_revectored))		goto cannot_handle;	intr_ptr = (unsigned long *) (i << 2);	if (get_user(segoffs, intr_ptr))		goto cannot_handle;	if ((segoffs >> 16) == BIOSSEG)		goto cannot_handle;	pushw(ssp, sp, get_vflags(regs));	pushw(ssp, sp, regs->cs);	pushw(ssp, sp, IP(regs));	regs->cs = segoffs >> 16;	SP(regs) -= 6;	IP(regs) = segoffs & 0xffff;	clear_TF(regs);	clear_IF(regs);	return;cannot_handle:	return_to_32bit(regs, VM86_INTx + (i << 8));}int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno){	if (VMPI.is_vm86pus) {		if ( (trapno==3) || (trapno==1) )			return_to_32bit(regs, VM86_TRAP + (trapno << 8));		do_int(regs, trapno, (unsigned char *) (regs->ss << 4), SP(regs));		return 0;	}	if (trapno !=1)		return 1; /* we let this handle by the calling routine */	if (current->ptrace & PT_PTRACED) {		unsigned long flags;		spin_lock_irqsave(&current->sigmask_lock, flags);		sigdelset(&current->blocked, SIGTRAP);		recalc_sigpending(current);		spin_unlock_irqrestore(&current->sigmask_lock, flags);	}	send_sig(SIGTRAP, current, 1);	current->thread.trap_no = trapno;	current->thread.error_code = error_code;	return 0;}void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code){	unsigned char *csp, *ssp;	unsigned long ip, sp;#define CHECK_IF_IN_TRAP \	if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \		pushw(ssp,sp,popw(ssp,sp) | TF_MASK);#define VM86_FAULT_RETURN \	if (VMPI.force_return_for_pic  && (VEFLAGS & (IF_MASK | VIF_MASK))) \		return_to_32bit(regs, VM86_PICRETURN); \	return;	                                   	csp = (unsigned char *) (regs->cs << 4);	ssp = (unsigned char *) (regs->ss << 4);	sp = SP(regs);	ip = IP(regs);	switch (popb(csp, ip)) {	/* operand size override */	case 0x66:		switch (popb(csp, ip)) {		/* pushfd */		case 0x9c:			SP(regs) -= 4;			IP(regs) += 2;			pushl(ssp, sp, get_vflags(regs));			VM86_FAULT_RETURN;		/* popfd */		case 0x9d:			SP(regs) += 4;			IP(regs) += 2;			CHECK_IF_IN_TRAP			set_vflags_long(popl(ssp, sp), regs);			VM86_FAULT_RETURN;		/* iretd */		case 0xcf:			SP(regs) += 12;			IP(regs) = (unsigned short)popl(ssp, sp);			regs->cs = (unsigned short)popl(ssp, sp);			CHECK_IF_IN_TRAP			set_vflags_long(popl(ssp, sp), regs);			VM86_FAULT_RETURN;		/* need this to avoid a fallthrough */		default:			return_to_32bit(regs, VM86_UNKNOWN);		}	/* pushf */	case 0x9c:		SP(regs) -= 2;		IP(regs)++;		pushw(ssp, sp, get_vflags(regs));		VM86_FAULT_RETURN;	/* popf */	case 0x9d:		SP(regs) += 2;		IP(regs)++;		CHECK_IF_IN_TRAP		set_vflags_short(popw(ssp, sp), regs);		VM86_FAULT_RETURN;	/* int xx */	case 0xcd: {	        int intno=popb(csp, ip);		IP(regs) += 2;		if (VMPI.vm86dbg_active) {			if ( (1 << (intno &7)) & VMPI.vm86dbg_intxxtab[intno >> 3] )				return_to_32bit(regs, VM86_INTx + (intno << 8));		}		do_int(regs, intno, ssp, sp);		return;	}	/* iret */	case 0xcf:		SP(regs) += 6;		IP(regs) = popw(ssp, sp);		regs->cs = popw(ssp, sp);		CHECK_IF_IN_TRAP		set_vflags_short(popw(ssp, sp), regs);		VM86_FAULT_RETURN;	/* cli */	case 0xfa:		IP(regs)++;		clear_IF(regs);		VM86_FAULT_RETURN;	/* sti */	/*	 * Damn. This is incorrect: the 'sti' instruction should actually	 * enable interrupts after the /next/ instruction. Not good.	 *	 * Probably needs some horsing around with the TF flag. Aiee..	 */	case 0xfb:		IP(regs)++;		set_IF(regs);		VM86_FAULT_RETURN;	default:		return_to_32bit(regs, VM86_UNKNOWN);	}}/* ---------------- vm86 special IRQ passing stuff ----------------- */#define VM86_IRQNAME		"vm86irq"static struct vm86_irqs {	struct task_struct *tsk;	int sig;} vm86_irqs[16];static int irqbits;#define ALLOWED_SIGS ( 1 /* 0 = don't send a signal */ \	| (1 << SIGUSR1) | (1 << SIGUSR2) | (1 << SIGIO)  | (1 << SIGURG) \	| (1 << SIGUNUSED) )	static void irq_handler(int intno, void *dev_id, struct pt_regs * regs) {	int irq_bit;	unsigned long flags;		save_flags(flags);	cli();	irq_bit = 1 << intno;	if ((irqbits & irq_bit) || ! vm86_irqs[intno].tsk)		goto out;	irqbits |= irq_bit;	if (vm86_irqs[intno].sig)		send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1);	/* else user will poll for IRQs */out:	restore_flags(flags);}static inline void free_vm86_irq(int irqnumber){	free_irq(irqnumber,0);	vm86_irqs[irqnumber].tsk = 0;	irqbits &= ~(1 << irqnumber);}static inline int task_valid(struct task_struct *tsk){	struct task_struct *p;	int ret = 0;	read_lock(&tasklist_lock);	for_each_task(p) {		if ((p == tsk) && (p->sig)) {			ret = 1;			break;		}	}	read_unlock(&tasklist_lock);	return ret;}void release_x86_irqs(struct task_struct *task){	int i;	for (i=3; i<16; i++)	    if (vm86_irqs[i].tsk == task)		free_vm86_irq(i);}static inline void handle_irq_zombies(void){	int i;	for (i=3; i<16; i++) {		if (vm86_irqs[i].tsk) {			if (task_valid(vm86_irqs[i].tsk)) continue;			free_vm86_irq(i);		}	}}static inline int get_and_reset_irq(int irqnumber){	int bit;	unsigned long flags;		if ( (irqnumber<3) || (irqnumber>15) ) return 0;	if (vm86_irqs[irqnumber].tsk != current) return 0;	save_flags(flags);	cli();	bit = irqbits & (1 << irqnumber);	irqbits &= ~bit;	restore_flags(flags);	return bit;}static int do_vm86_irq_handling(int subfunction, int irqnumber){	int ret;	switch (subfunction) {		case VM86_GET_AND_RESET_IRQ: {			return get_and_reset_irq(irqnumber);		}		case VM86_GET_IRQ_BITS: {			return irqbits;		}		case VM86_REQUEST_IRQ: {			int sig = irqnumber >> 8;			int irq = irqnumber & 255;			handle_irq_zombies();			if (!capable(CAP_SYS_ADMIN)) return -EPERM;			if (!((1 << sig) & ALLOWED_SIGS)) return -EPERM;			if ( (irq<3) || (irq>15) ) return -EPERM;			if (vm86_irqs[irq].tsk) return -EPERM;			ret = request_irq(irq, &irq_handler, 0, VM86_IRQNAME, 0);			if (ret) return ret;			vm86_irqs[irq].sig = sig;			vm86_irqs[irq].tsk = current;			return irq;		}		case  VM86_FREE_IRQ: {			handle_irq_zombies();			if ( (irqnumber<3) || (irqnumber>15) ) return -EPERM;			if (!vm86_irqs[irqnumber].tsk) return 0;			if (vm86_irqs[irqnumber].tsk != current) return -EPERM;			free_vm86_irq(irqnumber);			return 0;		}	}	return -EINVAL;}

⌨️ 快捷键说明

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