Bikky
驱动牛犊
驱动牛犊
  • 注册日期2003-12-01
  • 最后登录2017-02-21
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望11点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1435回复:5

内存映射问题....

楼主#
更多 发布于:2004-02-03 14:34
各位大虾,小弟最近在调一块老ISA板的驱动,那板上有一双口RAM,提供给PC机的地址是0xE000,即要求用内存映射访问.我用的是NT式非即插即用驱动,没用DriverWorks写,我认为就那么一个卡,直接用DDK写简单些.但现在在内存映射方面出问题了,我在驱动入口例程中用MmMapIoSpace函数将0xE000地址映射成了可以使用的指针,打印出来是0xF09E4000,我也可以用应用程序在这个地址上读写,但我把卡拔掉后还是能在这个地址上读写,就是说PC机没把数据写到板上的双口RAM中,我用示波器观察ISA接口的MEMW引脚也没看到低电平,就是说PC机跟本没往卡上写数据.

我在其它参考书上看到实例是这样做的:在驱动入口例程中先构造一个资源列表,然后用ReportResourceUsage函数通知内核要用哪些资源,这一步我没做,我认为没必要.然后用TrancelateBusAddress函数转换总线地址,它说看返因的AddSpace变量的值看是否有必要再进行内存映射,这一点不大明白,是IO地址还是内存地址是编写驱动的人自己决定的,怎么还要看内核的某个返回值再动态决定是否要再进行内存映射呢?有谁能帮我解释一下那个TrancelateBusAddress函数的用法吗?

买了一些书,都是讲WDM或DriverWorks的,没讲NT式驱动的,也不怎么讲驱动程序内部原理,更找不到ISA接口的实例,倒是PCI和USB的实例到处都是,真是头痛,哪位好心人帮我回答一下上面的问题,可送200分,不胜感激!!!

最新喜欢:

fueanafueana
百克
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
沙发#
发布于:2004-02-04 08:58
各位大虾,小弟最近在调一块老ISA板的驱动,那板上有一双口RAM,提供给PC机的地址是0xE000,即要求用内存映射访问.我用的是NT式非即插即用驱动,没用DriverWorks写,我认为就那么一个卡,直接用DDK写简单些.但现在在内存映射方面出问题了,我在驱动入口例程中用MmMapIoSpace函数将0xE000地址映射成了可以使用的指针,打印出来是0xF09E4000,我也可以用应用程序在这个地址上读写,但我把卡拔掉后还是能在这个地址上读写,就是说PC机没把数据写到板上的双口RAM中,我用示波器观察ISA接口的MEMW引脚也没看到低电平,就是说PC机跟本没往卡上写数据.

我在其它参考书上看到实例是这样做的:在驱动入口例程中先构造一个资源列表,然后用ReportResourceUsage函数通知内核要用哪些资源,这一步我没做,我认为没必要.然后用TrancelateBusAddress函数转换总线地址,它说看返因的AddSpace变量的值看是否有必要再进行内存映射,这一点不大明白,是IO地址还是内存地址是编写驱动的人自己决定的,怎么还要看内核的某个返回值再动态决定是否要再进行内存映射呢?有谁能帮我解释一下那个TrancelateBusAddress函数的用法吗?

买了一些书,都是讲WDM或DriverWorks的,没讲NT式驱动的,也不怎么讲驱动程序内部原理,更找不到ISA接口的实例,倒是PCI和USB的实例到处都是,真是头痛,哪位好心人帮我回答一下上面的问题,可送200分,不胜感激!!!


IoReportResourceUsage的用途是宣称(claim)某些硬件资源已经为自己所使用,不能被分配给之后加载的驱动。只有非PnP的设备驱动(NT式驱动)才需要调用它。

至于IO地址还是MEM地址,是由硬件决定的,驱动程序需要进行判断,所以才说要判断AddressSpace变量的值看是否有必要再进行内存映射。只有MEM地址才需要用MmMapIoSpace来映射。
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
Bikky
驱动牛犊
驱动牛犊
  • 注册日期2003-12-01
  • 最后登录2017-02-21
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望11点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2004-02-04 09:54
楼上老大,还有一事不明:
  IO地址或MEM地址是由硬件设计者决定的,但现在驱动开发者也知道哪个是IO地址,哪个是MEM地址,那么在写驱动程序时就不必等待内核的那个返回值AddressSpace了,是MEM地址就直接映射,是IO地址就直接访问,那么HalTranslateBusAddress那个函数也可不用了,对不对?
百克
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
地板#
发布于:2004-02-04 10:34
楼上老大,还有一事不明:
  IO地址或MEM地址是由硬件设计者决定的,但现在驱动开发者也知道哪个是IO地址,哪个是MEM地址,那么在写驱动程序时就不必等待内核的那个返回值AddressSpace了,是MEM地址就直接映射,是IO地址就直接访问,那么HalTranslateBusAddress那个函数也可不用了,对不对?


BusAddress是总线相对地址. DRIVER不能使用这个相对地址, 因为它不是唯一的. 比如PCI 0和PCI 1都可以有一个相对地址0xC0000. 所以, DRIVER要调用HalTranslateBusAddress把这个总线(BusNumber)相对地址映射为一个唯一的系统逻辑地址TranslatedAddress.

AddressSpace 是一个IN OUT参数. 0x00表示MEMORY SPACE, 0x01表示IO SPACE. 给这个参数赋值的时候要根据你 DEVICE 的类型来赋. 一个DEVICE是MEMORY SPACE还是IO SPACE是由硬件设计决定的. 换句话说, DEVICE定了, IO方式也就定了, 不可以改的. 那为什么这个参数还是个OUT呢? 这是因为HAL对这个ADDRESS MAPPING它自己的解释. 比如MIPS机器根本就没有IO SPACE, 只有MEMORY SPACE, 所以即使DEVICE是IO SPACE, HAL还是会在MIPS上把它映射成MEMORY SPACE. 而在X86机器上, IO SPACE还会映射成IO SPACE,因为X86支持IO SPACE.
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
soycola
驱动牛犊
驱动牛犊
  • 注册日期2001-09-19
  • 最后登录2007-03-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-02-12 01:27
seaquest大侠解释的很精彩,不过就这个问题而言,除了利用MmMapIoSpace获取线性地址以外,实际上可以利用nt在地址映射上的一个特点:nt将物理地址0~4M用一个large page directory entry来映射,这个large pde的线性地址是0x80000000,也就是说你可以用指针(char*)0x800e0000来访问你的dpram,由于这个4m的区域是ntoskrnl以及分页池等关键系统代码和数据的所在地所以总是被映射到所有进程的地址空间并且不被换出的,所以你不用执行任何额外的映射工作,唯一需要考虑的就是cache一致性,不过我不太清楚nt对这个是怎么解决的
soycola
驱动牛犊
驱动牛犊
  • 注册日期2001-09-19
  • 最后登录2007-03-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-02-12 01:30
才发现driverdev论坛居然用的是greenwich时间,呵呵,其实现在都已经深夜1点多了,不知道有几个夜猫子还在上头挂着呢
游客

返回顶部