QNX又一庄让人苦笑不得的糗事。。。。

这些天一直在写QNX 6.4.0下的82573E网卡驱动,居然又碰到一件怪事。
我可以使用mmap结合mmoffset函数根据虚拟地址得到物理地址。
但是。。。。居然没有函数能够实现物理地址到虚拟地址的转换。。。。。。

晕哦。。。。有人知道怎么实现QNX下物理地址到虚拟地址的转换么?

呵呵,别着急,先歇口气,再慢慢想想,你确信你需要一个物理地址到虚拟地址的"转换"函数吗?

在使用DMA时,如果没有物理地址转换到虚拟地址的函数,意味着我无法直接对
物理地址进行读取。那么我只能祈祷QNX在给我分配物理地址时,虚拟地址是
同样方向连续的,而且长度必须相等。

在目前来看,我的祈祷QNX是做到了,在仅仅开16KDMA空间的情况下。
如果开到1G,我还没试啊。。。。

不过物理地址转虚拟地址的函数,大多数操作系统都有。
QNX为什么不提供呢?这个和所谓系统安全应该不靠边吧。

不要失去信心嘛,看看mmap的帮助。一般在QNX在只做物理内存到虚拟内存的影射,然后,自己记来下就是了。
这两个例子有帮助吗?!

To share memory with hardware such as video memory on an x86 platform:

/* Map in VGA display memory */
addr = mmap( 0,
65536,
PROT_READ|PROT_WRITE,
MAP_PHYS|MAP_SHARED,
NOFD,
0xa0000 );To allocate a DMA buffer for a bus-mastering PCI network card:

/* Allocate a physically contiguous buffer */
addr = mmap( 0,
262144,
PROT_READ|PROT_WRITE|PROT_NOCACHE,
MAP_PHYS|MAP_ANON,
NOFD,
0 );

在DMA时,你需要的是“物理上连续的”(Physically Contiguous)内存。

POSIX函数mmap()就是用来向系统申请内存的。看看这个函数说明中的MAP_PHYS的说明吧。当与MAP_ANON连用时,系统保证返还给你一块“物理连续“空间。你接着用 mem_offset()取得返回指针的物理地址,你就能轻易取得至整块空间任何地址的物理地址与虚拟地址的对应关系。把物理地址交给DMA控制器就可以了。

既然你在写网卡驱动,为什么不拿一个QNX现存的网卡驱动,看看它们是怎么做DMA的呢?

顺便说一句,mmap()根据FLAGS,也可以直接给出物理地址和长度,返回一个虚拟地址指针的。这也可以算是”物理地址到虚拟地赴“的转换了吧。

最后,你提到在写82573E驱动。在Foudry27上,e1000驱动的原码已经贴出来了,直接拿来用应该就可以了。当然你要重新编译一下。

http://community.qnx.com/integration/viewcvs/viewcvs.cgi/trunk/sys/dev_qnx/e1000/?root=core_networking&system=exsy1001

82573E我的需求比较特殊,是要求网卡处于混杂模式对整个网络进行监听。
所以,只好自己写一个。

谢谢xtang,你的回复很有帮助。

目前可以确定QNX确实在使用mmap后物理地址和虚拟地址是线性一致的。
但是,没这个函数确实让人不爽罢了。。。。。