struct device,掛在全域鏈表 dev_base 上。| 欄位 | 用途 |
|---|---|
| name | 介面名,空則自動分配 ethN |
| base_addr, irq | I/O 埠址、中斷號,啟動參數或自動探測獲取 |
| flags | IFF_UP/IFF_RUNNING/IFF_PROMISC/IFF_MULTICAST 等能力標誌 |
| mtu | 最大傳輸單位,乙太網 1500 |
| hard_header_len | 硬體首部長度,乙太網 14 (MAC 首部) |
| dev_addr, broadcast | MAC 位址、廣播位址 (FF:FF:FF:FF:FF:FF) |
| priv | 私有資料指標,指向驅動專用結構 (如 ei_device),含統計計數器 |
| tx_queue_len | 發送佇列長度,乙太網預設 100 |
init:僅調用一次,探測硬體、填寫 device、分配 priv、註冊 IRQ/I/O。open:啟用介面,申請資源、啟動硬體、MOD_INC_USE_COUNT。stop:停用介面,釋放資源、MOD_DEC_USE_COUNT。hard_start_xmit:硬體發送封包核心邏輯(檢查 tbusy、填充硬體、釋放 skb)。hard_header / rebuild_header:構建/重建 MAC 首部(乙太網用通用 eth_header)。get_stats:回傳統計資料供 ifconfig/netstat 顯示。set_multicast_list、set_mac_address、do_ioctl、set_config、change_mtu 等。insmod → init_module()
→ 設定 dev->init = ne_probe
→ register_netdev(dev)
→ 檢查/分配名稱
→ 呼叫 dev->init() (ne_probe → ne_probe1 → ethdev_init → ether_setup)
→ 成功則掛入 dev_base 鏈表尾部
核心啟動時,dev_base 預載所有支援驅動的 device 靜態結構(含 probe 函數指標),net_dev_init() 遍歷鏈表逐一呼叫 init(),失敗者從鏈表移除。預設僅自動探測第一塊乙太網卡 (eth0)。
協議層 → dev_queue_xmit() → dev->hard_start_xmit() (ei_start_xmit)
→ 檢查 tbusy/逾時重置 → 屏蔽中斷 → ei_block_output() 複製資料到硬體
→ NS8390_trigger_send() 觸發發送 → 更新 trans_start、tbusy → 釋放 skb
硬體收到封包 → 發出 IRQ → ei_interrupt()
→ 讀取 ISR 判斷中斷來源
→ 接收中斷 → ei_receive()
→ dev_alloc_skb() 分配緩衝
→ skb_reserve(skb,2) 對齊 IP 首部
→ ei_block_input() 從硬體讀資料
→ eth_type_trans() 判斷協議類型
→ netif_rx(skb) 送入協議棧
→ 發送完成中斷 → ei_tx_intr() 清 tbusy 準備下次
→ 錯誤處理 → ei_tx_err()/ei_rx_overrun()
init / init_module)open / stophard_start_xmitrequest_irq 註冊)來源:「aban3rd的酒壺」博客,謝絕轉載。原文含詳細代碼註釋與流程圖。