2011-09-06 109 views
3

在一個項目中,我參與,我們有以下的硬件設置:兩個相互依賴的Linux內核模塊的結構?

 
    Linux PC ------> "Router" +----> "Device A" 
           | 
           +----> "Device B" 

的Linux PC是一個標準的X86 PC。

「路由器」是我們開發的一塊硬件,它連接到我們系統中的其他硬件。在這個例子中「設備A」。 「路由器」使用USB連接到Linux PC。

「設備A」「設備B」是系統中的一些硬件。它們通過某個通信通道連接到「路由器」硬件(在這種情況下不重要)。

我的任務是爲「設備A」(及其後的其他設備)編寫Linux設備驅動程序。

我已經構建了一個通用的USB驅動程序,談到「路由器」,這工作正常。我的計劃是有一個看起來像這樣的驅動程序堆棧:

 
+----------+----------+ 
| dev_A.ko | dev_B.ko | 
+----------+----------+ 
|  router.ko  | 
+---------------------+ 
| Linux USB driver | 
+---------------------+ 

即:設備驅動程序使用而這又是建立在標準的Linux USB的「router.ko」內核模塊的硬件進行通信驅動核心。

我的問題是,對於Linux PC,只有一個物理設備:通過USB連接的「路由器」硬件,這意味着設備驅動程序成爲某種虛擬設備。

我可以將設備驅動程序和路由器設備驅動程序編譯成一個大的內核模塊,但它似乎不是最好的解決方案。另外,由於「設備A」先前已經直接連接到Linux PC,因此已經存在用於其的具有明確定義的用戶空間接口的驅動程序,該接口必須被保持,因爲已經有應用程序在生產中需要對話它。

我的問題或多或少地歸結爲:

鑑於上述情形的硬件,你將如何構建Linux內核模塊?

+0

在USB中'router'是一個USB集線器。您可以讓您的路由器看起來像集線器,設備A和設備B看起來像連接到集線器的USB設備? –

+0

或者,也許你想使用USB(不能想到名字)多功能接口。你知道,就像你有一個假裝在同一個設備上的CDROM和硬盤驅動器的USB密鑰一樣。 –

+0

不,''router'可以由於各種原因而不能看起來像USB集線器。實際上,我甚至可能根本無法控制路由器硬件上的USB功能。它可以隨時被USB-to-serial芯片代替(將USB串口暴露給linux主機,串口暴露給'router'device)。 –

回答

3

我沒有看到任何問題與您提出的解決方案有一個router.ko模塊,講述實際的硬件和子模塊dev_A.ko和dev_B.ko與router.ko交談。你只需要讓router.ko導出一個「my_register_driver」函數,類似於現有的pci_register_driver函數。你會傳入一個具有「id」成員和「add_device」函數指針的結構; dev_A.ko會傳入id =「A」和add_device = dev_A_add,對dev_B.ko也是如此。

然後當router.ko出現時,它會發現硬件併爲A和B創建虛擬設備(您自己的上下文結構)。然後,當子模塊出現時,router.ko只需調用相應的add_device方法虛擬設備。 router.ko還應該導出dev_A和dev_B模塊可以用來訪問底層硬件的方法。

對於我所想的一個例子,您可以查看上游內核中的mlx4_core,mlx4_ib和mlx4_en模塊(我寫他們,所以我選擇這個例子:)。他們的想法是,有一個PCI設備可以同時用作InfiniBand和以太網設備;所以mlx4_ib和mlx4_en都使用mlx4_core來發現和訪問底層PCI設備。子驅動程序用來詢問哪些設備存在的一小段代碼位於drivers/net/mlx4/intf.c中。

此外,就現有的「設備A」用戶空間接口而言,這應該不成問題。你可以在你的dev_A.ko中實現相同的ABI,除非有一些你沒有提到的複雜功能。

+0

感謝您的建議。目前,我只是把所有東西都砸成了一個內核模塊。這不是很好,但我可能沒有時間再分開它們。 我會將此標記爲已接受的答案,因爲即使我沒有嘗試過,我也可以看到它是如何工作的。 對於有其他想法的人隨時添加另一個答案:) –