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

📄 pm.c

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 C
📖 第 1 页 / 共 4 页
字号:
			}		else if (insn[i] == 0x6d) {			if (prefix.rep) {				if (prefix.size)					em_rep_ins(4);				else					em_rep_ins(2);				}			else {				if (prefix.size)					em_ins(4);				else					em_ins(2);				}			i++;			break;			}		else if (insn[i] == 0x6e) {			if (prefix.rep)				em_rep_outs(1);			else				em_outs(1);			i++;			break;			}		else if (insn[i] == 0x6f) {			if (prefix.rep) {				if (prefix.size)					em_rep_outs(4);				else					em_rep_outs(2);				}			else {				if (prefix.size)					em_outs(4);				else					em_outs(2);				}			i++;			break;			}		else if (insn[i] == 0xec) {			*((uchar*)&context.vm.regs.eax) = port_in(context.vm.regs.edx);			i++;			break;			}		else if (insn[i] == 0xed) {			if (prefix.size)				*((ulong*)&context.vm.regs.eax) = port_inl(context.vm.regs.edx);			else				*((ushort*)&context.vm.regs.eax) = port_inw(context.vm.regs.edx);			i++;			break;			}		else if (insn[i] == 0xee) {			port_out(context.vm.regs.eax,context.vm.regs.edx);			i++;			break;			}		else if (insn[i] == 0xef) {			if (prefix.size)				port_outl(context.vm.regs.eax,context.vm.regs.edx);			else				port_outw(context.vm.regs.eax,context.vm.regs.edx);			i++;			break;			}		else			return 0;		}	context.vm.regs.eip += i;	return 1;}static void debug_info(int vret){	int i;	unsigned char *p;	fputs("vm86() failed\n", stderr);	fprintf(stderr, "return = 0x%x\n", vret);	fprintf(stderr, "eax = 0x%08lx\n", context.vm.regs.eax);	fprintf(stderr, "ebx = 0x%08lx\n", context.vm.regs.ebx);	fprintf(stderr, "ecx = 0x%08lx\n", context.vm.regs.ecx);	fprintf(stderr, "edx = 0x%08lx\n", context.vm.regs.edx);	fprintf(stderr, "esi = 0x%08lx\n", context.vm.regs.esi);	fprintf(stderr, "edi = 0x%08lx\n", context.vm.regs.edi);	fprintf(stderr, "ebp = 0x%08lx\n", context.vm.regs.ebp);	fprintf(stderr, "eip = 0x%08lx\n", context.vm.regs.eip);	fprintf(stderr, "cs  = 0x%04x\n", context.vm.regs.cs);	fprintf(stderr, "esp = 0x%08lx\n", context.vm.regs.esp);	fprintf(stderr, "ss  = 0x%04x\n", context.vm.regs.ss);	fprintf(stderr, "ds  = 0x%04x\n", context.vm.regs.ds);	fprintf(stderr, "es  = 0x%04x\n", context.vm.regs.es);	fprintf(stderr, "fs  = 0x%04x\n", context.vm.regs.fs);	fprintf(stderr, "gs  = 0x%04x\n", context.vm.regs.gs);	fprintf(stderr, "eflags  = 0x%08lx\n", context.vm.regs.eflags);	fputs("cs:ip = [ ", stderr);	p = (unsigned char *)((context.vm.regs.cs << 4) + (context.vm.regs.eip & 0xffff));	for (i = 0; i < 16; ++i)			fprintf(stderr, "%02x ", (unsigned int)p[i]);	fputs("]\n", stderr);}static int run_vm86(void){	unsigned int vret;	for (;;) {		vret = vm86(&context.vm);		if (VM86_TYPE(vret) == VM86_INTx) {			unsigned int v = VM86_ARG(vret);			if (v == RETURN_TO_32_INT)				return 1;			pushw(context.vm.regs.eflags);			pushw(context.vm.regs.cs);			pushw(context.vm.regs.eip);			context.vm.regs.cs = get_int_seg(v);			context.vm.regs.eip = get_int_off(v);			context.vm.regs.eflags &= ~(VIF_MASK | TF_MASK);			continue;			}		if (VM86_TYPE(vret) != VM86_UNKNOWN)			break;		if (!emulate())			break;		}	debug_info(vret);	return 0;}#define	IND(ereg) context.vm.regs.ereg = regs->ereg#define	OUTD(ereg) regs->ereg = context.vm.regs.eregvoid PMAPI DPMI_int86(int intno, DPMI_regs *regs){    if (!inited)		PM_init();    memset(&context.vm.regs, 0, sizeof(context.vm.regs));    IND(eax); IND(ebx); IND(ecx); IND(edx); IND(esi); IND(edi);    context.vm.regs.eflags = DEFAULT_VM86_FLAGS;    context.vm.regs.cs = get_int_seg(intno);    context.vm.regs.eip = get_int_off(intno);    context.vm.regs.ss = context.stack_seg;    context.vm.regs.esp = context.stack_off;    pushw(DEFAULT_VM86_FLAGS);    pushw(context.ret_seg);    pushw(context.ret_off);    run_vm86();    OUTD(eax); OUTD(ebx); OUTD(ecx); OUTD(edx); OUTD(esi); OUTD(edi);    regs->flags = context.vm.regs.eflags;}#define	IN(ereg) context.vm.regs.ereg = in->e.ereg#define	OUT(ereg) out->e.ereg = context.vm.regs.eregint PMAPI PM_int86(int intno, RMREGS *in, RMREGS *out){    if (!inited)		PM_init();    memset(&context.vm.regs, 0, sizeof(context.vm.regs));    IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);    context.vm.regs.eflags = DEFAULT_VM86_FLAGS;    context.vm.regs.cs = get_int_seg(intno);    context.vm.regs.eip = get_int_off(intno);    context.vm.regs.ss = context.stack_seg;    context.vm.regs.esp = context.stack_off;    pushw(DEFAULT_VM86_FLAGS);    pushw(context.ret_seg);    pushw(context.ret_off);    run_vm86();    OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);	out->x.cflag = context.vm.regs.eflags & 1;	return out->x.ax;}int PMAPI PM_int86x(int intno, RMREGS *in, RMREGS *out,	RMSREGS *sregs){	if (!inited)		PM_init();	if (intno == 0x21) {		time_t today = time(NULL);		struct tm *t;		t = localtime(&today);		out->x.cx = t->tm_year + 1900;		out->h.dh = t->tm_mon + 1;		out->h.dl = t->tm_mday;		}	else {		unsigned int seg, off;		seg = get_int_seg(intno);		off = get_int_off(intno);		memset(&context.vm.regs, 0, sizeof(context.vm.regs));		IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);		context.vm.regs.eflags = DEFAULT_VM86_FLAGS;		context.vm.regs.cs = seg;		context.vm.regs.eip = off;		context.vm.regs.es = sregs->es;		context.vm.regs.ds = sregs->ds;		context.vm.regs.fs = sregs->fs;		context.vm.regs.gs = sregs->gs;		context.vm.regs.ss = context.stack_seg;		context.vm.regs.esp = context.stack_off;		pushw(DEFAULT_VM86_FLAGS);		pushw(context.ret_seg);		pushw(context.ret_off);		run_vm86();		OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);		sregs->es = context.vm.regs.es;		sregs->ds = context.vm.regs.ds;		sregs->fs = context.vm.regs.fs;		sregs->gs = context.vm.regs.gs;		out->x.cflag = context.vm.regs.eflags & 1;	    }	return out->e.eax;}#define	OUTR(ereg) in->e.ereg =	context.vm.regs.eregvoid PMAPI PM_callRealMode(uint seg,uint off, RMREGS *in,	RMSREGS *sregs){    if (!inited)		PM_init();    memset(&context.vm.regs, 0, sizeof(context.vm.regs));    IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);    context.vm.regs.eflags = DEFAULT_VM86_FLAGS;    context.vm.regs.cs = seg;    context.vm.regs.eip = off;    context.vm.regs.ss = context.stack_seg;    context.vm.regs.esp = context.stack_off;    context.vm.regs.es = sregs->es;    context.vm.regs.ds = sregs->ds;    context.vm.regs.fs = sregs->fs;    context.vm.regs.gs = sregs->gs;    pushw(DEFAULT_VM86_FLAGS);    pushw(context.ret_seg);    pushw(context.ret_off);    run_vm86();    OUTR(eax); OUTR(ebx); OUTR(ecx); OUTR(edx); OUTR(esi); OUTR(edi);    sregs->es = context.vm.regs.es;    sregs->ds = context.vm.regs.ds;    sregs->fs = context.vm.regs.fs;    sregs->gs = context.vm.regs.gs;    in->x.cflag = context.vm.regs.eflags & 1;}void PMAPI PM_availableMemory(ulong *physical,ulong *total){    FILE 	*mem = fopen("/proc/meminfo","r");    char 	buf[1024];    fgets(buf,1024,mem);    fgets(buf,1024,mem);    sscanf(buf,"Mem: %*d %*d %ld", physical);    fgets(buf,1024,mem);    sscanf(buf,"Swap: %*d %*d %ld", total);    fclose(mem);    *total += *physical;}void * PMAPI PM_allocLockedMem(uint size,ulong *physAddr){	// TODO: Implement this for Linux	return NULL;}void PMAPI PM_freeLockedMem(void *p,uint size){	// TODO: Implement this for Linux}void PMAPI PM_setBankA(int bank){    if (!inited)		PM_init();    memset(&context.vm.regs, 0, sizeof(context.vm.regs));	context.vm.regs.eax = 0x4F05;	context.vm.regs.ebx = 0x0000;	context.vm.regs.edx = bank;    context.vm.regs.eflags = DEFAULT_VM86_FLAGS;    context.vm.regs.cs = get_int_seg(0x10);    context.vm.regs.eip = get_int_off(0x10);    context.vm.regs.ss = context.stack_seg;    context.vm.regs.esp = context.stack_off;    pushw(DEFAULT_VM86_FLAGS);    pushw(context.ret_seg);    pushw(context.ret_off);    run_vm86();}void PMAPI PM_setBankAB(int bank){    if (!inited)		PM_init();    memset(&context.vm.regs, 0, sizeof(context.vm.regs));	context.vm.regs.eax = 0x4F05;	context.vm.regs.ebx = 0x0000;	context.vm.regs.edx = bank;    context.vm.regs.eflags = DEFAULT_VM86_FLAGS;    context.vm.regs.cs = get_int_seg(0x10);    context.vm.regs.eip = get_int_off(0x10);    context.vm.regs.ss = context.stack_seg;    context.vm.regs.esp = context.stack_off;    pushw(DEFAULT_VM86_FLAGS);    pushw(context.ret_seg);    pushw(context.ret_off);    run_vm86();	context.vm.regs.eax = 0x4F05;	context.vm.regs.ebx = 0x0001;	context.vm.regs.edx = bank;    context.vm.regs.eflags = DEFAULT_VM86_FLAGS;    context.vm.regs.cs = get_int_seg(0x10);    context.vm.regs.eip = get_int_off(0x10);    context.vm.regs.ss = context.stack_seg;    context.vm.regs.esp = context.stack_off;	pushw(DEFAULT_VM86_FLAGS);	pushw(context.ret_seg);	pushw(context.ret_off);	run_vm86();}void PMAPI PM_setCRTStart(int x,int y,int waitVRT){	if (!inited)		PM_init();    memset(&context.vm.regs, 0, sizeof(context.vm.regs));	context.vm.regs.eax = 0x4F07;	context.vm.regs.ebx = waitVRT;	context.vm.regs.ecx = x;	context.vm.regs.edx = y;	context.vm.regs.eflags = DEFAULT_VM86_FLAGS;	context.vm.regs.cs = get_int_seg(0x10);	context.vm.regs.eip = get_int_off(0x10);	context.vm.regs.ss = context.stack_seg;	context.vm.regs.esp = context.stack_off;	pushw(DEFAULT_VM86_FLAGS);	pushw(context.ret_seg);	pushw(context.ret_off);	run_vm86();}int PMAPI PM_enableWriteCombine(ulong base,ulong length,uint type){#ifdef ENABLE_MTRR	struct mtrr_sentry sentry;	if (mtrr_fd < 0)		return PM_MTRR_ERR_NO_OS_SUPPORT;	sentry.base = base;    sentry.size = length;	sentry.type = type;	if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &sentry) == -1) {		// TODO: Need to decode MTRR error codes!!		return PM_MTRR_NOT_SUPPORTED;		}	return PM_MTRR_ERR_OK;#else	return PM_MTRR_ERR_NO_OS_SUPPORT;#endif}ibool PMAPI PM_doBIOSPOST(	ushort axVal,	ulong BIOSPhysAddr,	void *copyOfBIOS,	ulong BIOSLen){	char		*bios_ptr = (char*)0xC0000;	char        *old_bios;	ulong       Current10, Current6D, *rvec = 0;	RMREGS      regs;	RMSREGS     sregs;	/* The BIOS is mapped to 0xC0000 with a private memory mapping enabled	 * which means we have a copy on write scheme. Hence we simply copy	 * the secondary BIOS image over the top of the old one.	 */	if (!inited)		PM_init();	if ((old_bios = malloc(BIOSLen)) == NULL)    	return false;	if (BIOSPhysAddr != 0xC0000) {		memcpy(old_bios,bios_ptr,BIOSLen);		memcpy(bios_ptr,copyOfBIOS,BIOSLen);        }	/* The interrupt vectors should already be mmap()'ed from 0-0x400 in PM_init */	Current10 = rvec[0x10];	Current6D = rvec[0x6D];	/* POST the secondary BIOS */	rvec[0x10] = rvec[0x42]; /* Restore int 10h to STD-BIOS */	regs.x.ax = axVal;	PM_callRealMode(0xC000,0x0003,&regs,&sregs);    /* Restore interrupt vectors */	rvec[0x10] = Current10;	rvec[0x6D] = Current6D;    /* Restore original BIOS image */    if (BIOSPhysAddr != 0xC0000)		memcpy(bios_ptr,old_bios,BIOSLen);	free(old_bios);	return true;}int PMAPI PM_lockDataPages(void *p,uint len){	p = p;	len = len;		/* Do nothing for real mode	*/	return 1;}int PMAPI PM_unlockDataPages(void *p,uint len){	p = p;	len = len;		/* Do nothing for real mode	*/	return 1;}int PMAPI PM_lockCodePages(void (*p)(),uint len){	p = p;	len = len;		/* Do nothing for real mode	*/	return 1;}int PMAPI PM_unlockCodePages(void (*p)(),uint len){	p = p;	len = len;		/* Do nothing for real mode	*/	return 1;}PM_MODULE PMAPI PM_loadLibrary(	const char *szDLLName){	// TODO: Implement this to load shared libraries!	(void)szDLLName;	return NULL;}void * PMAPI PM_getProcAddress(	PM_MODULE hModule,	const char *szProcName){	// TODO: Implement this!	(void)hModule;	(void)szProcName;	return NULL;}void PMAPI PM_freeLibrary(	PM_MODULE hModule){	// TODO: Implement this!	(void)hModule;}int PMAPI PM_setIOPL(	int level){	// TODO: Move the IOPL switching into this function!!	return level;}

⌨️ 快捷键说明

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