Friday, March 12, 2010

终于解决了一个困扰了1周多的问题

要实现的功能不是很复杂,就是在SMM 下面操纵下网卡。

一开始在QEMU虚拟机里调试,还算比较顺利。想明白了之后,自己用汇编写个小程序,又写个小LOADER就实现了。这时心情很好,自信心也很足,剩下的就是把代码移植到一台真正的物理机器上了。

谁知道,恶梦开始了。在QEMU里跑的好好的程序在物理机器上就是不行。没办法,又重新看网卡SPEC,然后用各种方法,加了N多调试,始终不行。之前我努力的重点是看在操作网卡的时候有没有漏掉什么。因为我怀疑QEMU虚拟的网卡和真实的差别比较大。另外,我在我的SMI里把用到的数据都读出来,验证过,证明数据都是没有错的。于是继续怀疑网卡。同时又看了一堆LINUX 网卡实现方面的东西。

搞了好几天,还是不行,十分沮丧,差点都不想搞了。不过老板在后面逼着,不搞不行。于是接着想其他方法。后来又想到,也许是SMM的问题。如果我在 LINUX环境下用SMM里同样的方法操作下网卡,看看是否能得到想要的结果。如果可以,那么就是SMM的问题,如果不行,那么是我的程序在网卡设置什么地方不对。又改了下小程序,试了试,发现在LINUX中是可以的。也就是我操作网卡的地方没错。那么就是SMM的问题了。是什么问题呢?突然想到,我是把网卡的 TX_DESC之类的东西放在SMRAM里面的,难道网卡DMA的时候,读不到 SMRAM?于是接着改程序,把TX_DESC放到系统内存里。

再次怀着紧张的心情试了下,成了!!!!!!!!!!!!!!!!!!!!!!!!!

结论就是,网卡DMA的时候果然访问不到SMRAM里面的东西。其实这个我觉得还是有点奇怪的。也许只是适用我实验的那台老机器。按理说,我SMRAM也没加锁,而且又是在SMM模式下操作的网卡,PCI卡应该能访问到SMRAM才对啊? 不过也无所谓了,反正放到普通RAM里也一样。

PS:在这个过程中,顺手解决了一堆小BUG, 比如SMI只能触发一次啦。在SMM和OS之间没法利用共享的内存通信啦,如何检测网卡内部FIFO状态啦等等,呵呵。还是学到了不少东西。

No comments: