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

📄 host-linux.c

📁 bochs : one pc simulator.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  plex86: run multiple x86 operating systems concurrently *  Copyright (C) 1999-2003 Kevin P. Lawton * *  host-linux.c: Linux specific VM host driver functionality * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Lesser General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Lesser General Public License for more details. * *  You should have received a copy of the GNU Lesser General Public *  License along with this library; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */#include "plex86.h"#define IN_HOST_SPACE#include "monitor.h"#include <linux/config.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/mm.h>#include <linux/proc_fs.h>#include <linux/wrapper.h>#include <linux/version.h>#include <asm/irq.h>#include <asm/atomic.h>#ifndef VERSION_CODE#  define VERSION_CODE(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) )#endif#if LINUX_VERSION_CODE < VERSION_CODE(2,4,20)/* I use get_user_pages() to find and pin physical pages of memory * underlying the guest physical memory malloc()'d from user space. * This became an exported symbol available for kernel modules * as of 2.4.20.  You will have to recode some functions for * lesser kernels. */#  error "Currently, you need Linux kernel 2.4.20 or above."#endif#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)#  include <asm/uaccess.h>#endif#include <asm/io.h>/************************************************************************//* Compatibility macros & convenience functions for older kernels       *//************************************************************************/#ifndef EXPORT_NO_SYMBOLS#  define EXPORT_NO_SYMBOLS register_symtab(NULL)#endif#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,29)#  define proc_register_dynamic proc_register#endif#if LINUX_VERSION_CODE < VERSION_CODE(2,2,0)#define NEED_RESCHED need_resched#else#define NEED_RESCHED current->need_resched#endif/* Instrumentation of how many hardware interrupts were redirected * to the host, while the VM monitor/guest was running.  This can be * written to by multiple contexts, so it needs SMP protection. */static atomic_t interruptRedirCount[256];#if LINUX_VERSION_CODE < VERSION_CODE(2,1,0)  static inline unsigned longcopy_from_user(void *to, const void *from, unsigned long n){  int i;  if ( (i = verify_area(VERIFY_READ, from, n)) != 0 )    return i;  memcpy_fromfs(to, from, n);  return 0;}  static inline unsigned longcopy_to_user(void *to, const void *from, unsigned long n){  int i;  if ( (i = verify_area(VERIFY_WRITE, to, n)) != 0 )    return i;  memcpy_tofs(to, from, n);  return 0;}#endif#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,18) && !defined(THIS_MODULE)/* Starting with version 2.1.18, the __this_module symbol is present, * but the THIS_MODULE #define was introduced much later ... */#define THIS_MODULE (&__this_module)#endif/************************************************************************//* Declarations                                                         *//************************************************************************//* Use dynamic major number allocation. (Set non-zero for static allocation) */#define PLEX86_MAJOR 0static int plex_major = PLEX86_MAJOR;#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,18)MODULE_PARM(plex_major, "i");MODULE_PARM_DESC(plex_major, "major number (default " __MODULE_STRING(PLEX86_MAJOR) ")");#endif/* The kernel segment base. */#if LINUX_VERSION_CODE < VERSION_CODE(2,1,0)#  define KERNEL_OFFSET 0xc0000000#else#  define KERNEL_OFFSET 0x00000000#endif/* File operations. */static int plex86_ioctl(struct inode *, struct file *, unsigned int,                        unsigned long);static int plex86_open(struct inode *, struct file *);#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,31)static int plex86_release(struct inode *, struct file *);#elsestatic void plex86_release(struct inode *, struct file *);#endif#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)static int plex86_mmap(struct file * file, struct vm_area_struct * vma);#elsestatic int plex86_mmap(struct inode * inode, struct file * file,                       struct vm_area_struct * vma);#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)/* New License scheme. */#ifdef MODULE_LICENSEMODULE_LICENSE("GPL"); /* Close enough.  Keeps kernel from complaining. */#endif#endif/************************************************************************//* Structures / Variables                                               *//************************************************************************/static int      retrieveKernelModulePages(void);static unsigned retrievePhyPages(Bit32u *page, int max_pages, void *addr,                                 unsigned size);static struct file_operations plex86_fops = {#if LINUX_VERSION_CODE >= VERSION_CODE(2,4,0)  owner:    THIS_MODULE,#endif  mmap:     plex86_mmap,  ioctl:    plex86_ioctl,  open:     plex86_open,  release:  plex86_release,  };#ifdef CONFIG_DEVFS_FS#include <linux/devfs_fs_kernel.h>devfs_handle_t my_devfs_entry;#endif/* For the /proc/driver/plex86 entry. */#if LINUX_VERSION_CODE >= VERSION_CODE(2,4,0) /* XXX - How far back? */int plex86_read_procmem(char *, char **, off_t, int);#elseint plex86_read_procmem(char *, char **, off_t, int, int);#endif#if LINUX_VERSION_CODE < VERSION_CODE(2,3,25)static struct proc_dir_entry plex86_proc_entry = {  0,                  /* dynamic inode */  6, "driver/plex86",     /* len, name */  S_IFREG | S_IRUGO,  /* mode */  1, 0, 0,  0,  NULL,  &plex86_read_procmem,  /* read function */  };#endif#if CONFIG_X86_PAE#  error "CONFIG_X86_PAE defined for this kernel, but unhandled in plex86"#endif/************************************************************************//* Main kernel module code                                              *//************************************************************************/  intinit_module(void){  int err;  /* Initialize structures which are not specific to each VM.  These   * are things which are set only once upon kernel module initialization.   */  memset(&kernelModulePages, 0, sizeof(kernelModulePages));  memset(&interruptRedirCount, 0, sizeof(interruptRedirCount));  /* Register the device with the kernel. */  err = register_chrdev(plex_major, "plex86", &plex86_fops);  if (err < 0) {    printk(KERN_WARNING "plex86: can't get major %d\n", plex_major);    return(err);    }  /* If this was a dynamic allocation, save the major for   * the release code   */  if(!plex_major)    plex_major = err;  /* Register the /proc entry. */#ifdef CONFIG_PROC_FS#if LINUX_VERSION_CODE >= VERSION_CODE(2,3,25)  if (!create_proc_info_entry("driver/plex86", 0, NULL, plex86_read_procmem))    printk(KERN_ERR "plex86: registering /proc/driver/plex86 failed\n");#else  proc_register_dynamic(&proc_root, &plex86_proc_entry);#endif#endif  /* Register /dev/misc/plex86 with devfs. */#ifdef CONFIG_DEVFS_FS  my_devfs_entry = devfs_register(NULL, "misc/plex86",                                   DEVFS_FL_DEFAULT,                                   plex_major, 0 /* minor mode*/,                                   S_IFCHR | 0666, &plex86_fops,                                  NULL /* "info" */);  if (!my_devfs_entry)    printk(KERN_ERR "plex86: registering misc/plex86 devfs entry failed\n");#endif  /* Retrieve the monitor physical pages. */  if ( !retrieveKernelModulePages() ) {    printk(KERN_ERR "plex86: retrieveKernelModulePages returned error\n");    err = -EINVAL;    goto fail_retrieve_pages;    }  /* Kernel independent code to be run when kernel module is loaded. */  if ( !hostModuleInit() ) {    printk(KERN_ERR "plex86: genericModuleInit returned error\n");    err = -EINVAL;    goto fail_cpu_capabilities;    }  /* Success. */  EXPORT_NO_SYMBOLS;  return(0);fail_cpu_capabilities:fail_retrieve_pages:  /* Unregister /proc entry. */#ifdef CONFIG_PROC_FS#if LINUX_VERSION_CODE >= VERSION_CODE(2,3,25)  remove_proc_entry("driver/plex86", NULL);#else  proc_unregister(&proc_root, plex86_proc_entry.low_ino);#endif#endif  /* Unregister device. */  unregister_chrdev(plex_major, "plex86");  return err;}  voidcleanup_module(void){  /* Unregister device. */  unregister_chrdev(plex_major, "plex86");  /* Unregister /proc entry. */#ifdef CONFIG_PROC_FS#if LINUX_VERSION_CODE >= VERSION_CODE(2,3,25)  remove_proc_entry("driver/plex86", NULL);#else  proc_unregister(&proc_root, plex86_proc_entry.low_ino);#endif#endif#ifdef CONFIG_DEVFS_FS  devfs_unregister(my_devfs_entry);#endif}/************************************************************************//* Open / Release a VM                                                  *//************************************************************************/  intplex86_open(struct inode *inode, struct file *filp){  vm_t *vm;#if LINUX_VERSION_CODE < VERSION_CODE(2,4,0)  MOD_INC_USE_COUNT;#endif  /* Allocate a VM structure. */  if ( (vm = hostOSAllocZeroedMem(sizeof(vm_t))) == NULL )    return -ENOMEM;  filp->private_data = vm;    /* Kernel independent device open code. */  hostDeviceOpen(vm);  return(0);}#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,31)  int#else  void#endifplex86_release(struct inode *inode, struct file *filp){  vm_t *vm = (vm_t *)filp->private_data;  filp->private_data = NULL;  /* Free the virtual memory. */  hostUnallocVmPages( vm );  /* Free the VM structure. */  memset( vm, 0, sizeof(*vm) );  vfree( vm );#if LINUX_VERSION_CODE < VERSION_CODE(2,4,0)  MOD_DEC_USE_COUNT;#endif#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,31)  return(0);#endif}  intplex86_ioctl(struct inode *inode, struct file *filp,             unsigned int cmd, unsigned long arg){  vm_t *vm = (vm_t *)filp->private_data;  int ret;  /* Call non host-specific ioctl() code which calls back to this   * module only when it needs host-specific features.   */  ret = hostIoctlGeneric(vm, inode, filp, cmd, arg);  /* Convert from plex86 errno codes to host-specific errno codes.  Not   * very exciting.   */  if ( ret < 0 )    ret = - hostOSConvertPlex86Errno(- ret);  return( ret );}  int#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)plex86_mmap(struct file * file, struct vm_area_struct * vma)#elseplex86_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)#endif{  vm_t *vm = (vm_t *)file->private_data;  UNUSED(vm);  return -EINVAL;

⌨️ 快捷键说明

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