easydss与linux内核接收网络数据流程(二)

来源:互联网 发布:网面白鞋怎么清洗知乎 编辑:程序博客网 时间:2024/05/17 23:14

     以DM9000网卡为例,剖析从网卡硬件中断开始,直到tcpudp应用层读取到数据的过程

一  DM9000网卡驱动(这里我们仅仅分析最主要的流程,具体驱动程序可以自行阅读)

static struct platform_driver dm9000_driver = {

.driver = {

.name    = "dm9000",

.pm  = &dm9000_drv_pm_ops,

.of_match_table = of_match_ptr(dm9000_of_matches),

},

.probe   = dm9000_probe,

.remove  = dm9000_drv_remove,

};

网卡驱动标准

网卡驱动入口:dm9000_probe

网卡驱动出口:dm9000_drv_remove

(1) dm9000_probe

-->platform_get_irq() 注册一个中断,中断响应函数,dm9000_wol_interrupt()读取NSR,WCR寄存器

ndev->netdev_ops = &dm9000_netdev_ops;//设置网卡操作接口

-->register_netdev()

(2) 打开网卡dm9000_open()

注册收发数据中断 

dm9000_interrupt()

{

dm9000_rx(dev);//收数据中断处理

dm9000_tx_done(dev, db);//数据发送完中断处理

}

dm9000_rx()

{

netdev_alloc_skb();//申请skb

netif_rx();//处理skb

}

netif_rx(skb)

{

netif_rx_internal(skb);//

}

//驱动的工作到此就结束了

 

二 linux内核网络模块处理skb

(1) 插入到事件通知队列

netif_rx_internal()

{

enqueue_to_backlog();//插入到cpu对应的__skb_queue_tail(&sd->input_pkt_queue, skb);队列

}

 

(2) 处理事件通知队列

net_dev_init()

{

open_softirq(NET_TX_SOFTIRQ, net_tx_action);//写数据软中断注册

open_softirq(NET_RX_SOFTIRQ, net_rx_action);//收数据软中断注册

hotcpu_notifier(dev_cpu_callback, 0);//cpu通知回调

 }

 

dev_cpu_callback()

{

netif_rx_ni(skb);//激活软中断

}

(3) 软中断处理过程

static void net_rx_action(struct softirq_action *h)

{

napi_poll();//

{//sd->backlog.poll = process_backlog;

n->poll(n, weight)

}

}

 

Poll 处理的是backlog队列

process_backlog()

{

__netif_receive_skb(skb);

{

__netif_receive_skb_core(skb, true);

{

deliver_skb();//发送到上层协议,比如ip协议,icmp协议

}

}

}

 

四 下一节分析上层协议处理过程,敬请关注


更多开源流媒体技术,请关注我们的微信:EasyDarwin 


原创粉丝点击