RFC-0192:Fuchsia 上的裝置樹狀結構

RFC-0192: Fuchsia 上的裝置樹
狀態已接受
區域
  • 裝置
說明

使用裝置樹狀結構描述硬體配置的策略

問題
變更
作者
審查人員
提交日期 (年/月)2022-08-03
審查日期 (年/月)2022-10-01

摘要

扁平化裝置樹 (「FDT」或「devicetrees」) 是廣泛使用的格式,用於描述棋盤上的硬體版面配置。這類 ID 的用途與 ACPI 非常類似,不過運作方式其實比抽象層更低,因此也會讓作業系統更複雜。FDT 規格定義了二進位裝置樹狀結構 blob (「DTB」) 格式,以及用於編譯裝置樹狀結構 blob 的來源格式 (「DTS」)。

這個 RFC 提出了務實的方法,引入福奇尼亞裝置中裝置樹狀結構的支援,而無須將裝置樹狀結構 (無論是版面配置或二進位檔格式) 視為 ABI 即可。而是將裝置樹狀結構的確切 ABI 推入駕駛,在自己和韌體之間定義。另請注意,此 RFC 僅關注主機驅動程式使用裝置樹狀結構的情況。如果核心剖析裝置樹狀結構或剖析裝置樹狀結構,個別的 RFC 將說明上述裝置樹狀結構的格式。

提振精神

如要繼續增加 Fuchsia 硬體支援,光是主面板驅動程式並非永續的方式,可能有幾個原因:

  1. 我們希望能疊代硬體設定,而不用重新組合/重建 Fuchsia 映像檔。
  2. 裝置樹狀結構廣受開發人員使用,而我們希望在他們所在地區與開發人員互動。此外,Devicetree 也具有相對健全的生態系統。
  3. 目前的寫入方式因而不適合多個機構之間協同合作。
  4. 這會導致韌體和主機板驅動程式庫之間重複偵測系統中可用的硬體。
  5. 這些功能在支援多個相關的主面板 (即共用 SoC 或 SoC 系列) 時無法妥善調整。
    • 如要支援多個主面板,必須在主面板驅動程式庫中新增條件式,或是有多個主面板驅動程式。
    • 雖然能以簡潔的方式完成此作業,但最終使用義大利程式碼,會比使用裝置樹狀結構來得簡單許多。
    • Devicetree 將可讓您使用單一 Fuchsia 映像檔輕鬆支援多個主機板 (但請注意,在這個階段,我們的目標是使用「通用」Fuchsia 映像檔)。

Devicetree 可以為硬體設定提供單一可靠資料來源,以便與系統的其他部分分開進行操控 (可透過啟動韌體和啟用時的群組輕鬆修改),同時也能易於撰寫 (方便根據同一個 SoC 系列在各板之間共用設定)。

請注意,這項 RFC 的目標並非完全消除主機板驅動程式,董事會仍是 Fuchsia 驅動程式庫程式拓撲中的核心部分,這個 RFC 提議使用裝置樹來補充棋盤驅動程式,以增進彈性。無法以裝置樹狀結構表達的任何內容,仍可在主面板驅動程式庫中實作。

相關人員

講師:

cpu@google.com

審查者:

  • surajmalhotra@google.com
  • curtisgalloway@google.com
  • gkalsi@google.com
  • bradenkell@google.com
  • cja@google.com
  • dpursell@google.com

顧問:

  • aaronwood@google.com
  • mcgrathr@google.com

社群媒體化:

我們內部已分享此提案的簡要概略版本。

詞彙解釋

  • board 驅動程式 - 用來向驅動程式庫架構說明系統硬體的驅動程式。系統中只有一個主機板驅動程式庫程式執行個體。
  • 韌體 - 系統在首次開機時執行的系統的一部分,負責載入並啟動 Zircon。

設計

本文件中的重要字詞「必須」、「不得」、「必要」、「應」、「不應」、「應該」、「不應該」、「建議」、「可能」和「選用」均採用 IETF RFC 2119 說明。

Devicetree 的角色

裝置樹狀結構只會用於說明硬體版面配置資訊。產品設定必須透過產品組合完成。裝置樹狀結構只能包含與主機板有關的資訊,且無論其執行中的產品為何,不應設定可能變動的驅動程式行為 (例如預先分配的記憶體緩衝區或分區對應)。

Devicetree 與 ACPI

我們偏好以裝置樹狀圖 ACPI。如果主面板支援 ACPI,請使用 ACPI 啟動。「不得」在支援 ACPI 的主機上使用裝置樹狀結構。 這是因為 Fuchsia 為每個支援的架構提供單一 ACPI 板驅動程式庫。ACPI 提供的抽象層級與標準化程度越高,支援的機率也就越高。

相容性

我們的裝置樹狀結構繫結不會嘗試維持與 Linux 或其他 OS 的相容性,特別是針對裝置驅動程式庫繫結。這只是因為與 ACPI 不同,裝置樹狀結構並未廣泛標準化,且在不同 OS 版本間完全相同的版面配置和意義也有所不同。不過,我們會採用規格中所述的來源和二進位格式。

Fuchsia 做為平台,不會嘗試指定裝置樹狀結構的確切格式,也不會支援讓各面板使用單一板型驅動程式庫,而我們會依據規範定義一組繫結,支援常見的功能 (例如中斷、GPIO、公車)。使用裝置樹狀結構的桌遊「應」支援此 RFC 中定義的繫結,但他們可以定義自己的繫結,視需要支援其他功能。

我們將提供一種方式,讓裝置樹係指定已寫入目標的主面板驅動程式庫 (例如透過 fuchsia,board-driver = "vim3-devicetree" 等根節點的屬性),讓棋盤驅動程式會用來確保其剖析為相容的裝置樹狀結構。

此外,我們也將定義車板驅動程式「必須」向下游驅動程式公開的介面。這個介面與 ACPI 介面非常類似,而我們會設法將 ACPI 和裝置樹狀結構串連在一起,以便駕駛人在兩者之間進行真正的診斷。

將 Devicetree 傳遞至 Fuchsia。

我們已有類型為 ZBI_TYPE_DEVICETREE 的 ZBI 項目。此 ZBI 項目的內容為裝置樹 blob。我們在這裡唯一需要的變更是更新說明文件,反映主機驅動程式庫可能會使用。

主面板可能會選擇使用裝置樹。在這種情況下,系統啟動載入程式應該知道這一點,而且系統啟動載入程式「應」將裝置樹狀結構做為 ZBI_TYPE_DEVICETREE 項目傳遞。如有需要,主機板 MAY 可能會在組件時直接將裝置樹狀結構納入 ZBI 中 (例如在系統啟動載入程式內建支援 ZBI 前,啟動啟動期間)。

系統啟動載入程式通常「應」從非揮發性儲存空間載入裝置樹狀結構,驗證裝置樹狀結構的真實性,然後在執行階段附加至 ZBI。但如有需要,他們可以使用其他機制 (例如將系統編譯至系統啟動載入程式),並視情況略過驗證步驟 (例如開發人員主面板)。

Fuchsia 平台導入

我們將為希望實作這一組繫結的主機驅動程式提供程式庫。這個程式庫會使用樹狀結構中的現有裝置樹狀結構剖析器。此外,我們也會實作參考板驅動程式庫和裝置樹狀結構,使用這個程式庫啟動實際系統。前者會成為 SDK 的一部分,並位於樹狀結構中,但後者最終可能會移至樹狀結構中。

Devicetree 的可讀性

在裝置上,裝置樹的一項批評是,來源格式可能相當不透明,因為 devicetree 編譯器不支援具名常數。解決這個問題的常見做法是使用包含 #define 陳述式的 C 標頭檔案,這類陳述式會宣告常數的常數名稱,然後加入這些標頭檔案,以便在裝置樹狀結構來源中使用。我們會在 fuchsia.git 內實作這個方法,日後也會支援從繫結程式庫產生這類標頭檔案。

大致上,支援與裝置樹狀結構搭配使用的驅動程式都會有包含標頭的目錄,可供 devicetree 來源檔案使用。這些標頭會定義參照驅動程式庫所公開資源時使用的值,GPIO 驅動程式庫可能具有 PULL_UPPULL_DOWN 等的常數。裝置樹來源檔案建構規則將取決於他們使用的驅動程式,用於驗證裝置樹狀結構 (請參閱說明文件),並新增至提供給 C 預先處理器的 include 路徑。

裝置樹狀結構審查能力

為協助裝置樹狀結構審查,我們也會導入裝置樹「golden」檔案。這些黃金檔案是將裝置樹狀結構來源編譯成二進位檔,然後再編譯回原始碼的輸出內容,這樣來源變更對最終裝置樹狀結構的影響就會清楚。編譯主面板驅動程式庫和裝置樹狀結構時,我們會編譯並解編譯裝置樹狀結構來源,如果輸出內容與黃金不同,建構作業就會失敗。

使用這項功能的動機是,假如某塊面板包含相同的裝置樹狀結構來源檔案 (例如 SoC 定義的項目),就很適合使用這項功能。審查人員可能無法立即瞭解變更「共用」 devicetree 檔案會造成哪些影響。黃金檔案可讓裝置清楚掌握每個裝置樹狀結構在裝置上使用時的最終輸出內容。

節點數

每個 devicetree 節點都會對應到一個 Fuchsia 裝置節點。Fuchsia 裝置節點將成為複合節點,這些節點是代表裝置樹狀結構節點的節點,以及代表裝置所耗用資源的節點 (例如 I2C 裝置、GPIO 等)。這與 ACPI 使用的方法類似。請注意,以下範例僅列舉部分例子,目的僅為說明我們一開始支援的資源類型。日後可視需求新增其他資源類型。特別要注意的是,本文件所述的 FIDL 介面和繫結規則並非最終成果,而是用原始範例來指出介面可支援的功能。一般而言,這些介面會需要更全面的審查。

裝置中繼資料節點

裝置中繼資料節點將公開下列 FIDL 通訊協定。此通訊協定旨在當做通用的「非結構化中繼資料」通訊協定,供裝置驅動程式使用。

library fuchsia.hardware.metadata;

using zx;

/// Maximum length of a property key.
const PROP_MAX: uint32 = 128;

/// Reasonable maximum for amount of data in a byte array.
const MAX_BYTE_ARRAY_LENGTH: uint32 = 4096;

/// Reasonable maximum length for a string.
const MAX_STRING_LENGTH: uint32 = 4096;

/// Reasonable maximum number of entries for a string array.
const MAX_STRING_ARRAY_LENGTH: uint32 = 4096;

/// Maximum number of properties in a dictionary.
const MAX_PROPERTIES: uint32 = 128;

type Value = flexible union {
    /// True if property is present but has no value.
    1: present bool;
    /// Little-endian 32-bit value.
    2: u32 uint32;
    /// Little-endian 64-bit value.
    3: u64 uint64;
    /// String or string array.
    4: string vector<string:MAX_STRING_LENGTH>:MAX_STRING_ARRAY_LENGTH;
    /// Byte array
    5: bytes vector<uint8>:MAX_BYTE_ARRAY_LENGTH;
    /// Child node.
    6: node Dictionary;
};

type Property = flexible table {
    /// Name of the property.
    1: name string:PROP_MAX;
    /// Value of the property.
    2: value Value;
};

type Dictionary = struct {
    /// List of properties. There may be duplicate property names, in which case the first one should win.
    1: properties vector<Property>:MAX_PROPERTIES;
};


protocol NodeMetadata {
    /// Get unstructured metadata belonging to this node.
    GetMetadata() -> (Dictionary) error zx.status;

};

繫結

這些章節會說明裝置樹狀結構繫結,以及功能在 Fuchsia 上的使用方式。

會議和標準資源

我們會使用第 0.3 版規格 2.2 節所述慣例。

在第 2.3 節定義的標準屬性中,我們可能會支援下列屬性:compatiblephandlestatus#address-cells#size-cellsregranges。我們省略 virtual-reg,因為系統啟動載入程式跳轉至核心時,其狀態與主面板驅動程式庫無關 (因為 MMU 位於使用者空間內)。我們省略「dma-ranges」和「dma-coherent」,因為這兩個屬性在 Fuchsia 上沒有立即等項目。

使用 Fuchsia:

  • compatible - 相容陣列中的第一個值會公開為繫結屬性 fuchsia.devicetree.first_compatible。日後有更複雜的繫結系統 (有優先順序) 時,可能會使用其他值。
    • 此外,我們也會允許節點自行定義繫結屬性,方法可能是透過命名空間屬性 (例如,bind,<prop-name> = <value> 會對應至具有 value 值的 prop-name 繫結屬性)。
  • phandle - 用於識別裝置樹狀結構中的裝置節點。由裝置樹編譯器產生,且只會在執行階段使用。
  • status:可在主面板驅動程式庫中使用,控制節點是否發布。我們會調查如何在實作此 RFC 期間,省略受支援繫結的狀態,如果情況能大幅改善裝置樹狀結構來源檔案的清晰度,則可選擇省略該狀態。
    • 具體來說,建議您同時組合裝置樹狀結構來源檔案 (將單一 SoC 定義分割至多個檔案,並在最終的主面板檔案中納入必要的項目),而不要將這些檔案納入一個,並透過 status 屬性停用/啟用 IP 區塊。
  • #address-cells#size-cells - 會在主面板驅動程式庫中使用,以決定其他值的大小。
  • reg - 針對可從樹狀結構根目錄中定址的節點,主機板驅動程式庫會使用該節點來判斷實體記憶體區域。這些記憶體區域將透過 GetMmio(int index) FIDL 呼叫提供給子節點 (可能透過平台匯流排驅動程式)。
  • ranges - 在棋盤驅動程式庫中使用,以決定子項位址範圍如何對應至父項

中斷

中斷繫結將由規格第 2.4 節定義。

主面板驅動程式庫會將下列中繼資料提供給每個中斷控制器驅動程式庫:

/// Data for an individual interrupt.
type InterruptData = flexible table {
    /// The cells associated with an interrupt. The size of this vector
    /// is determined by the `#interrupt-cells` property.
    1: cells vector<uint32>:MAX;
};

/// Data for an interrupt controller.
type InterruptControllerData = flexible table {
    /// This vector contains all of the interrupts discovered by the board driver.
    1: configuration vector<InterruptData>:MAX;
};

每次中斷的驅動程式庫都會發布一個節點。節點具有下列繫結規則:

fuchsia.devicetree.node_type == INTERRUPT;
fuchsia.devicetree.phandle == <phandle of interrupt controller devicetree node>;
fuchsia.devicetree.cellN == <nth configuration cell>;

請注意,phandle 是每個裝置樹狀結構的唯一值,應只用於主面板驅動程式庫產生的繫結規則。

節點會發布下列 FIDL 服務:

library fuchsia.hardware.interrupt;

protocol Provider {
    /// Return the interrupt represented by this provider.
    Get(struct {}) -> (resource struct { irq zx.interrupt; }) error zx.status;
};

在大多數情況下,中斷情況會直接對應於實體硬體中斷的情況,但在某些情況下 (例如 GPIO) 可能會受到多工處理,並涉及中介驅動程式庫。我們未來可能會想這麼做,以允許在核心內處理這些中斷情形,但這類作業不在本文件的討論範圍。

I2C、SPI、UART 和其他週邊裝置

這些公車上的裝置都模擬為其控制器裝置的子項。為了判斷控制器的匯流排類型,我們會為每個支援的公車類型定義額外的「相容」值。舉例來說,i2c 控制器的最後一個相容值會是 fuchsia,i2c-controller

我們會定義公車專用裝置樹狀結構,用來填入 Fuchsia 匯流排驅動程式所使用的中繼資料。這些屬性可能與其他作業系統使用的相等屬性一致,但確切的格式將會記錄在 //docs 中。

代表 I2C/SPI 等公車的節點會稱為 i2c000spi000 等。請注意,即使 devicetree 只能代表這個類型的單一父項,我們仍會為父項設定編號,以便與 ACPI 維持相容。

GPIO

GPIO 的主要差異在於這些資源有一些用戶端設定。舉例來說,客戶可能想要啟用內部提取/向下電阻器,或者圖釘可能是活躍的高/低。

GPIO 控制器節點必須具備 #gpio-cells 屬性,定義用於識別節點所公開 GPIO 的儲存格數量。此外,它必須包含空白的 gpio-controller 屬性,

如果 GPIO 控制器節點沒有 compatible 字串,系統會改為提供與子節點相關的中繼資料,也就是 GPIO 控制器節點的父項。這種做法適用於單一邏輯「控制器」會曝露多組針腳銀行。

我們會定義下列中繼資料,讓控制器驅動程式瞭解每個圖釘執行個體的預期設定。請注意,這個中繼資料並非特定裝置樹狀結構。我們會定義裝置樹狀結構的幾個慣例:

  1. 最後一個設定儲存格含有 GpioConfiguration 旗標。
  2. 其他儲存格會位於每個圖釘中繼資料的 data 向量中。

中繼資料類型看起來可能會像這樣:

library fuchsia.hardware.gpio;

using fuchsia.driver.framework;

/// Maximum number of properties a pin can have.
const uint32 MAX_PIN_PROPERTIES = 32;
/// Maximum number of configuration cells a driver can have.
const uint32 MAX_PIN_CELLS = 8;

/// GPIO configuration flags.
type GpioConfiguration = flexible bits {
    /// If this bit is set, GPIO is active-low. Otherwise, GPIO is active-high.
    GPIO_ACTIVE_LOW = 0x1,
    // more properties here as appropriate.
};

type GpioPinMetadata = flexible table {
    /// Properties the published device should have.
    1: expected_properties vector<fuchsia.driver.framework.NodePropertyValue>:MAX_PIN_PROPERTIES;
    /// Arbitrary, driver-specific data. This will likely encode the pin number.
    2: data vector<uint32>:MAX_PIN_CELLS;
    /// GPIO configuration flags.
    3: flags GpioConfiguration;
};

type GpioMetadata = flexible table {
    /// Standard metadata for GPIO pins.
    /// The GPIO controller driver should publish a GPIO pin node for each of these.
    1: pins vector<GpioPinMetadata>:MAX;
};

此外,GPIO 控制器通常屬於較大的「固定控制器」,其中一組 GPIO 控制器是由單一驅動程式庫管理。為了支援這項功能,如果驅動程式庫無法繫結至個別 GPIO 控制器節點 (即未設定相容或其他繫結屬性),我們會將此中繼資料提供給父項節點。

每個已發布的圖釘應具備下列屬性:

fuchsia.devicetree.node_type == GPIO;
fuchsia.devicetree.phandle == <phandle>;
fuchsia.devicetree.cellN == <nth configuration cell>;

想要使用 GPIO 的裝置樹狀結構節點應使用名為 <name>-gpios 的屬性。這些物件最後會成為名為 gpio-<name>NNN 的片段父項。如果有多個 gpios 命名,系統會根據其索引為這些 gpios 指派數字。這些節點應公開 fuchsia.hardware.gpio.Gpio 通訊協定。

如要將驅動程式庫繫結至 GPIO,就需要繫結規則,例如:

node "gpio" {
    fuchsia.resource.name == "example";
    fuchsia.resource.index == 0; // zeroth gpio in the "example-gpios" list.
    fuchsia.hardware.gpio.Gpio == ZirconTransport;
}

電壓調節器

我們以類似於 GPIO 的方式處理電壓監管器,但是不會向監管機構驅動程式提供中繼資料。系統會從標示為 -supply 的屬性中,推斷其節點的使用情形。

單一監管機構應對應至單一裝置樹狀結構節點,因此不需要額外設定。

監管器驅動程式應發布具有以下屬性的節點:

fuchsia.devicetree.node_type == REGULATOR;
fuchsia.devicetree.phandle == <phandle>;

供應節點只能參照單一監管機構。這些片段應公開 fuchsia.hardware.vreg.Vreg 通訊協定。

接著,「監管機構」使用者將使用以下繫結規則:

node "regulator" {
    fuchsia.resource.name == "vdd"; // equivalent to vdd-supply in devicetree.
    fuchsia.hardware.vreg.Vreg == ZirconTransport;
}

時鐘和其他資源

這些裝置可以獲派多個執行個體。

時鐘與電壓調節器很類似,不需要中繼資料,因為時鐘驅動程式庫會知道它匯出的時鐘數量。時鐘控制器節點應定義 #clock-cells,也就是識別時鐘裝置所需的儲存格數量。

其中應具有以下屬性:

fuchsia.devicetree.node_type == CLOCK;
fuchsia.devicetree.phandle == <phandle>;
fuchsia.devicetree.cellN == <nth configuration cell>;

時鐘使用者可在 clocks 屬性中指定時鐘 ID 陣列,並在 clock-names 屬性中指定選用名稱陣列,藉此定義時鐘。

如果裝置使用時鐘,就會有名為 clk-<name> (如果 clock-names 出現) 的片段父項;或 clk-NNN,其中 NNNclocks 陣列中的時鐘索引。這些片段都會公開 fuchsia.hardware.clock.Device 通訊協定。

若要繫結至時鐘節點,驅動程式庫會使用以下繫結規則:

// If clock-names is expected:
node "clock-input" {
    fuchsia.resource.name == "input";
    fuchsia.hardware.clock.Device == ZirconTransport;
}

// If clock-names is not expected:
node "clock-input" {
    fuchsia.resource.index == 0;
    fuchsia.hardware.clock.Device == ZirconTransport;
}

端對端範例

vim3 USB PHY 為例。嚴格來說,Fuchsia 驅動程式會控制兩個 USB PHY 和一個特殊多工機,在主機和周邊模式之間轉送其中一個 PHY。

如果特別著重於這個方程式的「mux」部分,它具有下列資源:

  • 一個 MMIO 區域。
  • 一項幹擾
  • 一個時鐘。

其 devicetree 節點看起來會像這樣:

/ { // Root node of the devicetree.
    // 64 bit addresses.
    #address-cells = <2>;
    #size-cells = <2>;
    #interrupt-parent = <&gic>;

    usb-mux@ffe09000 {
        compatible = "amlogic,g12b-usb-mux";
        reg = <0x0 0xffe09000 0x0 0xa0>; // MMIO region.
        interrupts = <GIC_SPI 16 INTERRUPT_MODE_EDGE_HIGH>; // Interrupt.
        clocks = <&clk CLK_G12B_USB>; // Clocks.
        clock-names = "usb"; // Clock names.
    };

    gic: interrupt-controller@ff000000 {
        compatible = "arm,gic-400";
        interrupt-controller; // This is an interrupt controller.
        #interrupt-cells = <3>; // 3 32-bit values are used to identify interrupt on this controller.
    };
};

在這個節點版面配置 (特別是查看 usb-mux 節點) 下,裝置樹板驅動程式將執行以下作業:

  • 請參閱 reg 節點,並將 0xffe09000...0xffe090a0 中的 MMIO 區域新增至平台裝置的定義。
  • 查看中斷資源,並為裝置群組新增中斷節點,其中含有「中斷次數」一節所述的屬性。
  • 查看時鐘資源,並使用「時鐘」一節所述的屬性,將時鐘節點新增至裝置群組。

若要繫結至此觸控螢幕裝置,裝置驅動程式庫程式的複合繫結檔案看起來會像這樣:

composite g12b_usb_mux;

primary node "pdev" {
    fuchsia.devicetree.first_compatible == "amlogic,g12b-usb-mux";
    fuchsia.hardware.platform.device.PDev == ZirconTransport;
}

node "clock-usb" {
    fuchsia.hardware.clock.Device == ZirconTransport;
    fuchsia.resource.name == "usb";
}

node "interrupt" {
    fuchsia.hardware.interrupt.Provider == ZirconTransport;
    fuchsia.resource.index == 0;
}

請注意,驅動程式庫看到的繫結屬性不同於用來比對複合屬性的屬性,因為我們會利用裝置群組提供的轉換 API。

實作

我們可能會透過多個 CL 引進實作這個 RFC 的程式碼。在這個階段,實作程序本身不太可能會特別複雜,因為我們不會將任何 API 新增至樹狀結構外的 SDK。

這些 API 最終會成為驅動程式庫 SDK 的一部分,但我們打算先樹狀結構內證明設計,因為此設計較容易快速疊代。

效能

這個 RFC 不太可能增加任何顯著的執行階段效能負擔,因為提議的大部分邏輯會在啟動時發生。

安全性考量

裝置樹狀結構是由系統韌體提供或包含在 ZBI 中的二進位 blob,也是系統受信任的部分。此外,驅動程式只能存取所屬節點的資源。雖然可檢查子節點的名稱和屬性,但無法存取系統性質所擁有子節點擁有的任何資源,但主面板驅動程式庫程式會透過複合式節點的片段父項明確授予資源存取權。

但是,驅動程式將能剖析裝置樹狀結構中的屬性,若未謹慎編寫,可能讓這些屬性容易遭利用。具體來說,我們將讓驅動程式能夠針對預期包含在裝置樹狀結構中的設定資料定義結構定義,但這個剖析程式碼可能會容易遭到利用,因此我們必須確保這些驅動程式更容易對使用這類設定資料的驅動程式進行測試。

主機板驅動程式庫並不屬於 Fuchsia 平台,因此裝置樹狀結構程式庫或主面板驅動程式庫的任何安全性修正都必須由上述電路板驅動程式的擁有者擷取,而新的主面板驅動程式庫則需要重新建構。

隱私權注意事項

裝置樹狀結構的存取權會受到限制,因為該裝置可用來建立裝置指紋。

測試

一開始,我們將使用單元測試來驗證棋盤驅動程式庫的個別功能。最後,我們會使用任意裝置樹狀結構進行整合測試,藉此建立裝置拓撲。

我們也會對裝置樹剖析器進行模糊處理。

我們也將提供工具,根據已知的裝置樹狀結構結構定義驗證裝置樹狀結構。

說明文件

我們會記錄 Fuchsia 使用裝置樹狀結構的方式,以及我們如何在 fuchsia.dev 的文件中支援這些樹。具體來說,我們想讓董事會擁有者瞭解他們如何在他們想要啟動的白板上使用裝置樹;瞭解我們採取的做法與其他作業系統不同,以及如何實際完成工作。

此外,我們也會要求驅動程式指定他們預期的裝置樹狀結構結構定義,並將其納入建構項目。為確保說明文件符合預期和裝置樹狀結構的正確性,我們會實作結構定義驗證,以便依據這些結構定義驗證實際工作環境的裝置樹狀結構。

缺點、替代方案和未知

缺點:可讀性

裝置樹狀結構比較不易閱讀。特別是,組合不同來源檔案以產生最終輸出的模式,意味著您需要剖析所有來源檔案才能理解最終結果。

我們希望透過工具 (也就是黃金檔案) 解決這個問題,但這可能是使用裝置樹狀結構時發生的阻礙。

替代做法:繼續使用純車板驅動程式

我們可以繼續在車板驅動程式中以程式輔助方式表示所有硬體設定,而這需要編寫程式碼並重新建構驅動程式庫來表達變更。如上所述,主機板驅動程式並非持續擴充 Fuchsia 主機板生態系統的永續方法。

替代做法:使用不同的機制來描述硬體

我們可以使用其他資料型機制來描述硬體配置。透過假想替代方法,使用裝置樹的主要優點如下:

  • 廣泛使用且熟悉硬體生態系統的參與者。
  • 常見的建構模塊 (例如中斷支援) 定義明確且容易採用。
  • 我們運用現有的工具。

裝置樹狀結構的主要缺點如下:

  • 沒有明顯的跨作業系統標準化作業。大部分的活動都在 Linux 上。
    • 許多現有的繫結都只為 Linux 驅動程式庫編寫。
  • 對其他硬體設定 (例如產品專屬設定) 而言易於濫用。
  • 多部裝置樹狀結構重疊並改變彼此的節點 (例如 status = "disabled"/status = "okay" 可以停用/啟用節點) 的複雜性。

此外,也沒有顯而易見的裝置樹狀結構 (大多數作業系統都會使用裝置樹狀結構或主機板檔案來解決這個問題)。裝置樹狀結構自 1994 年以來便一直存在,在描述硬體方面堅持使用的主要方法。

替代做法:定義由 Fuchsia 平台強制執行的穩定裝置樹狀結構結構定義

我們可以定義單一通用「裝置樹」板驅動程式庫程式支援的單一裝置樹狀結構結構定義,並成為使用裝置樹狀結構的官方方式。

這讓我們更接近使用裝置樹的所有系統都套用一張 Fuchsia 映像檔的目標,但裝置樹的廣度變化 (與 ACPI 類似) 是相當大的工程,而且可能需要大量演進。

此 RFC 不會排除日後採用這類結構定義,但我們認為目前使用裝置樹狀結構最務實的方法就是如上所述。

替代做法:與更廣大的生態系統,穩定裝置樹狀結構繫結

我們可以與使用裝置樹狀結構的其他群組合作,將整個生態系統中的繫結標準化。

這可能是多年來的努力,但不在 RFC 的涵蓋範圍內。由於絕大多數的裝置樹都不是福奇亞州編寫,因此 Fuchsia 不太可能會執行這類工作。

替代方法:自行使用數位單眼相機

與其使用裝置樹狀結構,我們可以匯總自己的 DSL,並整合了 FIDL 與繫結規則。這可能是我們未來想要執行的作業,但在撰寫時,目前沒有具體的 DSL 實作構想。如果我們確定日後有必要採用 DSL,那麼採用這個 RFC 的課程可能會對其設計造成影響。

先前的圖片和參考資料