您的位置:首页 > 其它

定位了RTEMS移植CS8900驱动的时候产生的 data abort exception 问题

2013-12-13 15:16 357 查看
之前是照葫芦画瓢,修改了几个结构体的定位,但是我一直觉得,不应该这样去处理的,今天有点时间,又继续研究

这个问题,我感觉是对齐问题,研究结论如下:

确定对齐问题,参考了 freeBSD 8.4 的代码

首先,以太网的头部因为只有14个字节,对于ARM来说,这肯定会出现问题的,所以需要添加 packed属性,让它

按照字节对齐,这样sizeof(ether_header) 的时候是 14,而不加属性的话是 16。freeBSD 8.4的代码中同样是需要

添加这个属性的,rtems不知道为什么这里没有更新。

struct ether_header {

} __packed;

其次是 ip包头结构,这个因为理论上都是4个字节对齐的所以不需要添加也没啥,但是参考 freeBSD 8.4 代码,这里

也添加了吧

struct ip {

} __packed __aligned(4);

最后

-mstructure-size-boundary=32 保持 32bit对齐,这样指令比较高效。

这样还不行,因为原来的驱动有点问题,其实主要是对齐出的问题,不是对齐的话这样写是没有问题的,libchip的其他

网络代码也是这样写,但是这个平台需要点特殊吧。

eh = mtod (m, struct ether_header *);

m->m_data += sizeof (struct ether_header);

首先以太头部指向所有接收缓冲,然后数据指针移动 sizeof (struct ether_header),也就是 14字节了。得到的是 IP

指针,也就是说,如果mbuf本身是对齐的话, IP 偏移了14字节,指针变成了 +0E 这个地址上了,这个地址并不是4字节对齐

在ARM平台上访问结构体成员,会产生错误,data abort exception。这个问题困扰了我很久,我阅读了 ether_input 和

ip_input 函数,对比了 freeBSD,和实验才得出的结果,看来真正的问题应该是这里了。

我的处理办法是将以太网头用一个独立的buffer保存,然后移动IP数据实现4个字节对齐,就不会产生问题了,当然了,

这里只是实验成功,还真的需要好好写驱动。

static char eh_buf[16];

// debug

memcpy(eh_buf, eh, sizeof(struct ether_header));

m->m_data -= 2;

memcpy(m->m_data, m->m_data+2, m->m_len);

eh = (struct ether_header*)eh_buf;

//

ether_input (ifp, eh, m);

目前测试 ping,tcp,http 都是正常的,压力测试还没有做,因为驱动还不是做的很好,ping200次就irq锁死,具体问题

还在定位中,感觉是驱动的问题,和协议栈无关。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: