Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 網路驅動基礎架構:PCI 註冊、net_device 初始化與 NAPI 接入

編輯:Linux 教學

Linux 網卡驅動是協議棧與硬件的橋樑。本文以 Intel e100 驅動為例,系統梳理驅動模組載入、PCI 探測、net_device 分配初始化、NAPI 接入以及 DMA/IO 內存映射準備的完整流程。

驅動模組入口:e100_init_module

static int __init e100_init_module(void)
{
    if (debug 条件) printk(KERN_INFO "驅動版本信息");
    return pci_module_init(&e100_driver);  // 註冊 PCI 驅動
}

pci_module_init 將 e100_driver 註冊到 PCI 子系統,當總線掃描到匹配設備時觸發 probe。

PCI 驅動結構:e100_driver

static struct pci_driver e100_driver = {
    .name     = DRV_NAME,
    .id_table = e100_id_table,      // 支援的設備 ID 列表
    .probe    = e100_probe,         // 設備探測/初始化
    .remove   = __devexit_p(e100_remove),
#ifdef CONFIG_PM
    .suspend  = e100_suspend,
    .resume   = e100_resume,
#endif
};

核心初始化邏輯:e100_probe

此函數完成從 PCI 設備到網路設備的完整轉化:

1. 分配 net_device(以太網專用封裝)

if (!(netdev = alloc_etherdev(sizeof(struct nic)))) {
    printk(KERN_ERR "Etherdev alloc failed");
    return -ENOMEM;
}

alloc_etherdev 內部調用 alloc_netdev,預分配私有數據區 sizeof(struct nic),並預設以太網相關字段(dev_addr、broadcast 等)。

2. 綁定 net_device 操作函數指針

netdev->open            = e100_open;
netdev->stop            = e100_close;
netdev->hard_start_xmit = e100_xmit_frame;   // 發送入口
netdev->get_stats       = e100_get_stats;
netdev->set_multicast_list = e100_set_multicast_list;
netdev->set_mac_address = e100_set_mac_address;
netdev->change_mtu      = e100_change_mtu;
netdev->do_ioctl        = e100_do_ioctl;
SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
netdev->tx_timeout      = e100_tx_timeout;
netdev->watchdog_timeo  = E100_WATCHDOG_PERIOD;

// NAPI 關鍵接口
netdev->poll            = e100_poll;         // 輪詢處理函數
netdev->weight          = E100_NAPI_WEIGHT;  // 輪詢權重
#ifdef CONFIG_NET_POLL_CONTROLLER
netdev->poll_controller = e100_netpoll;      // Netpoll 專用輪詢
#endif

3. 初始化私有數據結構 nic

nic = netdev_priv(netdev);
nic->netdev = netdev;
nic->pdev   = pdev;
nic->msg_enable = (1 << debug) - 1;
pci_set_drvdata(pdev, netdev);  // PCI 核心關聯 netdev

4. 啟用 PCI 設備:IO/內存映射準備

if ((err = pci_enable_device(pdev))) {
    DPRINTK(PROBE, ERR, "Cannot enable PCI device");
    goto err_pci;
}
// 後續:pci_set_master(pdev) 設置總線主模式
// pci_request_regions(pdev) 申請 IO/內存資源
// ioremap 映射寄存器地址空間

關鍵子系統接入點總結

接口函數觸發場景
opene100_openifconfig eth0 up、ip link set dev eth0 up
stope100_close接口關閉
hard_start_xmite100_xmit_frame協議棧發送數據包
polle100_pollNAPI 輪詢(接收/發送清理)
tx_timeoute100_tx_timeout發送超時看門狗
set_mac_addresse100_set_mac_address修改 MAC 地址
ioctle100_do_ioctlethtool、SIOCGMIIPHY 等

硬件資源管理流程

  1. PCI 啟用:pci_enable_device 分配 IRQ、IO/內存 BAR 空間
  2. 總線主模式:pci_set_master 允許設備發起 DMA 事務
  3. 資源申請:pci_request_regions 鎖定 BAR 區域
  4. 寄存器映射:ioremap 將 BAR 物理地址映射為核心虛擬地址
  5. 中斷申請:request_irq 註冊 e100_intr,啟用 MSIX/MSI 或傳統中斷

NAPI 架構優勢

e100 通過實現 poll 接口並設置 weight,接入核心 NAPI 框架:

  • 中斷上半部僅 netif_rx_schedule 調度,不處理具體數據
  • 核心在 net_rx_action 軟中斷中調用 poll
  • budget 機制限制單次輪詢處理量,保證公平調度
  • 高負載下自動切換為純輪詢模式,消除中斷風暴

總結

e100 驅動的 probe 流程展示了標準 Linux 網卡驅動的完整骨架:PCI 子系統綁定 → net_device 分配與操作函數綁定 → 私有數據初始化 → 硬件資源獲取與映射 → NAPI 接入。這一模式被絕大多數現代網卡驅動遵循,是驅動開發的標準範式。

Copyright © Windows教程網 All Rights Reserved