歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux管理 >> Linux網絡

Linux網絡協議棧之設備初始化

       Linux網絡協議棧的內核初始化工作大致分為設備鏈路層(e100_module_init、net_dev_init)、網絡層(inet_init)、傳輸層(proto_init)、應用層(sock_init)初始化。由於物理層為具體的網絡設備,所以內核對網絡協議棧的實現以及網卡驅動實現等沒有物理層(L1),驅動以及設備的初始化函數都應該化為L2層。前面介紹了e100系列網卡驅動的實現,下面我們看看內核初始化的時候對設備初始化的另一個函數net_dev_init。

/*設備處理層的初始化函數*/

static int __init net_dev_init(void)

{

         int i, rc = -ENOMEM;

         /*沒有被初始化*/

         BUG_ON(!dev_boot_phase);

 

         /*該函數在/proc目錄下創建三個文件,主要用於讀取網絡相關統計數據

         正如我們看到的,/proc下的文件基本都為只讀的,這裡提供的三個文件

         都沒有寫操作*/

         if (dev_proc_init())

                   goto out;

 

         /*在/sysfs設備文件系統的class中注冊net節點*/

         if (netdev_sysfs_init())

                   goto out;

        

         /*初始化網絡處理函數鏈表和散列表,這些函數是用來處理接收到的不同

         協議族報文*/

         INIT_LIST_HEAD(&ptype_all);

         for (i = 0; i < 16; i++)

                   INIT_LIST_HEAD(&ptype_base[i]);

 

         /*下面為初始化存放網絡設備的散列表*/

         /*散列表關鍵字由設備名稱計算獲得*/

         for (i = 0; i < ARRAY_SIZE(dev_name_head); i++)

                   INIT_HLIST_HEAD(&dev_name_head[i]);

 

         /*散列表關鍵字由設備接口索引計算獲得*/

         for (i = 0; i < ARRAY_SIZE(dev_index_head); i++)

                   INIT_HLIST_HEAD(&dev_index_head[i]);

 

         /*

          *     Initialise the packet receive queues.

          */

         /*初始化與CPU相關的數據接收隊列*/

         for_each_possible_cpu(i) {

                   struct softnet_data *queue;

 

                   queue = &per_cpu(softnet_data, i);

                   skb_queue_head_init(&queue->input_pkt_queue);

                   queue->completion_queue = NULL;

                   INIT_LIST_HEAD(&queue->poll_list);

                   set_bit(__LINK_STATE_START, &queue->backlog_dev.state);

                   queue->backlog_dev.weight = weight_p;

                   queue->backlog_dev.poll = process_backlog;

                   atomic_set(&queue->backlog_dev.refcnt, 1);

         }

         /*注冊網絡DMA客戶端*/

         netdev_dma_register();

 

         /*標志已經初始化*/

         dev_boot_phase = 0;

 

         /*注冊兩個軟件中斷用於數據接收和發送*/

         open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);

         open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);

         /*在通知鏈表中注冊一個回調函數,用於相應CPU熱插拔事件

         由回調函數可以看出,一旦接到通知,CPU輸入隊列中的包逐一

         交由netif_rx()處理*/

         hotcpu_notifier(dev_cpu_callback, 0);

         /*初始化目的路由緩存,通知鏈的方式*/

         dst_init();

         /*初始化網絡鏈路層的組播模塊,在/proc/net下創建文件dev_mcast

         用來存放內核中網絡設備與IP組播相關的參數*/

         dev_mcast_init();

         rc = 0;

out:

         return rc;

}

Net_dev_init函數在驅動程序之前調用,用於初始化一些必要的信息,包括兩種設備隊列、數據輸入輸出隊列以及注冊兩個用於接收和發送數據的軟中斷等。另外,上面各種初始化函數的層次劃分可能不正確,只是便於理解。

Copyright © Linux教程網 All Rights Reserved