许多人担心CE6驱动的向后兼容性。在CE6上,应用程序和OAL可以比较良好的兼容,但驱动就比较难。驱动在移植到CE6上必须做一定的修改,原封不动的放到CE6上运行是不太可能的。

驱动需要修改的主要原因:

1、  API的差异

2、  内存传递

3、  Buffer异步访问

4、  用户层接口处理

CE6驱动的最大差异在于内嵌指针和数据传递,这个在《Memory marshalling in Windows CE》有详细描述。有2个主要修改点:

1、  找出所有代码有映射函数,如MapCallerPtr和MapPtrToProcess,改为CeOpenCallerBuffer / CeCloseCallerBuffer。

2、  找出SetKMode、SetProcPermissions的地方,有异步访问的,修改为CeAllocAsynchronousBuffer / CeFreeAsynchronousBuffer。

其次查找UI相关的函数,内核中不允许驱动运行UI相关功能(显示UI)。CE6中,几乎所有驱动都运行在内核中。即使是用户态驱动,最好也使用kernel UI handling方式来处理UI。CE6中,驱动一旦使用UI相关的功能,就会切入到一个用户态的DLL。所有的资源、shell call等,都会带入到此DLL中。使用CeCallUserProc 会较为方便。

BOOL CeCallUserProc(
LPCWSTR pszDllName,
LPCWSTR pszFuncName,
LPVOID lpInBuffer, DWORD nInBufferSize,
LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned);

这个函数类似调用IOCTL来得到LoadLibrary 和 GetProcAddress的整合功能。当驱动在内核态调用此函数,udevice.exe实例中将会加载一个DLL。如果驱动在用户态调用此函数,也会在同个udevice.exe实例中加载此DLL,那么用户态和内核态驱动,在使用这个函数时候没有什么区别了。

CeCallUserProc和IOCTL之间最大区别在于,CeCallUserProc不允许内嵌指针。传入数据必须放在inbuffer参数中,而 传出数据只能放在outbuffer中,而不能通过内嵌指针再获取数据。问题是当内核调用用户层代码时,用户层无法同个 CeOpenCallerBuffer或其他方法获取内核内存的大小。所以用户态不允许访问内核态的内存。

还有,当使用新的内存重建函数和CeCallUserProc,修改驱动时。最好注意是否需要做安全备份和异常处理,如上文所提。现在驱动都在内核态下,必须要保证系统的安全和稳定。

用户态驱动:

CE6具有用户态驱动进程,udevice.exe。用户态驱动和内核驱动一样,应用层可以使用ActivateDevice(Ex)和 DeactivateDevice函数。设备管理器会读取注册表来判断驱动,是否需要运行在用户态。可以使用注册表指定udevice.exe的ID值, 让同一个进程加载多个用户态驱动。

例如,一个用户态驱动的驱动组ID为3,那么多个驱动都可以加载到这个组中。在CE6 %_WINCEROOT%/public/common/oak/files/common.reg中注册表,可以看到驱动组是怎样配置,驱动是怎样归纳到驱动组中的。如下:

[HKEY_LOCAL_MACHINE/Drivers/ProcGroup_0003]

"ProcName"="udevice.exe"

"ProcVolPrefix"="$udevice"

; Flags==0x10 is DEVFLAGS_LOAD_AS_USERPROC

[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Ethman]

"Flags"=dword:12

"UserProcGroup"=dword:3

[HKEY_LOCAL_MACHINE/Drivers/Console]

"Flags"=dword:10

"UserProcGroup"=dword:3

[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/SIP]

"Flags"=dword:10

"UserProcGroup"=dword:3

如果你不配置这个,那么会单独由一个udevice来加载此驱动。系统将会有多个udevice进程。

设备管理器会创建一个转接服务来协助用户态驱动。转接服务负责加载udevice,加载特殊卷标,注册文件系统。应用程序和用户态驱动,通过转接服务进行buffer marshalling,来相互通讯。同时转接服务也会帮助用户态驱动做用户态上无法实现的工作,如映射物理内存等。

我们希望用户态和内核态驱动能达到完全一致,但内核态总是比用户态有更多的权限。不断改进的内核功能,将会使内核态驱动更难移植为用户态驱动。

另外,如前文所提。用户态驱动不能异步的回写指针参数,甚至可以认为,用户态不能异步访问caller的内存。最好把需要异步访问的驱动放到内核态,或者修改框架,让驱动不要异步访问caller。

还有,用户态驱动不能从内核中获取内嵌指针, CeCallUserProc也不支持内嵌指针。如果驱动需要从内核态获取内嵌指针,那么只能把此驱动放到内核中运行。或者修改驱动,不使用内嵌指针,而是调用CeCallUserProc让内存传递通过简单的in/out buffer来传递。

有些函数在用户态是必须注意使用的,如VirtualCopy和类似的MmMapIoSpace。用户态程序不允许使用VirtualCopy,但是用户 态能通过转接服务来实现这功能。转接服务能代替用户态驱动来调用VirtualCopy,但是前提是转接服务要知道这些地址是可以访问的。在驱动的注册表 入口,键值IOBase和IOLen来指出地址的位置和大小。当驱动使用VirtualCopy来,转接服务会检查这些键值,确保驱动能正常访问这些物理 地址。下面是串口驱动的例子:

[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Serial]

"IoBase"=dword:02F8

"IoLen"=dword:8

如果只有一块地址需要访问,使用dword类型。如果是多块地址,那么使用multi_sz类型。

[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Serial]

"IoBase"=multi_sz:"2f8","3f6"

"IoLen"=multi_sz:"8","2"

由于这些地址只能被有特权的应用程序访问,那么需要确保这些地址不能被非特权程序访问。

用户态驱动不能调用以下函数:

1、  VM虚拟内存函数:VirtualCopy[Ex], LockPages[Ex], CreateStaticMapping

2、  中断函数:InterruptInitialize, InterruptDone, LoadIntChainHandler

3、  不能直接使用IISR,需要通过转接服务来做GIISR。

4、  OAL层的IOCTL不能直接使用。

禁止从用户态驱动回调任何进程。你不能在总线驱动中回调一个内核态的client驱动。如果一个总线驱动放到用户态运行,只能把总线上的client驱动也放到用户态中。那么这个总线上所有的client驱动,都必须和总线驱动放到同一个udevice进程中。

有些OEM厂商可能会把一些OAL IOCTL和函数,通过编写特有的转接服务,让内核态驱动提供给用户态使用。值得注意的是,通过内核态驱动来公开这些功能,实际上是公开了微软特意封装的内容,最好不要这样使用。

CE6 驱动: 你不得不知道的事情相关推荐

  1. 自2018年以来我不知道的事情-Dan Abramov

    原文地址哈:https://overreacted.io/things-i-dont-know-as-of-2018/ 人们常常假设我知道的知识远比实际知识道的多.我不抱怨这个错误的想法.(拥有些许成 ...

  2. 读书 | 5件富人都在做穷人却不知道的事情

    作者 | 杨小爱 习惯,就是我们长期以来养成的行为方式,这是美国作家托马斯科里在<富有的习惯>一书中对习惯的定义. 而我对习惯的理解就是,习惯就好像我们每天起床后会自然而然的去洗脸刷牙一样 ...

  3. JavaScript 日期操作我不知道的事情

    平时对 Date 很多内容都一知半解,每次一用到 Date 就需要查资料,着实恼火. 故此文记录关于 JS 日期操作那些我不知道的事. 基础问题 Date.prototype.getTime() 返回 ...

  4. 要想步入程序开发行列,就不得不知道的事情汇总

    前言 当迈入程序开发行列之后,就意味着从此与程序开发"相依为命".不管你已经迈入程序开发行列,还是即将迈入,一些做程序开发必知内容是需要提前知道的.尤其是打算做程序开发的大学生朋友 ...

  5. 你的QQ号又被盗了?关于网络安全你所不知道的事情

    不知道大家是否有这样一个经历: 就是大家的qq好像被别人登录了一样,群发给朋友,向朋友借钱的消息,有些身边的朋友还被骗取了大量的金额,别人又是如何知道自己的密码的呢? 现在都0202年了,想说的是QQ ...

  6. 祝贺!屠呦呦再获国际大奖!一文读懂:神药青蒿素那些我们不知道的事

    又有好消息传来!总部位于法国巴黎的联合国教科文组织10月22日公布2019年度联合国教科文组织-赤道几内亚国际生命科学研究奖获奖名单,共3人获奖,其中包括来自中国的屠呦呦. 此前,屠呦呦先后拿下多项大 ...

  7. 关于多线程编程您不知道的 5 件事 有关高性能线程处理的微妙之处

    虽然很少有 Java™ 开发人员能够忽视多线程编程和支持它的 Java 平台库,更少有人有时间深入研究线程.相反地,我们临时学习线程,在需要时向我们的工具箱添加新的技巧和技术.以这种方式构建和运行适当 ...

  8. 关于PHP你可能不知道的10件事

    小编之前也曾报导过PHP开发人员容易忽略的几点精华,除了一些精华技术方法外,很多细微之处也是程序员们容易忽略的,下面我们为您总结了10个关于PHP你可能不知道的事情. 关于PHP更多内容,欢迎访问:P ...

  9. 系统调优,你所不知道的TIME_WAIT和CLOSE_WAIT

    https://my.oschina.net/fdhay/blog/638631 高性能网络 | 你所不知道的TIME_WAIT和CLOSE_WAIT 2016-02-18 大房 大房说 本文是我将最 ...

最新文章

  1. mysql5.5.9_mysql5.5.9字符集设置
  2. ACE proactor example
  3. 2.1 Java程序的构成
  4. Java入门需掌握的30个基本概念[转]
  5. 后端技术:Java程序员常用的11个API,你都知道吗?
  6. Combox使用的一些技巧
  7. [css] 你知道css的预处理器和后处理器都有哪些吗?它们有什么区别呢?
  8. node.js 针对不同的请求路径(url) 做出不同的响应
  9. 作者:鄂世嘉,男,同济大学博士生,CCF学生会员。
  10. linux下删除cmake_ubuntu 16.04 + cmake 升级
  11. flutter 人脸检测_Flutter - 通过指纹和人脸识别认证
  12. 收购小蓝单车部分资产、与ofo蜜月期结束,滴滴重构共享单车布局
  13. Ortholab has been moved to Google Code
  14. android activity 主题,android activity 主题
  15. 外挂技术之-检测和反检测
  16. libGDX游戏开发之NPC敌人事件(六)
  17. 百度指数、淘宝指数学习笔记
  18. Mysql主从同步时Slave_IO_Running:Connecting ; Slave_SQL_Running:Yes的情况故障排除
  19. 蓝牙相关Profiles
  20. DB-RANK国内数据库权威排行出炉:OMS三足鼎立,达梦数据库排第七

热门文章

  1. linux下如何开发php,在linux下开发PHP,用哪个系统?该如何解决
  2. android设备唯一码的获取之二
  3. 【算法】决策树模型 集成算法模型GBDT
  4. 真正爱你的男孩(女孩必看)转
  5. 在windows下进行Openvidu webAPP开发
  6. 学了点Java IO的小菜菜,写了个文字字频统计
  7. 情人节相约曼谷,来一场浪漫旅行
  8. 【图片压缩】把图片的kb变小
  9. potplayer 64位 官网下载地址
  10. mysql barracuda_MySQL Antelope和Barracuda的区别分析