WinCE6.0中应用程序如何直接访问物理空间

简介: 在实际开发过程中,经常希望能在应用程序中直接读写设备的物理空间。以前在做WinCE6.0下的MEMMgr时通过秘密加载一个内核态驱动实现了这个需求。但这种方式有一个明显的缺陷,每次读写都必须经由它才能完成。

      在实际开发过程中,经常希望能在应用程序中直接读写设备的物理空间。以前在做WinCE6.0下的MEMMgr时通过秘密加载一个内核态驱动实现了这个需求。但这种方式有一个明显的缺陷,每次读写都必须经由它才能完成。如果只是读取GPIO,那问题不算大。如果想通过这种方式实现视频播放的加速就比较困难了。估计非但不能加速,反而会变得更慢。

      早先曾与ZL仔细的讨论过这个问题,他当时在WinCE6.0上移植TCPMP,发现播放视频不太流畅,于是想通过直接写显存进行加速。目的很明确,在应用中申请一段虚拟空间,通过某种方法将其映射到显存上,视频解码过程中直接往映射过的虚拟空间上写。这种方法与使用GAPI有一点类似。

      实现这个需求,需要用到函数VirtualCopyEx()。看看帮助中关于它的说明,This function dynamically maps a virtual address to a physical address by creating a new page-table entry.This function is callable in kernel mode and in user mode, when the source and destination process handles are the active process.This function is similar to VirtualCopy, except VirtualCopyEx requires handles to the source and destination process.

      据此基本可以确定,我们的确可以在应用中申请一段虚拟空间,然后通过这个函数将其映射到某段物理空间上。其中目标进程是我们的应用,而源进程是NK.exe。为了实现在NK.exe中执行VirtualCopyEx(),可以加载一个内核态的驱动。更为方便的方法是移植一个OALIOCTL,并在IOControl()中添加一个case。这样,应用程序在做内存映射时就无需打开某个流驱动,直接调用KernelIoControl()即可。

      OALIOCTL中添加的关键代码如下。 

 1  typedef  struct  {
 2       void *     pvDestMem;
 3      DWORD    dwPhysAddr;
 4      DWORD    dwSize;
 5  } VIRTUAL_COPY_EX_DATA;
 6 
 7  #define  IOCTL_VIRTUAL_COPY_EX CTL_CODE (FILE_DEVICE_UNKNOWN,3333,METHOD_BUFFERED,FILE_ANY_ACCESS)
 8 
 9 
10  case  IOCTL_VIRTUAL_COPY_EX:
11  {
12      VIRTUAL_COPY_EX_DATA  * =  (VIRTUAL_COPY_EX_DATA * )pInBuf;
13      HANDLE hDst  =  (HANDLE)GetDirectCallerProcessId();
14      HANDLE hSrc  =  (HANDLE)GetCurrentProcessId();
15      fRet  =  VirtualCopyEx(hDst,p -> pvDestMem,hSrc,(LPVOID)p -> dwPhysAddr,p -> dwSize,
16      PAGE_READWRITE | PAGE_PHYSICAL | PAGE_NOCACHE);
17  } break ;

       应用程序中进行内存映射的关键代码如下。

 1  volatile  LPVOID GetVirtual(DWORD dwPhyBaseAddress, DWORD dwSize)
 2  {
 3       volatile  LPVOID pVirtual;
 4      VIRTUAL_COPY_EX_DATA vced;
 5      
 6       if (dwPhyBaseAddress & 0xFFF )
 7      {
 8           return  NULL;
 9      }
10      vced.dwPhysAddr  =  dwPhyBaseAddress >> 8 ;
11      pVirtual  =  VirtualAlloc( 0 ,dwSize,MEM_RESERVE,PAGE_NOACCESS);
12      vced.pvDestMem  =  pVirtual;
13      vced.dwSize  =  dwSize;
14      KernelIoControl(IOCTL_VIRTUAL_COPY_EX, & vced,  sizeof (vced), NULL, NULL, NULL);
15       return  pVirtual;
16  }
17 
18  //  WinCE6.0模拟器中应用程序直接写屏
19  PBYTE pLCDBuf  =  (PBYTE)GetVirtual( 0x33f00000 , 0x100000 );
20  memset(pLCDBuf, 0 , 0x100000 );
21 

       这种方法在WinCE6.0的模拟器中测试了一下,能达到预期的效果。

目录
相关文章
|
存储 Unix 数据处理
【操作系统】文件的结构和组织
【操作系统】文件的结构和组织
405 0
|
6月前
|
存储 算法 程序员
操作系统(12)----页面分配策略
操作系统(12)----页面分配策略
123 1
|
6月前
|
存储 缓存 安全
操作系统(14)----文件系统的结构
操作系统(14)----文件系统的结构
120 1
|
测试技术 虚拟化
在同一物理服务器上同时运行多个独立的操作系统实例
在同一物理服务器上同时运行多个独立的操作系统实例
400 1
|
6月前
|
存储 缓存 Linux
|
12月前
|
存储 Java 关系型数据库
操作系统中文件系统的实现和分配方式探析(下)
本文介绍了非连续空间存放方式中的两种常见形式:链式分配和索引分配。链式分配通过链表的方式实现了文件的非连续分配,其中包括了隐式链接和显式链接两种方式。隐式链接通过遍历链表来获取下一个节点的指针,适合于文件的扩展,但查找效率较低。显式链接则将指针存储在文件分配表中,提高了检索速度,但不适用于大磁盘空间。索引分配通过为每个文件创建索引数据块,实现了文件的非连续分配和直接访问。多级索引和链式索引块是处理大文件存储的组合方式,提高了文件系统的性能和可靠性。通过深入了解这两种分配方式,可以更好地理解和应用非连续空间存放技术,从而有效提高文件系统的管理效率和性能。
157 1
操作系统中文件系统的实现和分配方式探析(下)
|
12月前
|
存储 缓存 Java
操作系统中文件系统的实现和分配方式探析(上)
本文主要讨论了操作系统中文件系统的实现和分配方式。首先介绍了虚拟文件系统(VFS)作为中间层,统一了不同文件系统的接口。然后介绍了文件的物理结构,包括文件块和逻辑块之间的映射关系。接着详细讨论了连续分配方式的特点和优缺点,包括顺序访问和随机访问的效率,以及磁盘空间碎片和文件长度扩展不方便的问题。最后提到了非连续分配方式来解决连续分配方式的问题,并留下了下次讨论的悬念。文件系统的实现和分配方式对于操作系统的性能和可靠性都有重要影响,因此深入理解和研究文件系统的原理和机制是非常有价值的。
143 0
操作系统中文件系统的实现和分配方式探析(上)
|
存储 算法 Unix
第八章 磁盘存储器的管理 【操作系统】
第八章 磁盘存储器的管理 【操作系统】
294 0
|
算法
【操作系统】第三章:计算机体系结构及内存分层体系(Part2:连续物理内存分配)
【操作系统】第三章:计算机体系结构及内存分层体系(Part2:连续物理内存分配)
227 0
【操作系统】第三章:计算机体系结构及内存分层体系(Part2:连续物理内存分配)
|
存储
操作系统分配存储时网络无法正常连接
操作系统分配存储时网络无法正常连接
60 0