目錄:http://www.cnblogs.com/WuCountry/archive/2008/11/15/1333960.html
[不提供插圖,讀者最好從網上下載源書]
5.7. Initializing the Device Handling Layer: net_dev_init
裝置處理層的初始化:net_dev_init
An important part of initialization for the networking code, including Traffic Control and per-CPU ingress queues, is performed at boot time by net_dev_init, defined in net/core/dev.c:
網路代碼初始化的一個很重要的部份,包括流量控制和每個CPU的入隊列,都是在啟動時候,由net_dev_init來完成的,它們在net/core/dev.c中定義:
static int _ _init net_dev_init(void)
{
...
}
subsys_initcall(net_dev_init);
See Chapter 7 for how the subsys_initcall macros ensure that net_dev_init runs before any NIC device drivers register themselves, and why this is important. You also will see why net_dev_init is tagged with the _ _init macro.
參見第7章,subsys_initcall這個宏確保net_dev_init在NIC裝置驅動註冊他們自己之前運行,以及為什麼這個很重要。你同樣可以看到,為什麼net_dev_init要用__init這個宏標記。
Let's walk through the main parts of net_dev_init:
讓我們看看net_dev_init的主要部份:
The per-CPU data structures used by the two networking software interrupts (softirqs) are initialized. In Chapter 9, we will see what a softirq is and go into detail on how the networking code uses softirqs.
每個CPU的資料結構是由兩個網路軟體中斷(非強制中斷)初始化所使用。在第9章中,我們會看到什麼是非強制中斷以及網路代碼是如何使用它們詳細情況。
When the kernel is compiled with support for the /proc filesystem (which is the default configuration), a few files are added to /proc with dev_proc_init and dev_mcast_init. See the later section "Tuning via /proc Filesystem" for more details.
當核心編譯成支援/proc檔案系統時(這是一個預設配置),會有一些檔案和with_proc_init一起添加到/proc中。詳細情況參見後面的“通過/proc檔案系統調整(核心)”章節。
netdev_sysfs_init registers the net class with sysfs. This creates the directory /sys/class/net, under which you will find a subdirectory for each registered network device. These directories include lots of files, some of which used to be in /proc.
netdev_sysfs_init通過sysfs註冊網路類。這會建立一個/sys/class/net/的目錄,在這個目錄下,你可以發現與每一個註冊的網路裝置的子目錄。這個目錄包括話多檔案,其中有一些就/proc所使用。
net_random_init initializes a per-CPU vector of seeds that will be used when generating random numbers with the net_random routine. net_random is used in different contexts, described later in this section.
net_random_init初始化每個CPU的向量種子數,這個數會通過net_radnom常式一起用於產生隨機數。net_random在不同的上下文中使用,在這一節的後面會說明。
The protocol-independent destination cache (DST), described in Chapter 33, is initialized with dst_init.
與協議相關的目的緩衝(DST)是通過dst_init初始的,這個會在第33章中說明。
The protocol handler vector ptype_base, used to demultiplex ingress traffic, is initialized. See Chapter 13 for more details.
處理協議的向量ptype_base也被初始化,它用於多功能的入隊流量管理,詳細的參見第13章。
When the OFFLINE_SAMPLE symbol is defined, the kernel sets up a function to run at regular intervals to collect statistics about the devices' queue lengths. In this case, net_dev_init needs to create the timer that runs the function regularly. See the section "Average Queue Length and Congestion-Level Computation" in Chapter 10.
當OFFLINE_SAMPLE符號被定義時,核心設定了一個函數在規則的間隙運行,用於收集與裝置隊列長度相關的統計。在這種情況下,net_dev_init需要建立一個計時器,用於規則的運行這個函數。參見第10章的“平均隊列長度和擁塞等級運算”。
A callback handler is registered with the notification chain that issues notifications about CPU hotplug events. The callback used is dev_cpu_callback. Currently, the only event processed is the halting of a CPU. When this notification is received, the buffers in the CPU's ingress queue are dequeued and are passed to netif_rx. See Chapter 9 for more detail on per-CPU ingress queues.
一個回調控制代碼被註冊到通知鏈中,這樣可以確保CPU會通知熱插事件。這個回調使用的是dev_cpu_callback。目前,唯一的事件處理就是暫停CPU。當收到這個通知時,CPU裡的入隊列緩衝隊列就被清出,然後傳給netif_rx。詳細的參見第9章的每CPU入隊列。
Random number generation is a support function that the kernel performs to help randomize some of its own activity. You will see in this book that many networking subsystems use randomly generated values. For instance, they often add a random component to the delay of timers, making it less likely for timers to run simultaneously and load down the CPU with background processing. Randomization can also defend against a Denial of Service (DoS) attack by someone who tries to guess the organization of certain data structures.
隨機數產生器是一個協助工具功能,可以讓核心協助它們實現一些隨機化的活動。你會從本書中看到,有很多網路子系統使用了隨機產生數。例如,他們經常添加一個隨機的組件到計時器中,使它不至於讓計時器同時地運行,並在後台進程中分擔CPU。隨機還可以防止一些人使用DOS攻擊來猜測組織圖和資料結構。
The degree to which the kernel's numbers can be considered truly random is called system entropy . It is improved through contributions by kernel components whose activity has a nondeterministic aspect, and networking often falls in this category. Currently, only a few NIC device drivers contribute to system entropy (see earlier discussion on SA_SAMPLE_RANDOM). A patch for kernel 2.4 adds a compile time option that you can use to enable or disable the contribution to system entropy by NICs. Search the Web using the keyword "SA_SAMPLE_NET_RANDOM," and you will find the current version.
可以被核心數所真實信任的隨機數的度,被稱為系統熵(譯:看原文,不知道什麼意思)。這可以增加核心中那些行為有不確定特性的組件的貢獻,並且一些網路經常落到這一話題中。目前,只有少數的NIC裝置驅動給核心貢獻了熵(參見前面所討論的SA_SAMPLE_RANDOM)。有一個給2.4的補丁,添加了編譯選項。你可以通過這些選項開啟或者關閉,是否讓NIC裝置給核心貢獻熵。從網路上搜尋“SA_SAMPLE_NET_RANDOM”,你會發現最新的版本內容。
5.7.1. Legacy Code 遺傳代碼
I mentioned in the previous section that the subsys_initcall macros ensure that net_dev_init is executed before any device driver has a chance to register its devices. Before the introduction of this mechanism, the order of execution used to be enforced differently, using the old-fashioned mechanism of a one-time flag.
我在前面的章節中已經提到過,subsys_initcall宏用於確保net_dev_init在任何裝置註冊它的驅動之間被調用。在介紹這個機制之前,執行的順序通常是強制要求不同的,在老的形式中是使用一個時間標誌。
The global variable dev_boot_phase was used as a Boolean flag to remember whether net_dev_init had to be executed. It was initialized to 1 (i.e., net_dev_init had not been executed yet) and was cleared by net_dev_init. Each time register_netdevice was invoked by a device driver, it checked the value of dev_boot_phase and executed net_dev_init if the flag was set, indicating the function had not yet been executed.
全域變數dev_boot_phase當成一個邏輯標誌位,用於記住net_dev_init是否已經被執行過。它在初始化時設定為1(就是說net_dev_init還沒有被執行),並由net_dev_init清零。每次register_netdevice被裝置驅動調用時,它就檢測dev_boot_phase這個值,關在標誌被設定的時候執行net_dev_init,即指示這個函數還沒有被執行過。
This mechanism is not needed anymore, because register_netdevice cannot be called before net_dev_init if the correct tagging is applied to key device drivers' routines, as described in Chapter 7. However, to detect wrong tagging or buggy code, net_dev_init still clears the value of dev_boot_phase, and register_netdevice uses the macro BUG_ON to make sure it is never called when dev_boot_phase is set.[*]
這種機制現在並不需要了,因為當正確的標籤被應用到裝置驅動程式的關鍵字上時,register_netdevice不能在net_dev_init之前被調用,這會在第7章中討論。然而,為了檢測錯誤的標籤,或者是代碼bug,net_dev_init還是會清除dev_boot_phase的值,並register_netdevice用宏BUG_ON來確保當dev_boot_phase被設定時,這決對不會調用。
[*] The use of the macros BUG_ON and BUG_TRAP is a common mechanism to make sure necessary conditions are met at specific code points, and is useful when transitioning from one design to another.
BUG_ON和BUG_TRAP宏的使用是一種常用的機制,用於在一些特殊的代碼點上,保證一些必須的條件,而且在從一個設計人轉到另一個人那裡的時候特別有用。