歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux管理 >> Linux網絡 >> Linux網絡協議棧之設備初始化

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

日期:2017/3/1 10:19:51   编辑: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