Tuesday, May 26, 2009

关于ioremap的一个小发现

关于ioremap的一个小发现

一.环境
二.起因
三.验证
四.结论


一.环境
linux 2.6.18, x86

二.起因
最近在看网卡里关于ioremap的用法。发现8139too.c 和8139cp.c里调用的不是同一个函数。8139too调用的是pci_iomap(),而8139cp调用的是ioremap()。那么这2个函数有什么不同的呢?在http://lxr.linux.no/linux+v2.6.18/lib/iomap.c#L206 里发现了pci_iomap的实现,其中有这么一段:if (flags & IORESOURCE_MEM) { 219 if (flags & IORESOURCE_CACHEABLE) 220 return ioremap(start, len); 221 return ioremap_nocache(start, len); 222 }

也就是说,pci_iomap会调用ioremap或者ioremap_nocache。那么对于8139too来说,到底调用了哪个呢?看上去应该是调用了ioremap_nocache。但是在8139cp里调用ioremap也没有问题啊。难道ioremap和ioremap_nocache一样?但是看他们的实现代码http://lxr.linux.no/linux+v2.6.18/arch/i386/mm/ioremap.c#L191, 2个是不一样的。怎么回事呢?
三.验证
首先验证下8139too是不是调用了ioremap_nocache. 方法是使用QEMU来调试LINUX. 在__ioremap(ioremap的实现)和ioremap_nocache2个地方设置了断点。然后加载8139too。发现确实是先停在了ioremap_nocache 这个地方。
其次,再验证下ioremap_nocache和ioremap是否一样。方法是google。结果发现了下面这个连接:http://lkml.org/lkml/2008/4/27/226
其中已经有了解释:what happened before was that on x86 ioremap() was "lax" about the PTE cachability and just said "writeback cached". That was utterly false for most of the real ioremap()s done by drivers, but it happened to work out fine due to the courtesy of BIOSes setting up UC MTRRs that forced those areas into uncachable.

四.结论
在2.6.18及以前的版本,ioremap_nocache和ioremap结果在x86机器上是一样的。尽管代码看上去不同,但是BIOS通过设置MTRR使得ioremap后的内存也是uncachable的。
在某一个新版本(2008年1月左右),ioremap被改成了不依赖于MTRR保护,显式的设置内存为uncachable。

PS: 我对这方面也不是非常了解,不对的地方大家多指正。

ioremap

http://dev.yesky.com/412/2639912.shtml

http://blog.chinaunix.net/u2/62141/showart_489317.html

Monday, May 25, 2009

Convert physycal address to pfn

Convert a physical address to a Page Frame Number and back*/
//#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
//#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)

Linux, kernel

Thursday, May 14, 2009

A strange ethernet frame

0x33 33 0 0 0 16 52 54 0 12 34 56 “86 dd” 60 0 0 0 0 24 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ff 2 0 0 0 0 0 0 0 0 0 0 0 0 0 16 3a 0 5 2 0 0 1 0 8f 0 3b 22 0 0 0 1 4 0 0 0 ff 2 0 0 0 0 0 0 0 0 0 1 ff 12 34 56

What does "86 dd" mean?

Update: 86 dd means IP V6. :)

Wednesday, May 13, 2009

Set NIC in promisc mode on Linux

manually:
enable:
ifconfig eth0 promisc

disable:
ifconfig eth0 -promisc

automatically:
you can add a line"PROMISC=yes" to the /etc/sysconfig/network-scripts/ifcfg-eth0.or you can add "ifconfig eth0 promisc" to you startup scripts i believe it is /etc/rc.d/rc.local

ref:
http://www.linuxquestions.org/questions/linux-networking-3/set-nic-in-promisc-mode-225256/

Tuesday, May 12, 2009

OutputDebugString on Linux?

OutputDebugString is very easy to use on Windows platform. But it is not availabe on Linux. However, we can use syslog() for similar purpose. Then use tail -f /var/log/messages to watch the log.

Ref:
http://www.ifm-services.com/people/jamesk/papers/kylix/adv_in_kylix-2.php
http://forum.kde.org/outputdebugstring-equivalent-t-46658.html

Also , check man 3 syslog.