星期二, 9月 22, 2009

Network Drivers: Register

Network device 使用前要先註冊到 kernel, 註冊 network device 的時機有多種可能,例如:
  • LDD3 chapter 17 的 snull: 在 module_init 時註冊 network device
  • drivers/net/loopback.c: 開機時執行 register_pernet_device() 註冊 init function 及 exit function,其中 init function 會自動執行來註冊 network device。exit function 用來解除註冊。
  • drivers/net/tun.c: 另外建立 char device 介面於 /dev/net/tun,開啟後經執行 ioctl(TUNSETIFF) 註冊 network device。
  • NIC driver: 可以在 platform_driver_register() 註冊 probe function,用來偵測網路硬體存在時註冊 network device。
Network device 最重要的資料結構就是 struct net_device,整個註冊動作如下:
  1. 取得 struct net_device
    struct net_device *dev = alloc_netdev(int size_of_priv,
                                                                 const char *name,
                                                                 void (*setup)(struct net_device *));
    • size_of_priv:驅動程式 private 資料的大小,搭配 struct net_device 一起取得記憶體,之後透過 netdev_priv() 取得位址指標。
    • name:user space 看到的界面名稱,裡面可以有一個 printf-style 的 %d,kernel 會從 0 開始取代,以便讓一個程式給多個同樣的網路界面共用。
    • setup:會自動被呼叫來設定 struct net_device 的函數。
  2. 初始化 struct net_device。也可由上述 setup 函數完成。
    • netdev_ops:提供 init/uninit、open/stop、start_xmit、tx_timeout 等函數
    • dev_net_set(dev, net): for CONFIG_NET_NS
  3. register_netdev(dev):註冊到 kernel,然後驅動程式可開始使用
    • 如果有 dev->init 的話會被呼叫
解除註冊:
  1. unregister_netdev(dev)
    • 執行之後,此界面便從 kernel 中移除
  2. 做驅動程式內部 clean up
  3. free_netdev(dev)
    • 釋出 dev,包括 private data
可把步驟 2. 跟 3.寫成函數登記到 dev->destructor,unregister_netdev() 時會自動呼叫

另外,常見的網路界面可用 helper 函數取代 alloc_netdev(),使用預定的 name 及 setup 函數:
InterfaceHelper functionname usedsetup function used
Ethernetalloc_etherdev(size_of_priv)eth%dether_setup(dev)
fiber channelalloc_fcdev(size_of_priv)fc_setup(dev)
FDDIalloc_fddidev(size_of_priv)fddi_setup(dev)
HIPPIalloc_hippi_dev(size_of_priv)hippi_setup(dev)
token ringalloc_trdev(size_of_priv)tr_setup(dev)

struct net_device 資料相當多且有些複雜,只能在 run-time 設定,必須設定好才能呼叫 register_netdev()。一些預設或共用的值,例如 Ethernet,可以透過 alloc_etherdev() 或 ether_setup() 設定,其它還有 device methods,如 open/stop、hard_start_xmit,以及 flags、features 的參數設定等,也都需要設定好。

延伸閱讀: