📄 pm.c
字号:
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); fflush(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,ibool contiguous,ibool below16M){ /* TODO: Implement this for Linux */ return NULL;}void PMAPI PM_freeLockedMem(void *p,uint size,ibool contiguous){ /* TODO: Implement this for Linux */}void * PMAPI PM_allocPage( ibool locked){ /* TODO: Implement this for Linux */ return NULL;}void PMAPI PM_freePage( void *p){ /* 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}/****************************************************************************PARAMETERS:callback - Function to callback with write combine informationREMARKS:Function to enumerate all write combine regions currently enabled for theprocessor.****************************************************************************/int PMAPI PM_enumWriteCombine( PM_enumWriteCombine_t callback){#ifdef ENABLE_MTRR struct mtrr_gentry gentry; if (mtrr_fd < 0) return PM_MTRR_ERR_NO_OS_SUPPORT; for (gentry.regnum = 0; ioctl (mtrr_fd, MTRRIOC_GET_ENTRY, &gentry) == 0; ++gentry.regnum) { if (gentry.size > 0) { /* WARNING: This code assumes that the types in pmapi.h match the ones */ /* in the Linux kernel (mtrr.h) */ callback(gentry.base, gentry.size, gentry.type); } } 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 = PM_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,®s,&sregs); /* Restore interrupt vectors */ rvec[0x10] = Current10; rvec[0x6D] = Current6D; /* Restore original BIOS image */ if (BIOSPhysAddr != 0xC0000) memcpy(bios_ptr,old_bios,BIOSLen); PM_free(old_bios); return true;}int PMAPI PM_lockDataPages(void *p,uint len,PM_lockHandle *lh){ p = p; len = len; return 1;}int PMAPI PM_unlockDataPages(void *p,uint len,PM_lockHandle *lh){ p = p; len = len; return 1;}int PMAPI PM_lockCodePages(void (*p)(),uint len,PM_lockHandle *lh){ p = p; len = len; return 1;}int PMAPI PM_unlockCodePages(void (*p)(),uint len,PM_lockHandle *lh){ p = p; len = len; 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;}void PMAPI PM_flushTLB(void){ /* Do nothing on Linux. */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -