Zircon DDK入门指南
入門
此文檔是Driver Development Kit tutorial文檔的一部分。
編寫設備驅動程序通常被視為一項艱巨的任務,充滿了復雜性,并且需要具有對鮮為人知的核心機密的神秘知識。
本節的目標是揭開這個過程的神秘面紗;你將學到你所需要知道的關于如何編寫設備驅動程序的一切,從它們可以做什么開始,它們如何工作,以及它們如何融入整個系統。
概述
在最高層次上,設備驅動程序的工作是為特定的設備提供統一的接口,同時隱藏特定于設備實現的細節。
例如,兩個不同的以太網驅動程序都允許客戶機發送數據包。使用完全相同的C語言函數。每個驅動程序負責管理自己的硬件,使使用接口相同,即使硬件不同。
請注意,驅動程序提供的接口可能是中間態的 —也就是說,它們不一定代表鏈中的最終設備。
考慮一個基于PCI總線的以太網設備。首先,需要一個基本的PCI驅動程序來理解如何與PCI總線本身進行通信。這個驅動程序對以太網一無所知,但它知道
如何處理機器上存在的特定PCI芯片組。
它枚舉PCI總線上的設備,從每個設備上的各個寄存器收集信息,并提供程序允許其客戶(如基于PCI的以太網驅動程序)執行PCI操作,比如分配一個中斷或一個DMA通道。
因此,這個基本PCI驅動程序向以太網驅動程序提供服務,允許以太網驅動程序管理其相關硬件的。
同時,其它設備(如顯卡)也可以使用基本PCI驅動程序以類似方式管理其硬件。
Zircon模型
為了提供最大的靈活性,Zircon世界中的驅動程序允許綁定到匹配的"parent"設備,并發布自己的"child"設備。此層次結構根據需要擴展:一個驅動程序可發布一個"child",對于另一個將其視為父級的驅動程序,其又可發布自己的子輩,等等。
為了理解這是如何工作的,讓我們跟隨基于PCI的以太網示例講述。
系統首先提供一個特殊的"PCI root"父級。實際上,它表明"我知道這個系統上有一個PCI總線,當你找到它,把它綁在這里。"
以下的"Advanced Topics"章節詳述了此過程.
驅動程序由系統評估(目錄搜索),匹配的驅動程序自動完成綁定。
在這種情況下,找到匹配"PCI root"父級的驅動程序后,自動將其綁定。
這是基本的PCI驅動程序。它的任務是配置PCI總線,并枚舉總線上的外圍設備。
PCI總線對如何識別外圍設備有特定的約定:供應商ID(VID)和設備ID(DID)的組合唯一標識所有可能的PCI設備。在枚舉過程中,這些值從外圍設備讀取,發布的新父級節點包含檢測到的VID和DID(以及其它信息)。
每次發布新設備時,重復以上描述的過程(初始PCI root設備發布);也就是說,系統會對驅動程序進行評估,搜索匹配符合新父輩特點的驅動程序。
然而,對于PCI根設備,我們尋找一個驅動程序,其匹配的一定的功能(稱為"協議",稍后介紹),盡管如此,在本例中,我們搜索的驅動程序匹配不同的協議,即滿足"指定VID和DID的PCI設備"要求的協議。
如果找到合適的驅動程序(匹配要求的協議、VID和DID),綁定到父輩設備上.
作為綁定的一部分,我們初始化驅動程序 —這包括一些如下操作:配置網卡、拉起接口、以及發布此設備的一個或多個子輩。
對于PCI以太網驅動程序的情況,發布"ethernet"接口,其符合另外一種協議,即"ethernet implementation"協議。此協議代表一種通用的協議,接近客戶使用的功能(但還差一步;我們一會兒回來講述這一點)。
協議 Protocols
以上我們提到了三種協議:
- PCI root 協議 (ZX_PROTOCOL_PCIROOT),
- PCI 設備協議 (ZX_PROTOCOL_PCI), 以及
- Ethernet implementation 協議 (ZX_PROTOCOL_ETHERNET_IMPL).
括號中的名稱是對應于協議的C語言常量,以供參考。
那么,什么是協議呢?
協議是一個嚴格的接口定義。
Ethernet驅動程序發布了一個符合ZX_PROTOCOL_ETHERNET_IMPL的接口。這意味著它必須提供一組在數據結構中定義的函數(在本例中,為ethmac_protocol_ops_t)。
這些函數對于實現協議 &mdash 的所有設備都是通用的,例如,所有以太網設備必須提供查詢函數,查詢接口的MAC地址。
當然,其它協議對于必須提供的函數有著不同的要求。
例如,塊設備將發布符合"block implementation protocol" (ZX_PROTOCOL_BLOCK_IMPL)的接口,并且,提供由block_protocol_ops_t結構定義的函數。例如,這個協議包括一個函數,它以塊為單位返回設備的大小。
我們將在下面的章節中研究這些協議。
進階主題
上面介紹了Zircon內核的驅動程序大的框架,以及協議概念介紹。
在本節中,我們將研究一些高級主題,如平臺依賴和平臺無關代碼解耦、"miscellaneous"協議、以及協議與進程是如何映射的。
平臺相關與平臺無關
上面,我們提到ZX_PROTOCOL_ETHERNET_IMPL非常接近客戶所使用的函數,僅一步之差。這是因為還有一個協議ZX_PROTOCOL_ETHERNET,位于客戶和驅動程序之間。此附加協議用于處理所有以太網驅動程序通用的功能(為了避免代碼重復)。這些功能包括緩沖區管理、狀態報告和管理功能。
這實際上是一種"平臺依賴"與"平臺獨立"的解耦;公共代碼存在于平臺獨立部分(一次),驅動程序特定代碼實現在依賴平臺的部分中。
這種體系結構將在多個地方重復見到。例如,對于塊設備,硬件驅動程序綁定到總線(例如PCI),并提供了一個ZX_PROTOCOL_BLOCK_IMPL協議。獨立于平臺的驅動程序綁定到ZX_PROTOCOL_BLOCK_IMPL,并發布面向客戶的協議,ZX_PROTOCOL_BLOCK。
你還將會在顯示控制器、I2C bus, 和串行設備上看到這種體系架構。
雜項協議
在simple drivers文檔中,我們顯示了幾個驅動程序的代碼,其實現基本的功能,但不提供與特定協議相關的服務(即,它們不是"ethernet" 或者 "block"設備)。這些驅動程序綁定到ZX_PROTOCOL_MISC_PARENT。
進程 / 協議 映射
為了保持上述討論的簡單性,我們沒有討論過程分離。因為它與驅動程序相關。
為了理解這些問題,讓我們看看其他操作系統如何處理它們,并將其與Zircon系統的方法進行比較。
在宏內核(如Linux)中,許多驅動程序都是在內核中實現的。這意味著它們共享相同的地址空間,并且實際上運行在相同的"進程"中。
這種方法的主要問題是故障的隔離/發掘。一個糟糕的驅動程序可以控制整個內核,因為它們位于相同地址空間,從而有權訪問所有內核的內存和資源。由于同樣的原因,不合規范的驅動程序可能會帶來安全威脅。
另一個極端是,將每個驅動程序服務都放在其自身的進程中,一些微內核操作系統使用這種方法。它的主要缺點是,如果一個驅動程序依賴于另一個驅動程序的服務,內核必須至少實現在兩個驅動程序進程之間執行上下文切換操作(如果不是數據傳輸)。雖然微內核操作系統通常被設計成在這些方面運行很快,但是高頻率的執行這些操作是不可取的。
Zircon所采用的方法是基于設備主機(devhost)的概念。devhost是一個包含協議棧 &mdash 的進程,即一個或多個共同工作的協議。devhost從ELF共享庫文件(稱為Dynamic Shared Objects,或DSO)加載驅動程序。在simple drivers部分,我們將看到包含在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以上信息,可以看到進程ID1416(第3行到第6行),其是Advanced Configuration and Power Interface (ACPI)驅動程序,由DSO庫bus-acpi.so實現。
在主枚舉過程中,ACPI DSO檢測到一個PCI總線。這導致了發布一個具有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。此外,還創建了一個新的devhost(進程ID"2052"),并加載bus-pci.proxy.so DSO(第7行)。此代理充當新devhost(pid2052)到基本PCI驅動程序(pid1416)的接口。
這就是作出決定的地方,將設備驅動程序放入其自身的進程中 &mdash;新的devhost和基本PCI驅動程序現在運行于兩個不同的進程中
然后,新的devhost2052會找到一個匹配的子級(第8行的intel-ethernet.so 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 &mdash;這是可被客戶使用的部分,所以,沒有進一步的"設備"綁定了。
總結
以上是生活随笔為你收集整理的Zircon DDK入门指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python控制安捷伦频谱仪_安捷伦频谱
- 下一篇: 刚参加完阿里面试:一面+二面+三面+HR