下圖簡單描述了網卡驅動與Linux內核之間的聯系:
關於上圖的一些說明:
系統初始化:
1. 協議模塊調用 dev_add_pack() 來注冊協議處理函數到鏈表 &ptype_base;
2. __init br_init() 用於初始化橋接相關的操作;
3. __init net_dev_init() 初始化了兩個軟中斷;
網卡驅動初始化:
1. 網卡驅動在其 probe() 函數里面初始化 net_device 結構體,用來描述網卡,以及提供操作網卡的接口;
配置網卡:
1. 當我們通過ifconfig來配置網卡時,會調用到net_device->open(),該函數最主要的是注冊了一個中斷(當網卡接收到數據或數據發送完成會觸發中斷);
數據的發送與接收:
1. 當我們需要發送數據時,最終調用的是網卡驅動提供的函數:net_device->hard_start_xmit();
2. 當我們接收到數據時,會觸發中斷,中斷處理函數調用會調用內核函數來接收數據,最終由驅動程序調用內核函數netif_receive_skb(),把報文送入協議棧(接下來的代碼硬件無關,與具體報文處理協議相關,比如:ARP協議,IPv4協議,IPv6協議等)。
3. 網卡的中斷處理函數在調用內核函數接收數據時又分為非NAPI/NAPI兩種方式;
4. NAPI方式涉及到中斷的下半部處理的概念以及軟中斷。
5. 報文通過netif_receive_skb()送入協議棧之后,首先判斷需不需要進行橋接處理;
6. 如果報文沒有被橋接代碼處理,再調用協議處理函數來處理;