驅動程式中的通訊協定

什麼是通訊協定?

通訊協定是嚴格的介面定義。

乙太網路驅動程式庫發布了符合 ZX_PROTOCOL_ETHERNET_IMPL 的介面。 換句話說,它必須提供一組在資料結構中定義的函式。 (在本例中為 ethernet_impl_protocol_ops_t)。

這些函式適用於所有實作這項通訊協定的裝置,例如: 所有乙太網路裝置都必須提供功能,來查詢 存取 API

其他通訊協定當然對於其功能會有不同的要求 必需提供那些項目 舉例來說,封鎖裝置會發布符合 「封鎖實作通訊協定」(ZX_PROTOCOL_BLOCK_IMPL) 和 提供由 block_protocol_ops_t 定義的函式。 此通訊協定中的函式會以區塊的形式傳回裝置大小 例如

在許多情況下,Protocol 用了一種方式 常見的介面實作方法舉例來說驅動程式庫實作 通用區塊介面,並繫結至實施封鎖核心通訊協定的裝置。 和「乙太網路」驅動程式庫在乙太網路介面和 Ethermac 執行相同作業 通訊協定。部分通訊協定 (例如本文提到的兩種通訊協定) 會使用共用記憶體,以及 非遠端程序呼叫 (RPC) 信號的效率更高、延遲時間更短,處理量也高於預期 否則就會實現

類別代表裝置會實作介面或通訊協定的承諾。 裝置檔案系統中的裝置位於拓撲路徑下,例如 /sys/platform/pci/00:02:00/e1000。如果是特定課程,也會顯示 做為 /dev/class/CLASSNAME/... 下的別名。e1000 驅動程式庫會實作 Ethermac 介面,因此也會顯示在 /dev/class/ethermac/000。名稱 類別目錄中是獨一無二的,但不具意義,且會視需要指派。

通訊協定範例:

  • PCI 根通訊協定 (ZX_PROTOCOL_PCIROOT)
  • PCI 裝置通訊協定 (ZX_PROTOCOL_PCI) 和
  • 乙太網路實作通訊協定 (ZX_PROTOCOL_ETHERNET_IMPL)。

括號中的名稱是對應至通訊協定的 C 語言常數,以做為參考。

取決於平台與獨立平台

上面提到,ZX_PROTOCOL_ETHERNET_IMPL 目前「接近」 只移除一個步驟 這是因為還有一個通訊協定 ZX_PROTOCOL_ETHERNET, 用戶端和驅動程式庫 這項額外的通訊協定可以處理所有乙太網路通用的功能 驅動程式 (以免程式碼重複)。 這類功能包括緩衝區管理、狀態回報和管理 函式。

這實際上等同於「取決於平台」與「不受平台影響」分離; 分別存在於平台獨立部分 (一次性) 以及驅動程式庫專屬程式碼 只會在各平台端實作

這個架構在多個位置重複。 若是使用區塊裝置,例如,硬體驅動程式庫會繫結至匯流排 (例如PCI) 並提供 ZX_PROTOCOL_BLOCK_IMPL 通訊協定 平台獨立驅動程式庫會繫結至 ZX_PROTOCOL_BLOCK_IMPL,並發布 用戶端通訊協定,ZX_PROTOCOL_BLOCK

你也可以在顯示控制器、I2C 匯流排和序列驅動程式中看到硬體鎖。

程序 / 通訊協定對應

為了讓上述討論能保持簡單明瞭,我們不得不談到程序區隔 和駕駛人的關係 為了瞭解問題,我們來看看其他作業系統如何處理問題 然後跟 Fuchsia 的做法比較

在單體式核心 (例如 Linux) 中,許多驅動程式會在核心內實作。 換言之,這些群組會共用相同的位址空間,且能實際居住在相同的位址空間 「處理」。

這種方法的主要問題是隔離錯誤 / 利用漏洞。 品質不佳的驅動程式庫可能會把整個核心奪走整個核心,因為一切都位於相同位址 空間,因此具備所有核心記憶體與資源的特殊存取權。 遭入侵的驅動程式庫也可能基於相同原因產生安全威脅。

另一個極端問題,也就是讓每項驅動程式庫服務各自獨立, 會由部分微核心作業系統使用 最大的缺點是,如果其中一個驅動程式庫須使用另一名驅動程式庫的服務 核心至少應生效一項內容切換作業 (如果不是資料移轉作業) 即可。 而微核心作業系統的設計通常是為了 若是如此,則以高頻率執行這些作業是最理想的情況

Fuchsia 採取的方法是以驅動程式代管程序的概念為基礎。 驅動程式代管程序是包含通訊協定堆疊的程序,也就是 讓更多通訊協定能搭配運作 驅動程式主機會從 ELF 共用程式庫 (稱為「動態共用物件」) 載入驅動程式 或 DSO)。

通訊協定堆疊可有效建立完整的「驅動程式庫程式」的 裝置,包含各平台獨立和平台獨立元件; 並透過獨立的程序容器建構容器

如果您使用的是進階讀卡機,請查看以下提供的 driver dump 指令: Fuchsia 指令列這邊顯示一系列裝置, 程序 ID、DSO 名稱以及其他實用資訊。

以下是只顯示 PCI 乙太網路驅動程式庫零件的高度編輯版本:

1. [root]
2.    [sys]
3.       <sys> pid=1416 /boot/driver/bus-acpi.so
4.          [acpi] pid=1416 /boot/driver/bus-acpi.so
5.          [pci] pid=1416 /boot/driver/bus-acpi.so
            ...
6.             [00:02:00] pid=1416 /boot/driver/bus-pci.so
7.                <00:02:00> pid=2052 /boot/driver/bus-pci.proxy.so
8.                   [e1000] pid=2052 /boot/driver/e1000.so
9.                      [ethernet] pid=2052 /boot/driver/ethernet.so

在上述範例中,您可以看到該程序 ID 1416 (第 3 到 6 行) 是進階設定和電源介面 (ACPI) 驅動程式庫, 。bus-acpi.so

在主要列舉期間,ACPI DSO 偵測到 PCI 匯流排。 這會導致發布使用 ZX_PROTOCOL_PCI_ROOT (第 5 行、 造成 [pci] 項目的外觀), 然後,驅動程式代管程序載入 bus-pci.so DSO 並繫結至該函式。 DSO 是「基本 PCI 驅動程式庫」我曾說過 討論。

在繫結期間,基本 PCI 驅動程式庫列舉了 PCI 匯流排,並找到一個乙太網路 資訊卡 (第 6 行偵測到公車 0,裝置 2,函式 0,顯示為 [00:02:00])。 (當然,許多其他裝置也已找到,不過我們已將這些裝置從 為求簡單起見)。

偵測這部裝置之後,基礎 PCI 驅動程式庫又發布了新的父項 使用 ZX_PROTOCOL_PCI,以及裝置的 VID 和 DID。 此外,已建立新的驅動程式代管程序 (程序 ID 2052),並使用 bus-pci.proxy.so DSO (第 7 行)。 這個 Proxy 可做為新驅動程式代管程序 (pid 2052) 與基礎 PCI 的介面 驅動程式庫 (pid 1416)。

這是當時做出的決定隨著裝置驅動程式庫 — 新驅動程式代管程序與基礎 PCI 驅動程式庫,現在只需兩個 不同的處理程序

新的驅動程式代管程序 2052 接著會尋找相符的子項 (e1000.so 第 8 行 DSO該文字包含 ZX_PROTOCOL_PCI,而正確的 VID 和 DID)。 這個 DSO 會發布 ZX_PROTOCOL_ETHERNET_IMPL,以繫結至比對結果 子項 (第 9 行的 ethernet.so DSO;由於該版本包含 ZX_PROTOCOL_ETHERNET_IMPL 通訊協定)。

這個鏈結未顯示的內容是最終 DSO (ethernet.so) 發布的版本 ZX_PROTOCOL_ETHERNET 是可供用戶端使用的功能 當然也沒有裝置具有約束力

驅動程式架構版本 2 (DFv2)

如果已啟用驅動程式庫架構第 2 版,driver dump 會顯示 我們可以看到

$ driver dump
[root] pid=4766 fuchsia-boot:///#meta/platform-bus.cm
   [sys] pid=4766
      [platform] pid=4766
         [pt] pid=4766 fuchsia-boot:///#meta/platform-bus-x86.cm
            [acpi] pid=4766
               [acpi-pwrbtn] pid=4766 fuchsia-boot:///#meta/hid.cm
               ...
            [PCI0] pid=4766 fuchsia-boot:///#meta/bus-pci.cm
               [bus] pid=4766
                 ...
                 [00_04_0] pid=4766 fuchsia-boot:///#meta/virtio_ethernet.cm
                    [virtio-net] pid=4766 fuchsia-boot:///#meta/netdevice-migration.cm
                       [netdevice-migration] pid=4766 fuchsia-boot:///#meta/network-device.cm
                          [network-device] pid=4766
        ...

請務必指出節點 (裝置在 DFv2) 沒有相關聯的 .so 檔案。而是顯示 附加至指定節點的驅動程式庫元件資訊清單。