阅读:2000回复:9
又来请教版主问题了
现在偶要写一个怪怪的驱动,这里有几个问题想来问版主
这是做一个驱动的移植,原驱动支持9x/nt/2k等系统。现在偶要在linux下做,版主做移植一定是有经历的啦。 要偶移植吧,主要硬件接口却不让我看到(tnnd的),说是我没有必要知道!@#$$%$%$#%^#%^. 这个驱动的构架是这样的, 1. 底层驱动基本上没有什么硬件操作,只是一个通用框架。 2. 然后做了一个io接口库(应用程序),这里面有部分的硬件操作。另外还有一些操作硬件的东东(无法知道)。 3. sdk封装,提供给用户程序的接口。 偶要第一次在一点不清楚硬件操作的情况(事实上是不给偶看那部分代码,不知道为什么)下作驱动,然后绝大部分硬件操作竟要在应用层做感觉真是很怪,)(&×^¥&^#%¥@。 说了一大堆废话,现在开始切入正题。由于无法修改结构,有些东东在windows下很常见的东东,偶现在不知道在linux下怎么做,特请版主指点一二。 说白了就是驱动移植,而且绝大部分硬件操作要在应用程序里做, 先说下面几个问题 1. 给出用户空间虚拟地址,得到物理地址 PhyAddr=MmGetPhysicalAddress(paddr); 2. 先调用AllocateCommonBuffer得到DmaLgAddr,再把这个地址做映射,得到用户空间层可以访问的虚拟地址。 3. 先pUsrMem=GlobalAlloc(GMEM_FIXED,size); 再据pUsrMem调用IoAllocateMdl得到对应的mdl, 再用这个mdl得到ring0可用的虚拟地址 pSysMem=MmGetSystemAddressForMdl(Mdl); 其实就是用户空间与内核空间共用一块内存吧 4. 资源分配时得到PhyBaseAddr,再转换成总线LgAddr,最后调用 MmMapIoSpace得到驱动程序可以用内存操作命令访问的地址。 (这个到是写驱动一定要做的事,偶会,如果是在Linux中,如果需要做内存映射,通常会象这样得到内核可以访问的虚拟内存地址 BaseAddr = __ioremap( pci_resource_start(pdev,0), pci_resource_len(pdev,0),0 ); ) 不过这里要做的事情是:把这个PhyBaseAddr映射到用户空间可以访问的虚拟地址。 上面的问题就是一些内存映射问题。偶现在只知道到 把得到的PhyBaseAddr转换成BusAddr,再映射到内存来操作 或者是反过来把得到的虚拟地址转换为dma可以操作的地址 但是要应用程序来操作驱动,偶还真没做过(说实话,也不喜欢这样做,被逼无奈哦) 5. windows的驱动是用CreateEvent,WaitForxxxx,SetEvent用事件的方式来通知,linux下类似的机制是怎么样的呢?偶原来在linux下的驱动不去主动通知应用程序。 请版主解惑。偶正努力查资料中 |
|
最新喜欢:flyfox
|
沙发#
发布于:2002-08-20 20:15
所有你这些问题,linux device driver里面都有详细说明,
而且那本书还有中文版。此外,我强烈反对进行虚存到物理 地址的映射,特别是这块内存还有可能是应用层分配的。 现在偶要写一个怪怪的驱动,这里有几个问题想来问版主 |
|
|
板凳#
发布于:2002-08-21 09:34
不是可能,就是应用层分配的。
我怀疑版主没有明白我想问的问题,现在的问题就是物理地址要转换为应用层可用地址,应用层分配的地址也要转成内核程序可用的地址或是转换成硬件dma可用的物理地址。 版主说书上有,偶正在翻(原来也看过好些次了),内存部分应在7,13章吧? 1. get_user,put_user有点象,但这是取数据,送数据吧?这里想得到的是与物理地址对应的虚拟地址或与之相反 2. 事件这堆东东偶没找到:( |
|
|
地板#
发布于:2002-08-21 09:34
偶来看看asm/access.h里有没有好东东
|
|
|
地下室#
发布于:2002-08-21 10:25
不是可能,就是应用层分配的。 我知道你的想法了,这种想法和我在51所见到的做卡驱动 的思路一样-----让我白白浪费了1天时间。 看起来你希望的是应用层通过ioctl给核心发一个地址,然后 核心把这个地址转换成物理地址,然后启动dma,然后中断, 然后hb,然后通知应用层处理结束? 不管dma是分散还是集中方式,都有对齐需求吧?而且你怎么 保证应用层那块内存物理连续,而且对齐?还不能漂移? 当然,也许你可以保证,但是考虑到你的driver是要给大家 用的,并不只是你自己,如果我在你的driver上开发app,我 就会觉得这种要求很过分,因为对齐锁定之类的卡需求,卡 驱动本来应该对我屏蔽的。 为什么不在driver中开一块连续物理内存?每次应用层给核心 发请求的时候都做一遍内存拷贝,处理完成之后再做一次内存 拷贝?内存拷贝就是大约5条汇编指令。这样多安全?而且因为 driver中处理不可能并发,所以只需要一块这样的物理内存就 行了。而app分配的话,第一是要求很无理,多半app也需要自己 分配一个这样的内存池,每次都需要在app先做内存拷贝,把数据 拷贝到池中的某块之后才能发ioctl,app是可以并发的,那么还 需要管理这个内存池。 |
|
|
5楼#
发布于:2002-08-21 10:57
没错,就是版主说的这个意思
1. 关于内存分配 事实上我根本就不赞同这种做法,但问题是我现在只能这样做,看清楚,硬件操作有很大一部分没有给我开放出来。 这里其它的卡的驱动都不是这样做的,就这一块卡特别,现在偶就是要这么做。 我本来的想法是根本就不按这个构架来做,但是我无法得到硬件处理的全部操作。 看来版主应该是有经验的了,说来听听?偶到现在都还没有找到。 当然这样的驱动做出来,我是不打算维护的,不过现在我必须要做。 其实问题说简单一点,就是开一个共享内存,然后硬件可以做dma,驱动,应用层都可以访问,基本上就是这个意思了。 2. 关于event, 版主对此不以为然,一定是很清楚了。我的想法其实就是要在linux驱动里通知应用层。进程间的通信方式好象都是应用层之间的信息交互吧?在windows上通知我清楚,不过linux下的通知偶现在还没搞清楚,版主还是给那么一点点的提示吧。 |
|
|
6楼#
发布于:2002-08-21 12:11
关于第二个问题,好象可以用异步io,版主说的是不是第五章异步io?
fasync_helper,或是kill_fasync来通知上面? |
|
|
7楼#
发布于:2002-08-21 12:23
关于第二个问题,好象可以用异步io,版主说的是不是第五章异步io? 看起来你并不需要特别的通知机制,而且应该每次都是应用层 先发起硬件操作请求,然后硬件处理,最后driver完成应用层 的请求。 我猜想你也许是想应用层发起请求之后立即返回,然后某个 时候硬件完成操作之后通知应用层。当然你可以用异步,但是 千万不要用那种请求和通知消息无关的处理方法。这样代码非常 难以维护。我见到过有人在98下发请求之后,driver里面立即 返回,然后完成之后用shell_post_msg通知应用层。linux下面 没有这种机制,不过我想你总是能够找到一个替代方案,但是 我绝对不赞成这样做。因为这样做极度的垃圾。不过你现在 也并不打算维护这些代码,看起来你只是要写出来能够工作, 然后就卷一笔银子就走:-)。你自己决定吧。 你说的具体第几章,我手头上没有这本书,我记不太清楚了。 最近被单位拘回来了,目前正在埋头学习e语。 |
|
|
8楼#
发布于:2002-08-21 13:30
版主怎么想起学英文了?考了g,t等东东也没用吧?一定不会放你出国吧?看来是下有政策,上有对策,heihei.还是得换个方法。。。。。。。。。。
版主,关于第一类问题,有没有什么方案啊? 我的意思并不是那个意思,而是按那种方案我可以试着做,但一定不会去负责。 偶想把现在的架构推翻,把那些在应用层做的东东拿到驱动里面来,这样就不会有这许多乱七八糟的问题了。 |
|
|
9楼#
发布于:2002-08-21 14:54
hoho,在13章里好象有关于第一个问题的东东,偶来研究研究
|
|
|