5.4. Interaction Between Devices and Kernel 设备与内核的交互
目錄:http://www.cnblogs.com/WuCountry/archive/2008/11/15/1333960.html
?
[不提供插圖,讀者最好從網(wǎng)上下載源書]
????
5.4. Interaction Between Devices and Kernel 設(shè)備與內(nèi)核的交互
Nearly all devices (including NICs) interact with the kernel in one of two ways:
幾乎所有的設(shè)備(包括NIC)有2種方式與內(nèi)核交互:
Polling 輪詢
Driven on the kernel side. The kernel checks the device status at regular intervals to see if it has anything to say.
內(nèi)核驅(qū)動(dòng)模式,由內(nèi)核有規(guī)則的主動(dòng)檢測設(shè)備的狀態(tài),看設(shè)備是否有內(nèi)容要輸出。
Interrupt
Driven on the device side. The device sends a hardware signal (by generating an interrupt) to the kernel when it needs the kernel's attention.
設(shè)備驅(qū)動(dòng)模式,在設(shè)備須要內(nèi)核關(guān)注時(shí),由設(shè)備主動(dòng)發(fā)送一個(gè)硬件信號(通常是通過一個(gè)中斷)給內(nèi)核。
In Chapter 9, you can find a detailed discussion of NIC driver design alternatives as well as software interrupts. You will also see how Linux can use a combination of polling and interrupts to increase performance. In this chapter, we will look only at the interrupt-based case.
在第9章,你可以看到詳細(xì)的討論,關(guān)于NIC驅(qū)動(dòng)可以選擇性的設(shè)計(jì)成很好的軟件中斷模式。你同樣可以看到Linux是如何合并使用輪詢和中斷來提高性能的。在這一章,我只講基于中斷的情況。
I won't go into detail on how interrupts are reported by the hardware, the difference between hardware exceptions and device interrupts, how the driver and bus kernel infrastructures are designed, etc.; you can refer to Linux Device Drivers and Understanding the Linux Kernel for those topics. But I'll give a brief overview on interrupts to help you understand how device drivers initialize and register the devices they are responsible for, with special attention to the networking aspect.
我不會詳細(xì)的說明中斷是如何從硬件上報(bào)給內(nèi)核的,硬件異常和設(shè)備中斷的區(qū)別,驅(qū)動(dòng)和內(nèi)核總線的底層是怎樣設(shè)計(jì)的,等等。關(guān)于這些內(nèi)容你可以參考:Linux Device Drivers 和 Understanding the Linux Kernel。但我會簡單的說明一下中斷,以幫助你理解設(shè)備驅(qū)動(dòng)的初始化和讓設(shè)備回應(yīng)的注冊,而這些都只關(guān)注于網(wǎng)絡(luò)特性。
5.4.1. Hardware Interrupts 使用中斷
You do not need to know the low-level background about how hardware interrupts are handled. However, there are details worth mentioning because they can make it easier to understand how NIC device drivers are written, and therefore how they interact with the upper networking layers.
你須要知道一些關(guān)于硬件底層中斷處理的背景知識。顯然,它們的細(xì)節(jié)是值得被關(guān)注的,因?yàn)檫@會讓你更加容易的理解NIC設(shè)備驅(qū)動(dòng)應(yīng)該怎樣寫,而且知道它們是怎樣與網(wǎng)絡(luò)層交互的。
Every interrupt runs a function called an interrupt handler, which must be tailored to the device and therefore is installed by the device driver. Typically, when a device driver registers an NIC, it requests and assigns an IRQ. It then registers and (if the driver is unloaded) unregisters a handler for a given IRQ with the following two architecture-dependent functions. They are defined in kernel/irq/manage.c and are overridden by architecture-specific functions in arch/XXX/kernel/irq.c, where XXX is the architecture-specific directory:
每一個(gè)中斷是以一個(gè)被稱為中斷處理的函數(shù)調(diào)用來運(yùn)行的,這些必須可以通過安裝的設(shè)備驅(qū)動(dòng)程序,根據(jù)設(shè)備被裁剪。代表性的,當(dāng)一個(gè)設(shè)備驅(qū)動(dòng)注冊成一個(gè)NIC,它要請求分配一個(gè)IRQ。然后它就通過以下兩個(gè)基于系統(tǒng)體系結(jié)構(gòu)的函數(shù)來注冊和反注冊(如果設(shè)備在卸載時(shí))IRQ。這兩個(gè)函數(shù)定義在kernel/irq/manage.c中,而且它們被不同的體系結(jié)構(gòu)在arch/XXX/kernel/irq.c中重載,其中的XXX是指定的體系結(jié)構(gòu)目錄:
int request_irq(unsigned int irq, void (*handler)(int, void*, struct pt_regs*), unsigned long irqflags, const char * devname, void *dev_id)
This function registers a handler, first making sure that the requested interrupt is a valid one, and that it is not already allocated to another device unless both devices understand shared IRQs (see the later section "Interrupt sharing").
這個(gè)函數(shù)注冊一個(gè)句柄,首先確保請求的中斷是一個(gè)有效的中斷號,而且它還沒有分配給另一個(gè)設(shè)備,除非兩個(gè)設(shè)備都明確的使用共享IRQ(參見后面的一節(jié)“Interrupt sharing”)。
void free_irq(unsigned_int irq, void *dev_id)
Given the device identified by dev_id, this function removes the handler and disables the IRQ line if no more devices are registered for that IRQ. Note that to identify the handler, the kernel needs both the IRQ number and the device identifier. This is especially important with shared IRQs, as explained in the later section "Interrupt sharing."
dev_id給出了設(shè)備唯一標(biāo)識,如果一個(gè)IRQ上已經(jīng)沒有了注冊的設(shè)備,這個(gè)函數(shù)就用于刪除處理句柄并禁用IRQ總線。注意,為了標(biāo)識處理句柄,內(nèi)核同時(shí)須要IRQ號和設(shè)備ID。對于共享IRQ來說,這更加重要,在后面的章節(jié)“共享中斷”中有解釋。
When the kernel receives an interrupt notification, it uses the IRQ number to find out the driver's handler and then executes this handler. To find handlers, the kernel stores the associations between IRQ numbers and function handlers in a global table. The association can be either one-to-one or one-to-many, because the Linux kernel allows multiple devices to use the same IRQ, a feature described in the later section "Interrupt sharing."
當(dāng)內(nèi)核收到一個(gè)中斷通知時(shí),它就使用IRQ號來找到設(shè)備的句柄,然后執(zhí)行它。為了找到處理句柄,內(nèi)核將IRQ號和函數(shù)句柄以關(guān)聯(lián)的形式存儲在一個(gè)全局表中。這個(gè)關(guān)聯(lián)可以是一對一的,也可以是一對多的,因?yàn)長inux內(nèi)核充許多設(shè)備使用同一個(gè)IRQ,相關(guān)特性在后面的“共享中斷”中有描述
In the following sections, you will see common examples of the information exchanged between devices and drivers by means of interrupts, and how an IRQ can be shared by multiple devices under some conditions.
在下面的章節(jié)中,就會看到一些在名義上稱為中斷的,關(guān)于設(shè)備與驅(qū)動(dòng)之間信息交換的通用示例,以及一個(gè)IRQ是如何在一些條件下,在多個(gè)設(shè)備之間共享的。
5.4.1.1. Interrupt types 中斷類型
With an interrupt, an NIC can tell its driver several different things. Among them are:
在一個(gè)中斷上,一個(gè)NIC可以特性它的驅(qū)動(dòng)一些不同的事。這些有:
Reception of a frame 收到一個(gè)幀
This is the most common and standard situation. 這是最常見和標(biāo)準(zhǔn)的情況。
Transmission failure 轉(zhuǎn)送失敗
This kind of notification is generated on Ethernet devices only after a feature called exponential binary backoff has failed (this feature is implemented at the hardware level by the NIC). Note that the driver will not relay this notification to higher network layers; they will come to know about the failure by other means (timer timeouts, negative ACKs, etc.).
這種通知只在以太設(shè)備上,當(dāng)一個(gè)稱為(exponential binary backoff)失敗以后才發(fā)生。(這一特性是在NIC的硬件層上實(shí)現(xiàn)的)。注意,驅(qū)動(dòng)在更高層的網(wǎng)絡(luò)層上將不再對這個(gè)通知轉(zhuǎn)發(fā);它們以另一種形式來獲知這個(gè)失敗(計(jì)時(shí)器超時(shí),拒絕的確認(rèn)幀等)。
DMA transfer has completed successfully DMA傳送已經(jīng)成功的完成
Given a frame to send, the buffer that holds it is released by the driver once the frame has been uploaded into the NIC's memory for transmission on the medium. With synchronous transmissions (no DMA), the driver knows right away when the frame has been uploaded on the NIC. But with DMA, which uses asynchronous transmissions, the device driver needs to wait for an explicit interrupt from the NIC. You can find an example of each case at points where dev_kfree_skb[*] is called within the driver code drivers/net/3c59x.c (DMA) and drivers/net/3c509.c (non-DMA).
給一個(gè)發(fā)送幀,在介質(zhì)上傳送該幀時(shí),一但幀已經(jīng)上傳到NIC的內(nèi)存以后,該幀的緩存會被驅(qū)動(dòng)釋放。在同步傳輸時(shí)(非DMA),設(shè)備可以正確的知道在什么時(shí)候幀已經(jīng)上傳到NIC設(shè)備中。但在DMA中,也就是用戶使用異步傳送模式,設(shè)備驅(qū)動(dòng)須要等待NIC一個(gè)清楚的中斷。你可以在drivers/net/3c59x.c和drivers/net/3c509.c中分別找到調(diào)用dev_kfree_skb的示例。
[*] Chapter 11 describes this function in detail. 該函數(shù)在第11章中有詳細(xì)說明。
Device has enough memory to handle a new transmission 設(shè)備已經(jīng)有足夠的內(nèi)存來處理新的傳輸
It is common for an NIC device driver to disable transmissions by stopping the egress queue when that queue does not have sufficient free space to hold a frame of maximum size (e.g., 1,536 bytes for an Ethernet NIC). The queue is then re-enabled when memory becomes available. The rest of this section goes into this case in more detail.
對于NIC設(shè)備驅(qū)動(dòng)來說,當(dāng)隊(duì)列沒有足夠的空閑空間來存儲一個(gè)最大字節(jié)的幀(例如,在以太NIC上是1536字節(jié))時(shí),通過停止出口隊(duì)列來禁止傳輸是很常見的情況。而當(dāng)隊(duì)列上有了足夠的內(nèi)存時(shí)就會重新使能該設(shè)備。這一節(jié)后面的內(nèi)容會詳細(xì)討論這一問題。
The final case in the previous list covers a sophisticated way of throttling transmissions in a manner that can improve efficiency if done properly. In this system, a device driver disables transmissions for lack of queuing space, asks the NIC to issue an interrupt when the available memory is bigger than a given amount (typically the device's Maximum Transmission Unit, or MTU), and then re-enables transmissions when the interrupt comes.
前面列出的最后一個(gè)情況,包括了一個(gè)如果處理正確的話,可以提高效率的成熟的方法;在這個(gè)系統(tǒng)里,一個(gè)設(shè)備驅(qū)動(dòng)在缺少空間的隊(duì)列上禁用數(shù)據(jù)傳輸,詢問該NIC以確認(rèn)一個(gè)中斷,當(dāng)有大于給定數(shù)量的內(nèi)存空間(通常就是設(shè)備的最大傳輸單元,或者M(jìn)TU),然后當(dāng)中斷到來時(shí)重新使能數(shù)據(jù)傳輸。
A device driver can also disable the egress queue before a transmission (to prevent the kernel from generating another transmission request on the device), and re-enable it only if there is enough free memory on the NIC; if not, the device asks for an interrupt that allows it to resume transmission at a later time. Here is an example of this logic, taken from the el3_start_xmit routine, which the drivers/net/3c509.c driver installs as its hard_start_xmit function in its net_device structure:
一個(gè)設(shè)備驅(qū)動(dòng)同樣可以禁用出口隊(duì)列的數(shù)據(jù)傳輸(用于防止內(nèi)核在該設(shè)備上產(chǎn)生另一個(gè)傳輸請示),而只在NIC有足夠的內(nèi)存時(shí)才重新使能;否則,該設(shè)備請求一個(gè)中斷,該中斷充許它在后面某個(gè)時(shí)刻恢復(fù)數(shù)據(jù)傳輸。關(guān)于這一邏輯,這里有一個(gè)從drivers/net/3c509.c里取得的一個(gè)el3_start_xmit的示例,設(shè)備驅(qū)動(dòng)用類似hard_start_mit的函數(shù)放在它的設(shè)備數(shù)據(jù)結(jié)構(gòu)里:
?The hard_start_xmit virtual function is described in Chapter 11.
hard_start_xmit虛函數(shù)在第11章里討論
static int
el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
??? ... ... ...
??? netif_stop_queue (dev);
??? ... ... ...
??? if (inw(ioaddr + TX_FREE) > 1536)
??????? netif_start_queue(dev);
??? else
??????? outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
??? ... ... ...
}
The driver stops the device queue with netif_stop_queue, thus inhibiting the kernel from submitting further transmission requests. The driver then checks whether the device's memory has enough free space for a packet of 1,536 bytes. If so, the driver starts the queue to allow the kernel once again to submit transmission requests; otherwise, it instructs the device (by writing to a configuration register with an outw call) to generate an interrupt when that condition will be met. An interrupt handler will then re-enable the device queue with netif_start_queue so that the kernel can restart transmissions.
該驅(qū)動(dòng)用netif_stop_queue來停止設(shè)備隊(duì)列,這樣就抑制內(nèi)核后期的傳輸請求。然后驅(qū)動(dòng)檢測設(shè)備是否有足夠的內(nèi)存空間來存放一個(gè)1536字節(jié)的數(shù)據(jù)包。如果是這樣的,設(shè)備啟動(dòng)隊(duì)列,用以再次讓內(nèi)核可以提交數(shù)據(jù)傳輸請求。否則,它就指示設(shè)備(通過寫一個(gè)outw調(diào)用來寫一個(gè)配置寄存器)在這個(gè)條件滿足時(shí)產(chǎn)生一個(gè)中斷。然后一個(gè)中斷句柄用netif_start_queue來重新使能設(shè)備隊(duì)列,這樣內(nèi)核就可以重新啟動(dòng)數(shù)據(jù)傳輸。
The netif_xxx_queue routines are described in the section "Enabling and Disabling Transmissions" in Chapter 11.
netif_xxx_queue函數(shù)會在第11章的“傳輸?shù)氖鼓芘c去使能”中描述。
5.4.1.2. Interrupt sharing 共享中斷
IRQ lines are a limited resource. A simple way to increase the number of devices a system can host is to allow multiple devices to share a common IRQ. Normally, each driver registers its own handler to the kernel for that IRQ. Instead of having the kernel receive the interrupt notification, find the right device, and invoke its handler, the kernel simply invokes all the handlers of those devices that registered for the same shared IRQ. It is up to the handlers to filter spurious invocations, such as by reading a registry on their devices.
IRQ線是有限的資源。一個(gè)簡單的方法可以增加該系統(tǒng)可以提供的設(shè)備數(shù)目,就是充許多個(gè)設(shè)備共享一個(gè)通用的IRQ。原來內(nèi)核是收到一個(gè)中斷通知以后,查找到正確的設(shè)備,然后調(diào)用它的句柄;共享IRQ以后,內(nèi)核取而代之的就是簡單的調(diào)用這些設(shè)備注冊在同一個(gè)IRQ上的所有句柄。這就等于讓句柄去過濾欺騙的行為,例如在他們的設(shè)備上讀一個(gè)寄存器。
For a group of devices to share an IRQ line, all of them must have device drivers capable of handling shared IRQs. In other words, each time a device registers for an IRQ line, it needs to explicitly say whether it supports interrupt sharing. For example, the first device that registers for one IRQ, saying something like "assign me IRQ n and use this routine fn as the handler," must also specify whether it is willing to share the IRQ with other devices. When another device driver tries to register the same IRQ number, it is refused if either it, or the driver to which the IRQ is currently assigned, is incapable of sharing IRQs.
為了讓一組設(shè)備可以共享一個(gè)IRQ線,所有設(shè)備都必須有一個(gè)在共享IRQ上可以處理的句柄。也就是說,每次在注冊一個(gè)IRQ時(shí),它必須顯示的說明它是否支持共享中斷。例如,第一個(gè)設(shè)備在注冊一個(gè)IRQ時(shí),像這樣申明:“分配給我一個(gè)IRQ n,而且用這個(gè)句柄來做為我的調(diào)用函數(shù)”,同時(shí)還必須指定它是否要與其它設(shè)備共享這個(gè)中斷號。當(dāng)另一個(gè)設(shè)備來注冊同一個(gè)中斷號是時(shí),如果該設(shè)備不使用共享,那么它會被拒絕,或者說,已經(jīng)注冊了該中斷號的設(shè)備也是無法共享該中斷號的。
5.4.1.3. Organization of IRQs to handler mappings IRQ句柄的映射組織
The mapping of IRQs to handlers is stored in a vector of lists, one list of handlers for each IRQ (see Figure 5-2). A list includes more than one element only when multiple devices share the same IRQ. The size of the vector (i.e., the number of possible IRQ numbers) is architecture dependent and can vary from 15 (on an x86) to more than 200. With the introduction of interrupt sharing, even more devices can be supported on a system at once.
映射IRQ的句柄是存儲在一個(gè)向量鏈表中,每一個(gè)IRQ(參見圖5-2)有一個(gè)句柄鏈表。一個(gè)鏈表只有在多個(gè)設(shè)備共享同一個(gè)IRQ時(shí)才會包含更多的元素。向量的大小(例如:IRQ的可用數(shù)量)是與體系結(jié)構(gòu)相關(guān)的,而且是可以從15(在x86的體系結(jié)構(gòu)上)到多于200的范圍上變化的。和中斷共享所介紹的一樣,可能更多的設(shè)備可以一次在一個(gè)系統(tǒng)是被支持。
The section "Hardware Interrupts" already introduced the two functions provided by the kernel to register and unregister a handler, respectively. Let's now see the data structure used to store the mappings.
在硬件中斷一節(jié)中已經(jīng)介紹了內(nèi)核所提供的兩個(gè)函數(shù),用于注冊和反注冊一個(gè)句柄。接下來讓我們看看關(guān)于映射的數(shù)據(jù)結(jié)構(gòu)的存儲。
Mappings are defined with irqaction data structures. The request_irq function introduced in the earlier section "Hardware Interrupts" is a wrapper around setup_irq, which takes an irqaction structure as input and inserts it into the global irq_desc vector. irq_desc is defined in kernel/irq/handler.c and can be overridden in the per-architecture files arch/XXX/kernel/irq.c. setup_irq is defined in kernel/irq/manage.c and can be overridden in the per-architecture files arch/XXX/kernel/irq.c.
映射和中斷動(dòng)作(irqaction)數(shù)據(jù)結(jié)構(gòu)定義在一起。request_irq函數(shù)已經(jīng)在前面的“硬件中斷”一節(jié)中介紹過,它被封裝成setup_irq,這個(gè)函數(shù)用一個(gè)中斷動(dòng)作數(shù)據(jù)結(jié)構(gòu)做為一個(gè)輸入?yún)?shù),而且將它插入到一個(gè)全局的irq_desc向量中。irq_des在kernel/irq/handler.c中有定義,而且它可在以每個(gè)不同的體系結(jié)構(gòu)中被重載,這些體系結(jié)構(gòu)文件在arch/xxx/kernel/irq.c中。setup_irq被定義在kernel/irq/manage.c中,而且可以被arch/xxx/kernle/irq.c中不同的體系結(jié)構(gòu)所重載。
The kernel function that handles interrupts and passes them to drivers is architecture dependent. It is called handle_IRQ_event on most architectures.
內(nèi)核用于處理句柄并將它們傳給設(shè)備的函數(shù)是與體系結(jié)構(gòu)相關(guān)的。它們在很多體系結(jié)構(gòu)中都被稱為handle_IRQ_event。
Figure 5-2 shows how irqaction instances are stored: there is an instance of irq_desc for each possible IRQ and an instance of irqaction for each successfully registered IRQ handler. The vector of irq_desc instances is called irq_desc as well, and its size is given by the architecture-dependent symbol NR_IRQS.
圖5-2展示了中斷動(dòng)作實(shí)例是如何存儲的:這里,在每一個(gè)可能的IRQ上有一個(gè)irq_desc的實(shí)例,而且每中斷動(dòng)作的實(shí)例已經(jīng)成功的注冊了IRQ處理句柄。irq_desc向量的實(shí)例可以就稱為irq_desc,而且它的大小是由給定的與體系結(jié)構(gòu)相關(guān)的NR_IRQS所決定的。
Note that when you have more than one irqaction instance for a given IRQ number (that is, for a given element of the irq_desc vector), interrupt sharing is required (each structure must have the SA_SHIRQ flag set).
應(yīng)該注意,當(dāng)你在一個(gè)給定的IRQ數(shù)上使多個(gè)IRQ動(dòng)作時(shí)(也就是在一個(gè)給定的irq_desc向量元素上),中斷共享是必須的(每個(gè)結(jié)構(gòu)必須同時(shí)擁有SA_SHIRQ標(biāo)志位)。
Figure 5-2. Organization of IRQ handlers
圖5-2,IRQ句柄組織
Let's see now what information is stored about IRQ handlers in the fields of an irqaction data structure:
現(xiàn)在讓我們來看看關(guān)于IRQ句柄的信息在一個(gè)中斷動(dòng)作的數(shù)據(jù)結(jié)構(gòu)中是如何存儲的:
void (*handler)(int irq, void *dev_id, struct pt_regs *regs)
Function provided by the device driver to handle notifications of interrupts: whenever the kernel receives an interrupt on line irq, it invokes handler. Here are the function's input parameters:
該函數(shù)由設(shè)備驅(qū)動(dòng)提供,用于處理中斷通知:不管什么時(shí)候,只要內(nèi)核在IRQ線上收到一個(gè)中斷,它就調(diào)用這個(gè)句柄。這里是函數(shù)的輸入?yún)?shù):
int irq
IRQ number that generated the notification. Most of the time it is not used by the NICs' device drivers to accomplish their job; the device ID is sufficient.
IRQ號,用于合成(中斷)通知。多數(shù)時(shí)候,它只并不被NIC設(shè)備驅(qū)動(dòng)所使用去完成它們的任務(wù),設(shè)備ID已經(jīng)足夠了。
void *dev_id
Device identifier. The same driver can be responsible for different devices at the same time, so it needs the device ID to process the notification correctly.
設(shè)備ID,同一個(gè)設(shè)備驅(qū)動(dòng)可以同時(shí)對不同的設(shè)備負(fù)責(zé),所以它須要設(shè)備ID用于處理正確的中斷通知。
struct pt_regs *regs
Structure used to save the content of the processor's registers at the moment the interrupt interrupted the current process. It is normally not used by the interrupt handler.
該結(jié)構(gòu)用于在中斷正中斷了當(dāng)前進(jìn)程時(shí),用于保存當(dāng)前處理器的寄存器內(nèi)容。通常它不被中斷句柄所使用。
unsigned long flags
Set of flags. The possible values SA_XXX are defined in include/asm-XXX/signal.h. Here are the main ones from the x86 architecture file:
標(biāo)志位,它的可能值在include/asm-XXX/signal.h中以SA_XXX的形式定義,這里是幾個(gè)x86體系結(jié)構(gòu)的主要值:
SA_SHIRQ
When set, the device driver can handle shared IRQs.
設(shè)置它時(shí),設(shè)備驅(qū)動(dòng)可以處理共享IRQ
SA_SAMPLE_RANDOM
When set, the device is making itself available as a source of random events. This can be useful to help the kernel generate random numbers for internal use, and is called contributing to system entropy. This is further described in the later section "Initializing the Device Handling Layer: net_dev_init."
設(shè)置它時(shí),設(shè)備就讓它自己可成為一個(gè)隨機(jī)事件的源。這可以用于幫助內(nèi)核產(chǎn)生一些內(nèi)部使用的隨機(jī)數(shù),而且它被稱為給內(nèi)核貢獻(xiàn)的熵值。這個(gè)會在后面的“初始化設(shè)備句柄層:net_dev_init”章節(jié)中描述。
SA_INTERRUPT
When set, the handler runs with interrupts disabled on the local processor. This should be specified only for handlers that can get done very quickly. See one of the handle_IRQ_event instances for an example (for instance, /kernel/irq/handle.c).
當(dāng)它被設(shè)置時(shí),句柄就在本地處理器上以可中斷的形式運(yùn)行。這只有在句柄可以很快的處理完時(shí)指定。可以參見一個(gè)handle_IRQ_event的實(shí)例(/kernel/irq/handle.c)。
There are other values, but they are either obsolete or used only by particular architectures.
這里有另一個(gè)值,但它們并沒有被丟棄,也沒有被特殊的體系結(jié)構(gòu)所使用。
void *dev_id
Pointer to the net_device data structure associated with the device. The reason it is declared void * is that NICs are not the only devices to use IRQs. Because various device types use different data structures to identify and represent device instances, a generic type declaration is used.
用于指向一個(gè)與設(shè)備相關(guān)的數(shù)據(jù)結(jié)構(gòu)net_device,使用void *的理由是NIC并不是唯一使用IRQ的設(shè)備。
struct irqaction *next
All the devices sharing the same IRQ number are linked together in a list with this pointer.
所有的共享同一個(gè)IRQ數(shù)的設(shè)備被一個(gè)鏈表所關(guān)聯(lián)在一起,這個(gè)指針指向這個(gè)鏈表。
const char *name
Device name. You can read it by dumping the contents of /proc/interrupts.
設(shè)備名,你可以通過導(dǎo)出/proc/interrupts中的信息來讀取它。
轉(zhuǎn)載于:https://www.cnblogs.com/WuCountry/archive/2009/02/01/1382106.html
總結(jié)
以上是生活随笔為你收集整理的5.4. Interaction Between Devices and Kernel 设备与内核的交互的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 路由 交换 网桥 相关转贴
- 下一篇: 从赖斯想谈恋爱-------到教育的启迪