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

📄 pm.c

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************					SciTech OS Portability Manager Library**  ========================================================================**    The contents of this file are subject to the SciTech MGL Public*    License Version 1.0 (the "License"); you may not use this file*    except in compliance with the License. You may obtain a copy of*    the License at http://www.scitechsoft.com/mgl-license.txt**    Software distributed under the License is distributed on an*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or*    implied. See the License for the specific language governing*    rights and limitations under the License.**    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.**    The Initial Developer of the Original Code is SciTech Software, Inc.*    All Rights Reserved.**  ========================================================================**					Portions copyright (C) Josh Vanderhoof** Language:		ANSI C* Environment:	Linux** Description:	Implementation for the OS Portability Manager Library, which*				contains functions to implement OS specific services in a*				generic, cross platform API. Porting the OS Portability*				Manager library is the first step to porting any SciTech*				products to a new platform.*****************************************************************************/#include "pmapi.h"#include "drvlib/os/os.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/mman.h>#include <sys/kd.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/vt.h>#include <sys/wait.h>#include <sys/types.h>#include <sys/time.h>#include <unistd.h>#include <termios.h>#include <fcntl.h>#include <syscall.h>#include <signal.h>#include <time.h>#include <ctype.h>#include <errno.h>#include <asm/io.h>#include <asm/types.h>#ifdef ENABLE_MTRR#include <asm/mtrr.h>#endif#include <asm/vm86.h>#ifdef __GLIBC__#include <sys/perm.h>#endif/*--------------------------- Global variables ----------------------------*/#define REAL_MEM_BASE 		((void *)0x10000)#define REAL_MEM_SIZE 		0x10000#define REAL_MEM_BLOCKS 	0x100#define DEFAULT_VM86_FLAGS 	(IF_MASK | IOPL_MASK)#define DEFAULT_STACK_SIZE 	0x1000#define RETURN_TO_32_INT 	255/* Quick and dirty fix for vm86() syscall from lrmi 0.6 */static intvm86(struct vm86_struct *vm)	{	int r;#ifdef __PIC__	asm volatile (	 "pushl %%ebx\n\t"	 "movl %2, %%ebx\n\t"	 "int $0x80\n\t"	 "popl %%ebx"	 : "=a" (r)	 : "0" (113), "r" (vm));#else	asm volatile (	 "int $0x80"	 : "=a" (r)	 : "0" (113), "b" (vm));#endif	return r;	}static struct {	int 				ready;	unsigned short 		ret_seg, ret_off;	unsigned short 		stack_seg, stack_off;	struct vm86_struct	vm;	} context = {0};struct mem_block {	unsigned int size : 20;	unsigned int free : 1;	};static struct {	int ready;	int count;	struct mem_block blocks[REAL_MEM_BLOCKS];	} mem_info = {0};int 					_PM_console_fd = -1;int 					_PM_leds = 0,_PM_modifiers = 0;static ibool 			inited = false;static int 				tty_vc = 0;static int 				console_count = 0;static int 				startup_vc;static struct termios	old_termios;static ibool 			in_raw_mode = false;static int 				old_kb_mode,old_leds,old_flags;static int 				fd_mem = 0;#ifdef ENABLE_MTRRstatic int 				mtrr_fd;#endifstatic uint	VESABuf_len = 1024;		/* Length of the VESABuf buffer		*/static void *VESABuf_ptr = NULL;	/* Near pointer to VESABuf          */static uint VESABuf_rseg;   		/* Real mode segment of VESABuf     */static uint	VESABuf_roff;			/* Real mode offset of VESABuf      */#ifdef TRACE_IOstatic ulong 			traceAddr;#endifstatic void (PMAPIP fatalErrorCleanup)(void) = NULL;/*----------------------------- Implementation ----------------------------*/#ifdef	TRACE_IOextern void printk(char *msg,...);#endifstatic inline void port_out(int value, int port){#ifdef TRACE_IO	printk("%04X:%04X: outb.%04X <- %02X\n", traceAddr >> 16, traceAddr & 0xFFFF, (ushort)port, (uchar)value);#endif    asm volatile ("outb %0,%1"	      ::"a" ((unsigned char) value), "d"((unsigned short) port));}static inline void port_outw(int value, int port){#ifdef TRACE_IO	printk("%04X:%04X: outw.%04X <- %04X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (ushort)value);#endif    asm volatile ("outw %0,%1"	     ::"a" ((unsigned short) value), "d"((unsigned short) port));}static inline void port_outl(int value, int port){#ifdef TRACE_IO	printk("%04X:%04X: outl.%04X <- %08X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (ulong)value);#endif    asm volatile ("outl %0,%1"	     ::"a" ((unsigned long) value), "d"((unsigned short) port));}static inline unsigned int port_in(int port){    unsigned char value;    asm volatile ("inb %1,%0"		      :"=a" ((unsigned char)value)		      :"d"((unsigned short) port));#ifdef TRACE_IO	printk("%04X:%04X:  inb.%04X -> %02X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (uchar)value);#endif    return value;}static inline unsigned int port_inw(int port){    unsigned short value;    asm volatile ("inw %1,%0"		      :"=a" ((unsigned short)value)		      :"d"((unsigned short) port));#ifdef TRACE_IO	printk("%04X:%04X:  inw.%04X -> %04X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (ushort)value);#endif    return value;}static inline unsigned int port_inl(int port){    unsigned long value;    asm volatile ("inl %1,%0"		      :"=a" ((unsigned long)value)		      :"d"((unsigned short) port));#ifdef TRACE_IO	printk("%04X:%04X:  inl.%04X -> %08X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (ulong)value);#endif    return value;}static int real_mem_init(void){	void    *m;	int     fd_zero;	if (mem_info.ready)	    return 1;		if ((fd_zero = open("/dev/zero", O_RDONLY)) == -1)		PM_fatalError("You must have root privledges to run this program!");	if ((m = mmap((void *)REAL_MEM_BASE, REAL_MEM_SIZE,			PROT_READ | PROT_WRITE | PROT_EXEC,			MAP_FIXED | MAP_PRIVATE, fd_zero, 0)) == (void *)-1) {		close(fd_zero);		PM_fatalError("You must have root privledges to run this program!");		}	mem_info.ready = 1;	mem_info.count = 1;	mem_info.blocks[0].size = REAL_MEM_SIZE;	mem_info.blocks[0].free = 1;	return 1;}static void insert_block(int i){	memmove(	 	mem_info.blocks + i + 1,	 	mem_info.blocks + i,	 	(mem_info.count - i) * sizeof(struct mem_block));	mem_info.count++;}static void delete_block(int i){	mem_info.count--;	memmove(	 	mem_info.blocks + i,	 	mem_info.blocks + i + 1,	 	(mem_info.count - i) * sizeof(struct mem_block));}static inline void set_bit(unsigned int bit, void *array){	unsigned char *a = array;	a[bit / 8] |= (1 << (bit % 8));}static inline unsigned int get_int_seg(int i){	return *(unsigned short *)(i * 4 + 2);}static inline unsigned int get_int_off(int i){	return *(unsigned short *)(i * 4);}static inline void pushw(unsigned short i){	struct vm86_regs *r = &context.vm.regs;	r->esp -= 2;	*(unsigned short *)(((unsigned int)r->ss << 4) + r->esp) = i;}ibool PMAPI PM_haveBIOSAccess(void){ return true; }void PMAPI PM_init(void){	void	*m;	uint	r_seg,r_off;	if (inited)	    return;	/* Map the Interrupt Vectors (0x0 - 0x400) + BIOS data (0x400 - 0x502)	 * and the physical framebuffer and ROM images from (0xa0000 - 0x100000)	 */	real_mem_init();	if (!fd_mem && (fd_mem = open("/dev/mem", O_RDWR)) == -1) {		PM_fatalError("You must have root privileges to run this program!");		}	if ((m = mmap((void *)0, 0x502,	 		PROT_READ | PROT_WRITE | PROT_EXEC,	 		MAP_FIXED | MAP_PRIVATE, fd_mem, 0)) == (void *)-1) {		PM_fatalError("You must have root privileges to run this program!");		}	if ((m = mmap((void *)0xA0000, 0xC0000 - 0xA0000,			PROT_READ | PROT_WRITE,			MAP_FIXED | MAP_SHARED, fd_mem, 0xA0000)) == (void *)-1) {		PM_fatalError("You must have root privileges to run this program!");		}	if ((m = mmap((void *)0xC0000, 0xD0000 - 0xC0000,			PROT_READ | PROT_WRITE | PROT_EXEC,			MAP_FIXED | MAP_PRIVATE, fd_mem, 0xC0000)) == (void *)-1) {		PM_fatalError("You must have root privileges to run this program!");		}	if ((m = mmap((void *)0xD0000, 0x100000 - 0xD0000,			PROT_READ | PROT_WRITE,			MAP_FIXED | MAP_SHARED, fd_mem, 0xD0000)) == (void *)-1) {		PM_fatalError("You must have root privileges to run this program!");		}	inited = 1;	/* Allocate a stack */	m = PM_allocRealSeg(DEFAULT_STACK_SIZE,&r_seg,&r_off);	context.stack_seg = r_seg;	context.stack_off = r_off+DEFAULT_STACK_SIZE;	/* Allocate the return to 32 bit routine */	m = PM_allocRealSeg(2,&r_seg,&r_off);	context.ret_seg = r_seg;	context.ret_off = r_off;	((uchar*)m)[0] = 0xCD;         /* int opcode */	((uchar*)m)[1] = RETURN_TO_32_INT;	memset(&context.vm, 0, sizeof(context.vm));	/* Enable kernel emulation of all ints except RETURN_TO_32_INT */	memset(&context.vm.int_revectored, 0, sizeof(context.vm.int_revectored));	set_bit(RETURN_TO_32_INT, &context.vm.int_revectored);	context.ready = 1;#ifdef ENABLE_MTRR	mtrr_fd =  open("/dev/cpu/mtrr", O_RDWR, 0);	if (mtrr_fd < 0)       mtrr_fd =  open("/proc/mtrr", O_RDWR, 0);#endif    /* Enable I/O permissions to directly access I/O ports. We break the     * allocation into two parts, one for the ports from 0-0x3FF and     * another for the remaining ports up to 0xFFFF. Standard Linux kernels	 * only allow the first 0x400 ports to be enabled, so to enable all     * 65536 ports you need a patched kernel that will enable the full     * 8Kb I/O permissions bitmap.     */#ifndef	TRACE_IO	ioperm(0x0,0x400,1);	ioperm(0x400,0x10000-0x400,1);#endif	iopl(3);}long PMAPI PM_getOSType(void){ return _OS_LINUX; }int PMAPI PM_getModeType(void){ return PM_386; }void PMAPI PM_backslash(char *s){	uint pos = strlen(s);	if (s[pos-1] != '/') {		s[pos] = '/';		s[pos+1] = '\0';		}}void PMAPI PM_setFatalErrorCleanup(	void (PMAPIP cleanup)(void)){	fatalErrorCleanup = cleanup;}void PMAPI PM_fatalError(const char *msg){	if (fatalErrorCleanup)		fatalErrorCleanup();	fprintf(stderr,"%s\n", msg);	exit(1);}static void ExitVBEBuf(void){	if (VESABuf_ptr)		PM_freeRealSeg(VESABuf_ptr);	VESABuf_ptr = 0;}void * PMAPI PM_getVESABuf(uint *len,uint *rseg,uint *roff){	if (!VESABuf_ptr) {		/* Allocate a global buffer for communicating with the VESA VBE */		if ((VESABuf_ptr = PM_allocRealSeg(VESABuf_len, &VESABuf_rseg, &VESABuf_roff)) == NULL)			return NULL;		atexit(ExitVBEBuf);		}	*len = VESABuf_len;	*rseg = VESABuf_rseg;	*roff = VESABuf_roff;	return VESABuf_ptr;}/* New raw console based getch and kbhit functions */#define KB_CAPS 	LED_CAP /* 4 */#define KB_NUMLOCK 	LED_NUM /* 2 */#define KB_SCROLL 	LED_SCR /* 1 */#define KB_SHIFT 	8#define KB_CONTROL	16#define KB_ALT 		32/****************************************************************************REMARKS:Restore the keyboard to normal mode****************************************************************************/void _PM_restore_kb_mode(void){	if (_PM_console_fd != -1 && in_raw_mode) {		ioctl(_PM_console_fd, KDSKBMODE, old_kb_mode);		ioctl(_PM_console_fd, KDSETLED, old_leds);		tcsetattr(_PM_console_fd, TCSAFLUSH, &old_termios);		fcntl(_PM_console_fd,F_SETFL,old_flags);		if (_PM_console_fd > 2)			close(_PM_console_fd);		_PM_console_fd = -1;		in_raw_mode = false;		}}/****************************************************************************REMARKS:Safely abort the event module upon catching a fatal error.****************************************************************************/void _PM_abort(	int signo){	char	buf[80];	sprintf(buf,"Terminating on signal %d",signo);	_PM_restore_kb_mode();	PM_fatalError(buf);}/****************************************************************************REMARKS:Put the keyboard into raw mode****************************************************************************/void _PM_keyboard_rawmode(void){	struct termios conf;	if (!in_raw_mode) {		if (ioctl(_PM_console_fd, KDGKBMODE, &old_kb_mode))			perror("KDGKBMODE");		ioctl(_PM_console_fd, KDGETLED, &old_leds);		_PM_leds = old_leds & 0xF;		_PM_modifiers = 0;#ifdef	CHECKED		if (old_kb_mode != K_XLATE)			fprintf(stderr, "Warning: Console is already in raw mode.\n");#endif		tcgetattr(_PM_console_fd, &old_termios);		conf = old_termios;		conf.c_lflag &= ~(ICANON | ECHO | ISIG);		conf.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | BRKINT | PARMRK | INPCK | IUCLC | IXON | IXOFF);		conf.c_iflag  |= (IGNBRK | IGNPAR);		conf.c_cc[VMIN] = 1;		conf.c_cc[VTIME] = 0;		conf.c_cc[VSUSP] = 0;		tcsetattr(_PM_console_fd, TCSAFLUSH, &conf);

⌨️ 快捷键说明

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