我最近在學習linux網絡驅動,我想知道如果我的主板上有許多相同類型的網卡,那麼內核是如何驅動他們的?內核是否需要多次加載相同的驅動程序?我認爲這是不可能的,insmod不會這麼做,那麼我怎麼能讓所有同類卡片同時工作呢?linux如何用相同的驅動程序驅動多個網卡?
關於
我最近在學習linux網絡驅動,我想知道如果我的主板上有許多相同類型的網卡,那麼內核是如何驅動他們的?內核是否需要多次加載相同的驅動程序?我認爲這是不可能的,insmod不會這麼做,那麼我怎麼能讓所有同類卡片同時工作呢?linux如何用相同的驅動程序驅動多個網卡?
關於
每張卡(I/O地址,IRQ,...)的狀態都被存儲到一個驅動程序特定的結構中,該結構被直接或間接地傳遞給驅動程序的每個入口點,這樣可以區分牌。這樣,完全相同的代碼可以控制不同的卡(這意味着是的,內核只保留一個驅動程序模塊的一個實例,無論它控制的設備的數量是多少)。
例如,看看drivers/video/backlight/platform_lcd.c
,這是一個非常簡單的LCD電源驅動器。它包含一個名爲platform_lcd
的結構,該結構對該文件是專用的,用於存儲LCD的狀態(無論是否通電,以及是否掛起)。此結構的一個實例通過kzalloc
(即每個LCD設備一個)在驅動程序的probe
功能中分配,並使用platform_set_drvdata
存儲到代表LCD的平臺設備中。已分配此設備的實例然後在所有其他驅動程序功能開始提取回來,它知道它正在哪個實例:
struct platform_lcd *plcd = to_our_lcd(lcd);
to_our_lcd
擴展到lcd_get_data
本身擴展到dev_get_drvdata
(一如果您查看include/linux/lcd.h
,請與platform_set_drvdata相對應)。該功能可以知道設備的狀態已被調用。
這是一個非常簡單的例子,platform_lcd
驅動程序不直接控制任何設備(這是推遲到平臺數據中的函數指針),但添加硬件特定的參數(IRQ,I/O基地等),你會得到99%的Linux驅動程序是如何工作的。
驅動程序代碼只加載一次,但它爲每張卡分配一個單獨的上下文結構。通常你會看到struct pci_driver
和.probe
函數指針。 PCI支持代碼爲每個卡調用一次探測功能,並且它調用alloc_etherdev
爲它所需的任何私有上下文分配具有空間的網絡接口。
非常感謝您的回覆! – liunx
非常感謝,我知道如何在內核中添加多個相同的設備,只需增加platform_device結構的id,0,1,2等等,現在驅動程序就可以很好地檢測這些設備。 – liunx
對於平臺設備,是的 - 您也可以將id設置爲-1以指定系統中只能有一個設備實例(當打印設備名稱時,Linux會忽略此ID)。請注意,platform_devices是特定的,其他總線可能以不同的方式工作,例如,通過他們的地址而不是數字來識別設備。 – Gnurou
好的提示,再次感謝! – liunx