zircon ddk快速入门
# 入門
本文檔是[Driver Development Kit教程](ddk-tutorial.md)文檔的一部分。
編寫設備驅動程序通常被視為一項艱巨的任務,充滿了復雜性,并且需要鮮為人知的內核機密的晦澀知識。
本節的目標是揭開這一過程的神秘面紗;你會學到一切需要知道的如何編寫設備驅動程序的知識。從他們的工作開始,它們如何起作用,以及它們如何適應整個系統。
##概述
在最高級別,設備驅動程序的工作是為特定設備提供統一的接口,同時隱藏特定于設備實現的細節。
例如,兩個不同的以太網驅動程序都允許客戶端發送數據包,使用完全相同的C語言函數輸出接口。每個驅動程序都負責管理自己的硬件,但是,即使硬件不同,客戶端接口相同。
請注意,驅動程序提供的接口可能是“中間”&mdash層面的。也就是說,它們可能不一定代表鏈中的“最終”設備。
考慮一個基于PCI的以太網設備。
首先,需要基本PCI驅動程序,了解如何與PCI總線本身通信。
這個驅動程序對以太網一無所知,但確實知道如何與處理機器上的特定PCI芯片組通信。
它枚舉該總線上的設備,收集來自每個設備上的各種寄存器信息,并提供允許其客戶端(如基于PCI的以太網驅動程序)執行PCI操作的功能,比如分配中斷或DMA通道。
因此,這個基本PCI驅動程序為以太網驅動程序提供服務,以太網驅動程序來管理其相關硬件。
同時,其他設備(如視頻卡)也可以使用基本PCI驅動程序以類似的方式管理其硬件。
##zircon模型
為了提供最大的靈活性,Zircon世界的驅動允許綁定到匹配的“父”設備,并發布自己的“兒子”。
此層次結構根據需要進行擴展:一個驅動程序可能只發布一個子項,另一個驅動程序認為該子項是其parent,第二個驅動程序發布自己的child,等等。
為了理解其工作原理,讓我們按照基于PCI的以太網示例進行操作。
系統首先提供一個特殊的“PCI root”父級。
實際上,它說的是“我知道當你在這個系統上有一個PCI總線,當你找到它時,把它綁定在*這里*?!?/p>
>下面的“高級主題”部分提供了有關此過程的更多詳細信息。
驅動程序由系統(搜索目錄)和驅動程序進行評估匹配自動綁定。
在這種情況下,綁定到“PCI root”父級的驅動程序找到了,并綁定了。
這是基本的PCI驅動程序。它的工作是配置PCI總線,并枚舉總線上的外設。
PCI總線具有關于如何識別外圍設備的特定約定:
供應商ID(** VID **)和設備ID(** DID **)的組合是所有可能的PCI設備的唯一標識。
在枚舉期間,將從外設和新父級讀取這些值,發布包含檢測到的VID和DID(以及其他主機)的節點信息)。
每次發布新設備時,都會執行與上述相同的重復過程(像最初的PCI root設備發布一樣);
也就是說,系統會評估驅動程序,搜索匹配的驅動程序是否符合新父母的特點。
而對于PCI根設備,我們之前在搜索匹配某種功能(稱為“協議”,我們很快就會看到這一點)的驅動程序,但是,在這種情況下,我們將搜索匹配不同協議的驅動程序,即滿足“是一個PCI設備且有給定的VID和DID”的協議要求。
如果找到合適的驅動程序(一個匹配所需的協議,VID和DID),它將與父母綁定。
作為綁定的一部分,我們初始化驅動程序—這涉及此類操作,如設置card進行操作,啟動接口,和發布此設備的一個或多個子設備。
對于PCI以太網驅動程序,它發布“以太網”接口,同時符合另一種協議,稱為“以太網實現”協議。
該協議代表了一種與客戶使用(但刪除了一步;我們將回到此處)功能相近的通用協議。
###協議
我們上面提到了三個協議:
* PCI根協議(`ZX_PROTOCOL_PCIROOT`),
* PCI設備協議(`ZX_PROTOCOL_PCI`),和
*以太網實現協議(`ZX_PROTOCOL_ETHERNET_IMPL`)。
括號中的名稱是與協議對應的C語言常量,供參考。
什么是協議?
協議是嚴格的接口定義。
以太網驅動程序發布了一個符合`ZX_PROTOCOL_ETHERNET_IMPL`的接口。
這意味著它必須提供在數據結構中定義的一組函數(在本案例中是`ethmac_protocol_ops_t`)。
這些功能對于實現協議的所有設備都是通用的 - ?mdash;例如,
所有以太網設備必須提供查詢該MAC地址功能的接口。
其他協議當然對它們的功能有不同的要求,必須提供。
例如,塊設備將發布符合“塊實現協議”(`ZX_PROTOCOL_BLOCK_IMPL`)的接口,必須提供`block_protocol_ops_t`定義的函數。
該協議包括一個以塊為單位返回設備大小的函數。
我們將在以下章節中研究這些協議。
#高級主題
上面介紹了zircon驅動器的全景圖,重點是協議。
在本節中,我們將研究一些高級主題,例如平臺相關的主題和平臺無關的代碼解耦,
“雜項”協議,以及協議和進程的映射方式。
##平臺依賴與平臺無關
上面,我們提到`ZX_PROTOCOL_ETHERNET_IMPL`是“接近”由客戶端使用的函數,但這個接口將會被刪除。那是因為還有一個協議,`ZX_PROTOCOL_ETHERNET`,介于客戶端和驅動兩者之間。
此附加協議用于處理所有以太網驅動程序的通用函數(以避免代碼重復)。
此類功能包括緩沖區管理,狀態報告和管理功能。
這實際上是“平臺依賴”與“平臺無關”的解耦;
公共代碼存在于平臺獨立部分(一次),而特定于驅動程序的代碼在平臺相關部分中實現。
這種架構(套路)在多個地方都有使用。
例如,對于塊設備,硬件驅動程序綁定到總線(例如,PCI),并提供`ZX_PROTOCOL_BLOCK_IMPL`協議。
獨立于平臺的驅動程序綁定到`ZX_PROTOCOL_BLOCK_IMPL`,并發布面向客戶的協議,`ZX_PROTOCOL_BLOCK`。
您還可以通過顯示控制器,I<sup>2</sup>C總線和串行驅動程序看到這一點。
##雜項協議
在[simple drivers](simple.md)中,我們展示了幾個驅動程序的代碼基本功能,但不提供與特定協議相關的服務(即,它們不是“以太網”或“塊”設備)。
這些驅動程序綁定到`ZX_PROTOCOL_MISC_PARENT`。
> @@@更多內容?
##進程/協議映射
為了使討論保持簡單,我們沒有討論進程分離,因為它與驅動有關。
要了解這些問題,讓我們看看其他操作系統如何處理它們,并將其與zircon方法進行比較。
在宏內核(如Linux)中,許多驅動程序都在內核中實現。
這意味著它們共享相同的地址空間,并且有效地生活在同一個“進程”中。
這種方法的主要問題是故障隔離/利用。
壞驅動程序可以取出整個內核,因為它位于同一個地址空間中,因此具有對所有內核內存和資源的特權訪問。
受損的驅動程序可能出于同樣的原因而出現安全威脅。
另一個極端,在一些微內核操作系統中,將每個驅動程序服務都放在自己的進程中。
它的主要缺點是如果一個驅動程序依賴于另一個驅動程序的服務,
內核至少會影響兩個驅動進程的上下文切換操作(如果不是數據傳輸)。
雖然微內核操作系統通常對這種操作設計得很快,但是高頻率的調用它們也是不合需求的。
Zircon采用的方法基于設備主機(** devhost **)的概念。
devhost是一個包含協議棧的進程&mdash;也就是說,一個或更多協同工作的協議。
devhost從ELF共享庫加載驅動程序(稱為動態共享對象,或** DSO **)。
在[simple drivers](simple.md)部分中,我們將看到meta信息包含在DSO中以加快發現過程。
協議棧有效地允許為設備創建完整的“驅動程序”,由平臺相關和平臺獨立組件組成,在一個獨立的過程容器中。
對于高級閱讀器,請查看Zircon命令行可用的`dm dump`命令。
它顯示設備樹,并顯示進程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. ? ? ? ? ? ? ? ? ? [intel-ethernet] pid=2052 /boot/driver/intel-ethernet.so
9. ? ? ? ? ? ? ? ? ? ? ?[ethernet] pid=2052 /boot/driver/ethernet.so
```
從上面可以看到進程ID“1416”(第3到6行)是"高級配置和電源接口"(** ACPI **)驅動程序,
通過DSO`bus-acpi.so`實現。
在主枚舉期間,ACPI DSO檢測到PCI總線。
這導致parent發布了`ZX_PROTOCOL_PCI_ROOT`(第5行,導致`[pci]`條目的出現)
然后導致devhost加載`bus-pci.so` DSO并綁定到它。
DSO是我們上面討論的在整個過程中引用的“基本PCI驅動程序”。
在綁定期間,基本PCI驅動程序枚舉了PCI總線,并找到了以太網卡(第6行檢測總線0,設備2,功能0,顯示為“[00:02:00]”)。
(當然,還發現了許多其他設備,但簡單起見,我們已將它們從上面列出中移除)。
然后,檢測到此設備會導致基本PCI驅動程序發布使用`ZX_PROTOCOL_PCI`和設備的VID和DID新parent。
此外,創建了一個新的devhost(進程ID“2052”)并加載了`bus-pci.proxy.so` DSO(第7行)。
此代理充當從新devhost(pid`2052`)到基本PCI驅動(pid`1416`)的接口。
>這是“切斷”設備驅動程序只在自己進程的地方&mdash;新的devhost和基本的PCI驅動程序現在在兩個不同的進程中。
新的devhost`2052`然后找到一個匹配的child(`intel-ethernet.so`第8行的DSO;它被認為是匹配的,因為它有'ZX_PROTOCOL_PCI`和正確VID和DID)。
DSO發布了一個`ZX_PROTOCOL_ETHERNET_IMPL`,它綁定到一個匹配的child(第9行的`ethernet.so` DSO;它被認為是匹配的,因為它有一個`ZX_PROTOCOL_ETHERNET_IMPL`協議)。
這個鏈沒有顯示的是最終的DSO(`ethernet.so`)發布了一個`ZX_PROTOCOL_ETHERNET`&mdash;這是客戶端可以使用的部分,所以當然不會涉及進一步的“設備”綁定。
?
總結
以上是生活随笔為你收集整理的zircon ddk快速入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器人学习笔记(一)
- 下一篇: UE4/UE5 虚幻引擎,Light光照