📄 pm.c
字号:
/* Restore the old console font */ if (ioctl(console_id,PIO_FONT,®s[FONT]) < 0) perror("ioctl(PIO_FONT)");}/****************************************************************************REMARKS:Close the Linux console and put it back to normal.****************************************************************************/void PMAPI PM_closeConsole(PM_HWND _PM_console_fd){ /* Restore console to normal operation */ if (--console_count == 0) { if (startup_vc > 0) ioctl(_PM_console_fd, VT_ACTIVATE, startup_vc); }}void PM_setOSCursorLocation(int x,int y){ /* Nothing to do in here */}/****************************************************************************REMARKS:Set the screen width and height for the Linux console.****************************************************************************/void PM_setOSScreenWidth(int width,int height){ struct winsize ws; struct vt_sizes vs; // Resize the software terminal ws.ws_col = width; ws.ws_row = height; ioctl(_PM_console_fd, TIOCSWINSZ, &ws); // And the hardware vs.v_rows = height; vs.v_cols = width; vs.v_scrollsize = 0; ioctl(_PM_console_fd, VT_RESIZE, &vs);}ibool PMAPI PM_setRealTimeClockHandler(PM_intHandler ih, int frequency){ // TODO: Implement this for Linux return false;}void PMAPI PM_setRealTimeClockFrequency(int frequency){ // TODO: Implement this for Linux}void PMAPI PM_restoreRealTimeClockHandler(void){ // TODO: Implement this for Linux}const char * PMAPI PM_getCurrentPath(void){ static char cwd[512]; return getcwd(cwd,sizeof(cwd));}char PMAPI PM_getBootDrive(void){ return '/'; }const char * PMAPI PM_getVBEAFPath(void){ return PM_getNucleusConfigPath(); }const char * PMAPI PM_getNucleusPath(void){ char *env = getenv("NUCLEUS_PATH"); return env ? env : "/usr/lib/nucleus";}const char * PMAPI PM_getNucleusConfigPath(void){ static char path[256]; strcpy(path,PM_getNucleusPath()); PM_backslash(path); strcat(path,"config"); return path;}const char * PMAPI PM_getUniqueID(void){ static char buf[128]; gethostname(buf, 128); return buf;}const char * PMAPI PM_getMachineName(void){ static char buf[128]; gethostname(buf, 128); return buf;}void * PMAPI PM_getBIOSPointer(void){ static uchar *zeroPtr = NULL; if (!zeroPtr) zeroPtr = PM_mapPhysicalAddr(0,0xFFFFF,true); return (void*)(zeroPtr + 0x400);}void * PMAPI PM_getA0000Pointer(void){ /* PM_init maps in the 0xA0000 framebuffer region 1:1 with our * address mapping, so we can return the address here. */ if (!inited) PM_init(); return (void*)(0xA0000);}void * PMAPI PM_mapPhysicalAddr(ulong base,ulong limit,ibool isCached){ uchar *p; ulong baseAddr,baseOfs; if (!inited) PM_init(); if (base >= 0xA0000 && base < 0x100000) return (void*)base; if (!fd_mem && (fd_mem = open("/dev/mem", O_RDWR)) == -1) return NULL; /* Round the physical address to a 4Kb boundary and the limit to a * 4Kb-1 boundary before passing the values to mmap. If we round the * physical address, then we also add an extra offset into the address * that we return. */ baseOfs = base & 4095; baseAddr = base & ~4095; limit = ((limit+baseOfs+1+4095) & ~4095)-1; if ((p = mmap(0, limit+1, PROT_READ | PROT_WRITE, MAP_SHARED, fd_mem, baseAddr)) == (void *)-1) return NULL; return (void*)(p+baseOfs);}void PMAPI PM_freePhysicalAddr(void *ptr,ulong limit){ if ((ulong)ptr >= 0x100000) munmap(ptr,limit+1);}ulong PMAPI PM_getPhysicalAddr(void *p){ // TODO: This function should find the physical address of a linear // address. return 0xFFFFFFFFUL;}void PMAPI PM_sleep(ulong milliseconds){ // TODO: Put the process to sleep for milliseconds}int PMAPI PM_getCOMPort(int port){ // TODO: Re-code this to determine real values using the Plug and Play // manager for the OS. switch (port) { case 0: return 0x3F8; case 1: return 0x2F8; } return 0;}int PMAPI PM_getLPTPort(int port){ // TODO: Re-code this to determine real values using the Plug and Play // manager for the OS. switch (port) { case 0: return 0x3BC; case 1: return 0x378; case 2: return 0x278; } return 0;}void * PMAPI PM_mallocShared(long size){ return malloc(size);}int PMAPI PM_mapShared(void *ptr){ printf("PM_mapShared not implemented yet!\n"); return -1;}void PMAPI PM_freeShared(void *ptr){ free(ptr);}void * PMAPI PM_mapToProcess(void *base,ulong limit){ return (void*)base; }void * PMAPI PM_mapRealPointer(uint r_seg,uint r_off){ /* PM_init maps in the 0xA0000-0x100000 region 1:1 with our * address mapping, as well as all memory blocks in a 1:1 address * mapping so we can simply return the physical address in here. */ if (!inited) PM_init(); return (void*)MK_PHYS(r_seg,r_off);}void * PMAPI PM_allocRealSeg(uint size,uint *r_seg,uint *r_off){ int i; char *r = (char *)REAL_MEM_BASE; if (!inited) PM_init(); if (!mem_info.ready) return NULL; if (mem_info.count == REAL_MEM_BLOCKS) return NULL; size = (size + 15) & ~15; for (i = 0; i < mem_info.count; i++) { if (mem_info.blocks[i].free && size < mem_info.blocks[i].size) { insert_block(i); mem_info.blocks[i].size = size; mem_info.blocks[i].free = 0; mem_info.blocks[i + 1].size -= size; *r_seg = (uint)(r) >> 4; *r_off = (uint)(r) & 0xF; return (void *)r; } r += mem_info.blocks[i].size; } return NULL;}void PMAPI PM_freeRealSeg(void *mem){ int i; char *r = (char *)REAL_MEM_BASE; if (!mem_info.ready) return; i = 0; while (mem != (void *)r) { r += mem_info.blocks[i].size; i++; if (i == mem_info.count) return; } mem_info.blocks[i].free = 1; if (i + 1 < mem_info.count && mem_info.blocks[i + 1].free) { mem_info.blocks[i].size += mem_info.blocks[i + 1].size; delete_block(i + 1); } if (i - 1 >= 0 && mem_info.blocks[i - 1].free) { mem_info.blocks[i - 1].size += mem_info.blocks[i].size; delete_block(i); }}#define DIRECTION_FLAG (1 << 10)static void em_ins(int size){ unsigned int edx, edi; edx = context.vm.regs.edx & 0xffff; edi = context.vm.regs.edi & 0xffff; edi += (unsigned int)context.vm.regs.ds << 4; if (context.vm.regs.eflags & DIRECTION_FLAG) { if (size == 4) asm volatile ("std; insl; cld" : "=D" (edi) : "d" (edx), "0" (edi)); else if (size == 2) asm volatile ("std; insw; cld" : "=D" (edi) : "d" (edx), "0" (edi)); else asm volatile ("std; insb; cld" : "=D" (edi) : "d" (edx), "0" (edi)); } else { if (size == 4) asm volatile ("cld; insl" : "=D" (edi) : "d" (edx), "0" (edi)); else if (size == 2) asm volatile ("cld; insw" : "=D" (edi) : "d" (edx), "0" (edi)); else asm volatile ("cld; insb" : "=D" (edi) : "d" (edx), "0" (edi)); } edi -= (unsigned int)context.vm.regs.ds << 4; context.vm.regs.edi &= 0xffff0000; context.vm.regs.edi |= edi & 0xffff;}static void em_rep_ins(int size){ unsigned int ecx, edx, edi; ecx = context.vm.regs.ecx & 0xffff; edx = context.vm.regs.edx & 0xffff; edi = context.vm.regs.edi & 0xffff; edi += (unsigned int)context.vm.regs.ds << 4; if (context.vm.regs.eflags & DIRECTION_FLAG) { if (size == 4) asm volatile ("std; rep; insl; cld" : "=D" (edi), "=c" (ecx) : "d" (edx), "0" (edi), "1" (ecx)); else if (size == 2) asm volatile ("std; rep; insw; cld" : "=D" (edi), "=c" (ecx) : "d" (edx), "0" (edi), "1" (ecx)); else asm volatile ("std; rep; insb; cld" : "=D" (edi), "=c" (ecx) : "d" (edx), "0" (edi), "1" (ecx)); } else { if (size == 4) asm volatile ("cld; rep; insl" : "=D" (edi), "=c" (ecx) : "d" (edx), "0" (edi), "1" (ecx)); else if (size == 2) asm volatile ("cld; rep; insw" : "=D" (edi), "=c" (ecx) : "d" (edx), "0" (edi), "1" (ecx)); else asm volatile ("cld; rep; insb" : "=D" (edi), "=c" (ecx) : "d" (edx), "0" (edi), "1" (ecx)); } edi -= (unsigned int)context.vm.regs.ds << 4; context.vm.regs.edi &= 0xffff0000; context.vm.regs.edi |= edi & 0xffff; context.vm.regs.ecx &= 0xffff0000; context.vm.regs.ecx |= ecx & 0xffff;}static void em_outs(int size){ unsigned int edx, esi; edx = context.vm.regs.edx & 0xffff; esi = context.vm.regs.esi & 0xffff; esi += (unsigned int)context.vm.regs.ds << 4; if (context.vm.regs.eflags & DIRECTION_FLAG) { if (size == 4) asm volatile ("std; outsl; cld" : "=S" (esi) : "d" (edx), "0" (esi)); else if (size == 2) asm volatile ("std; outsw; cld" : "=S" (esi) : "d" (edx), "0" (esi)); else asm volatile ("std; outsb; cld" : "=S" (esi) : "d" (edx), "0" (esi)); } else { if (size == 4) asm volatile ("cld; outsl" : "=S" (esi) : "d" (edx), "0" (esi)); else if (size == 2) asm volatile ("cld; outsw" : "=S" (esi) : "d" (edx), "0" (esi)); else asm volatile ("cld; outsb" : "=S" (esi) : "d" (edx), "0" (esi)); } esi -= (unsigned int)context.vm.regs.ds << 4; context.vm.regs.esi &= 0xffff0000; context.vm.regs.esi |= esi & 0xffff;}static void em_rep_outs(int size){ unsigned int ecx, edx, esi; ecx = context.vm.regs.ecx & 0xffff; edx = context.vm.regs.edx & 0xffff; esi = context.vm.regs.esi & 0xffff; esi += (unsigned int)context.vm.regs.ds << 4; if (context.vm.regs.eflags & DIRECTION_FLAG) { if (size == 4) asm volatile ("std; rep; outsl; cld" : "=S" (esi), "=c" (ecx) : "d" (edx), "0" (esi), "1" (ecx)); else if (size == 2) asm volatile ("std; rep; outsw; cld" : "=S" (esi), "=c" (ecx) : "d" (edx), "0" (esi), "1" (ecx)); else asm volatile ("std; rep; outsb; cld" : "=S" (esi), "=c" (ecx) : "d" (edx), "0" (esi), "1" (ecx)); } else { if (size == 4) asm volatile ("cld; rep; outsl" : "=S" (esi), "=c" (ecx) : "d" (edx), "0" (esi), "1" (ecx)); else if (size == 2) asm volatile ("cld; rep; outsw" : "=S" (esi), "=c" (ecx) : "d" (edx), "0" (esi), "1" (ecx)); else asm volatile ("cld; rep; outsb" : "=S" (esi), "=c" (ecx) : "d" (edx), "0" (esi), "1" (ecx)); } esi -= (unsigned int)context.vm.regs.ds << 4; context.vm.regs.esi &= 0xffff0000; context.vm.regs.esi |= esi & 0xffff; context.vm.regs.ecx &= 0xffff0000; context.vm.regs.ecx |= ecx & 0xffff;}static int emulate(void){ unsigned char *insn; struct { unsigned int size : 1; unsigned int rep : 1; } prefix = { 0, 0 }; int i = 0; insn = (unsigned char *)((unsigned int)context.vm.regs.cs << 4); insn += context.vm.regs.eip; while (1) {#ifdef TRACE_IO traceAddr = ((ulong)context.vm.regs.cs << 16) + context.vm.regs.eip + i;#endif if (insn[i] == 0x66) { prefix.size = 1 - prefix.size; i++; } else if (insn[i] == 0xf3) { prefix.rep = 1; i++; } else if (insn[i] == 0xf0 || insn[i] == 0xf2 || insn[i] == 0x26 || insn[i] == 0x2e || insn[i] == 0x36 || insn[i] == 0x3e || insn[i] == 0x64 || insn[i] == 0x65 || insn[i] == 0x67) { /* these prefixes are just ignored */ i++; } else if (insn[i] == 0x6c) { if (prefix.rep) em_rep_ins(1); else em_ins(1); i++; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -