對驅動程式載入失敗時進行偵錯

本指南將提供最佳做法,協助您在新驅動程式無法載入您的 Fusia 系統時,對該驅動程式進行偵錯。

查看驅動程式目前是否在系統中執行

在 Fuchsia 中,當驅動程式庫與代表硬體或虛擬裝置的節點配對時,系統就會在系統中載入驅動程式庫。比對出並載入完成後,驅動程式庫就會開始執行,並向系統中的其他元件提供服務。

如要查看您的 Fuchsia 系統是否已載入驅動程式庫 (也就是目前正在執行),請執行下列指令:

ffx driver list --loaded

這個指令會輸出系統中載入的驅動程式清單,例如:

$ ffx driver list --loaded
fuchsia-boot:///#meta/bus-pci.cm
fuchsia-boot:///#meta/fvm.cm
fuchsia-boot:///#meta/hid.cm
fuchsia-boot:///#meta/intel-rtc.cm
fuchsia-boot:///#meta/netdevice-migration.cm
fuchsia-boot:///#meta/network-device.cm
fuchsia-boot:///#meta/pc-ps2.cm
fuchsia-boot:///#meta/platform-bus-x86.cm
fuchsia-boot:///#meta/platform-bus.cm
fuchsia-boot:///#meta/ramdisk.cm
fuchsia-boot:///#meta/sysmem.cm
fuchsia-boot:///#meta/virtio_block.cm
fuchsia-boot:///#meta/virtio_ethernet.cm
fuchsia-pkg://fuchsia.com/virtual_audio#meta/virtual_audio_driver.cm
fuchsia-pkg://bazel.pkg.component/qemu_edu#meta/qemu_edu.cm
fuchsia-boot:///#meta/block.core.cm
fuchsia-boot:///#meta/intel-i2c-dfv2.cm

或者,如果您知道確切的驅動程式庫元件,可以使用 ffx component show 指令查看元件的狀態,例如:

$ ffx component show intel-i2c-dfv2
               Moniker: /bootstrap/boot-drivers:root.sys.platform.pt.pci.00_15_2.composite
                   URL: fuchsia-boot:///#meta/intel-i2c-dfv2.cm
                  Type: CML dynamic component
       Component State: Resolved
 Incoming Capabilities: fuchsia.boot.Items
                        fuchsia.driver.compat.Service
                        fuchsia.logger.LogSink
                        pkg
  Exposed Capabilities: diagnostics
                        fuchsia.driver.compat.Service
       Execution State: Running
          Start reason: Instance is in a single_run collection
 Outgoing Capabilities: fuchsia.driver.compat.Service

如果您發現系統未載入驅動程式庫,請參閱下一節的資訊來偵錯問題。

偵錯的最佳做法

在編寫新 Fuchsia 驅動程式庫的初始階段,您需要先確保您的新元件能在 Fuchsia 系統中識別為驅動程式庫。在 Fuchsia 系統中將元件列為驅動程式庫後,您就可以開始著手撰寫繫結規則,如此一來,驅動程式才能繫結至系統中代表目標裝置的特定節點。將驅動程式庫繫結至目標節點 (因此,驅動程式庫已成功載入系統中) 後,您就可以繼續下一個開發指令,也就是開始為驅動程式庫實作功能。

對 Fuchsia 系統中無法載入的驅動程式庫進行偵錯時,請考慮下列步驟:

  1. 檢查元件資訊清單
  2. 向驅動程式庫架構註冊驅動程式庫
  3. 確認繫結規則是否正確

1. 檢查元件資訊清單

如要讓 Fuchsia 系統以驅動程式庫形式查看元件,元件資訊清單 (.cml) 中的元件 runner 欄位必須設為 driver,例如:

    program: {
        runner: 'driver',
        ...
    }

2. 向驅動程式庫程式架構註冊驅動程式

接著,確認您的元件已列為 Fuchsia 系統中的驅動程式庫。

您必須在 Fuchsia 系統中將元件明確註冊為驅動程式,才算是驅動程式。如果元件沒有以驅動程式庫形式顯示在系統中,表示驅動程式架構無法得知該元件,因此系統不會將這類元件視為驅動程式繫結。因此,在寫出新驅動程式庫時,讓新元件顯示為 Fuchsia 系統中的驅動程式庫,應該是第一個里程碑。

若要在 Fuchsia 系統中將元件註冊為驅動程式庫,請執行下列步驟:

  1. 將包含驅動程式庫元件的 Fuchsia 套件上傳至 Fuchsia 套件伺服器

  2. 在系統中將元件註冊為驅動程式庫:

    ffx driver register <URL>
    

    URL 替換為 Fuchsia 套件伺服器中的元件網址,例如:

    ffx driver register fuchsia-pkg://fuchsia.com/my_example#meta/my_new_driver.cm
    
  3. 查看系統中目前已註冊 (但不一定執行中的) 的驅動程式清單:

    ffx driver list
    

    這個指令會輸出類似以下的輸出內容:

    $ ffx driver list
    fuchsia-boot:///#meta/block.core.cm
    fuchsia-boot:///#meta/bus-pci.cm
    fuchsia-boot:///#meta/fvm.cm
    fuchsia-boot:///#meta/hid-input-report.cm
    fuchsia-boot:///#meta/hid.cm
    fuchsia-boot:///#meta/intel-rtc.cm
    fuchsia-boot:///#meta/netdevice-migration.cm
    fuchsia-boot:///#meta/network-device.cm
    fuchsia-boot:///#meta/pc-ps2.cm
    fuchsia-boot:///#meta/platform-bus-x86.cm
    fuchsia-boot:///#meta/platform-bus.cm
    fuchsia-boot:///#meta/ramdisk.cm
    fuchsia-boot:///#meta/sysmem.cm
    fuchsia-boot:///#meta/virtio_block.cm
    fuchsia-boot:///#meta/virtio_ethernet.cm
    fuchsia-boot:///#meta/zxcrypt.cm
    fuchsia-pkg://fuchsia.com/virtual_audio#meta/virtual_audio_driver.cm
    fuchsia-pkg://fuchsia.com/my_example#meta/my_new_driver.cm
    

    確認您的新驅動程式庫元件顯示在此清單中。

3. 確認繫結規則是否正確

最後,請開始檢查駕駛人員的繫結規則。

驅動程式的繫結規則會決定可在 Fuchsia 系統中繫結至哪些節點。驅動程式庫架構只會在符合系統中特定節點的節點屬性時載入驅動程式。如果驅動程式已在系統中註冊,但未載入 (因此並未執行),請檢查驅動程式的繫結規則,並確認這些驅動程式是否正確編寫,符合 Fuchsia 系統中目標節點的繫結屬性。

如要查看 Fuchsia 系統中的所有節點及其節點屬性,請執行下列指令:

ffx driver list-devices -v

這個指令會輸出類似以下的輸出內容:

$ ffx driver list-devices -v
...
Name : I2C2
Moniker : root.sys.platform.pt.acpi.I2C2
Driver : None
6 Properties
[ 1/ 6] : Key fuchsia.BIND_ACPI_ID Value 0x000034
[ 2/ 6] : Key fuchsia.BIND_PCI_TOPO Value 0x0000aa
[ 3/ 6] : Key fuchsia.BIND_ACPI_BUS_TYPE Value 0x000001
[ 4/ 6] : Key "fuchsia.hardware.acpi.Device" Value true
[ 5/ 6] : Key fuchsia.BIND_PROTOCOL Value 0x00001e
[ 6/ 6] : Key "fuchsia.platform.DRIVER_FRAMEWORK_VERSION" Value 0x000002
...
Name : 00_15_2
Moniker : root.sys.platform.pt.pci.00_15_2
Driver : None
9 Properties
[ 1/ 9] : Key fuchsia.BIND_PROTOCOL Value 0x00001f
[ 2/ 9] : Key fuchsia.BIND_PCI_VID Value 0x008086
[ 3/ 9] : Key fuchsia.BIND_PCI_DID Value 0x009d62
[ 4/ 9] : Key fuchsia.BIND_PCI_CLASS Value 0x000011
[ 5/ 9] : Key fuchsia.BIND_PCI_SUBCLASS Value 0x000080
[ 6/ 9] : Key fuchsia.BIND_PCI_INTERFACE Value 0x000000
[ 7/ 9] : Key fuchsia.BIND_PCI_REVISION Value 0x000021
[ 8/ 9] : Key fuchsia.BIND_PCI_TOPO Value 0x0000aa
[ 9/ 9] : Key "fuchsia.platform.DRIVER_FRAMEWORK_VERSION" Value 0x000002
...

對繫結規則進行偵錯時,建議您以視覺化的方式檢查這個指令的輸出內容,確保 Fuchsia 系統所含節點具有正確的節點屬性。另請注意,每個節點只能繫結一個驅動程式庫。因此,您想確保 Fuchsia 系統中的目標節點尚未有繫結的驅動程式庫。

上方的範例輸出內容顯示了一個 intel-i2c 驅動程式庫可繫結的 PCI 節點和 ACPI 節點。您可以按照以下方式,針對這兩個節點撰寫驅動程式的繫結規則:

primary node "pci" {
    fuchsia.driver.framework.dfv2 == true;

    fuchsia.BIND_PROTOCOL == fuchsia.pci.BIND_PROTOCOL.DEVICE;
    fuchsia.BIND_PCI_VID == fuchsia.pci.BIND_PCI_VID.INTEL;
    accept fuchsia.BIND_PCI_DID {
        // For now we only add the DID for the touchpad.
        fuchsia.intel.platform.pci.BIND_PCI_DID.SUNRISE_POINT_SERIALIO_I2C2,
    }
}

node "acpi" {
    fuchsia.driver.framework.dfv2 == true;

    fuchsia.BIND_ACPI_ID == 0x000034;
    fuchsia.BIND_PCI_TOPO == 0x0000aa;
    fuchsia.BIND_ACPI_BUS_TYPE == 0x000001;
}

若是 ACPI 節點,請以視覺化方式確認繫結規則中指定的 ACPI 值與 ACPI 節點屬性 (如上述 ffx 指令的輸出內容所示) 相符。如果是 PCI 節點,請直接檢查 PCI 繫結程式庫,檢查程式庫中定義的值是否與 PCI 節點屬性的值相符。(如要進一步瞭解這兩種方法,請參閱編寫驅動程式繫結規則)。

附錄

錯誤:找不到驅動程式庫生命週期

在 Fuchsia 系統中將元件註冊為驅動程式庫後,您可能會在裝置記錄 (ffx log) 中看到類似以下的錯誤訊息:

Failed to start driver; driver lifecycle not found url=<DRIVER_URL>

如果遇到這個錯誤,請務必將 FUCHSIA_DRIVER_EXPORT() 巨集加至驅動程式庫程式元件原始碼的結尾處,例如:

// Register driver hooks with the framework
FUCHSIA_DRIVER_EXPORT(qemu_edu::QemuEduDriver);

如要進一步瞭解這個巨集,請參閱驅動程式程式碼研究室中的「驅動程式庫掛鉤」。