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

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

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


确定对齐问题,参考了 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锁死,具体问题
还在定位中,感觉是驱动的问题,和协议栈无关。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值