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

📄 pm.c

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Restore the old console font */	if (ioctl(console_id,PIO_FONT,&regs[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 + -