本文档演示了如何构建驱动程序,重点介绍了定义软件包、组件和驱动程序的最佳实践。
概念
驱动程序是一种组件,因此在深入了解之前,请务必先了解如何构建组件。
驱动程序软件包 GN 模板
驱动程序作者应使用特定于驱动程序的 GN 模板。 Fuchsia 定义了以下 GN 模板来定义驱动程序组件和驱动程序软件包:
以下是一个假设的软件包,其中包含一个驱动程序组件:
import("//build/drivers.gni")
driver_bind_rules("bind") {
rules = "meta/driver.bind"
bind_output = "my-driver.bindbc"
}
fuchsia_cc_driver("driver") {
output_name = "my-driver"
sources = [ "my_driver.cc" ]
}
fuchsia_driver_component("component") {
component_name = "my-driver"
deps = [
":driver",
":bind",
]
}
fuchsia_driver_package("package") {
package_name = "my-driver"
deps = [ ":component" ]
}
请注意以下细节:
* fuchsia_driver_component()
模板声明了组件。
它依赖于驱动程序共享库 (fuchsia_cc_driver()
) 以及驱动程序的绑定规则 (driver_bind_rules()
)。* fuchsia_driver_component()
会自动为驱动程序生成组件清单。我们将在后面的部分中了解其外观。
* 组件名称和软件包名称均派生自其目标名称。
在上面的示例中,这些名称组合在一起,形成了用于启动组件的网址:fuchsia-pkg://fuchsia.com/my_package#meta/my_driver.cm
。
自动生成的组件清单是什么样的?
当您使用 fuchsia_driver_component
模板时,系统会自动为驱动程序生成组件清单。对于上述示例,它将如下所示
{
program: {
runner: 'driver',
binary: driver/my_driver.so,
bind: meta/bind/my_driver_bind.bindbc
}
}
请注意以下细节:
* binary
字段指向驱动程序共享库。
* bind
字段指向驱动程序的绑定规则文件。
我可以包含自己的组件清单吗?
没问题!如需编写自己的组件清单,只需将其作为文件添加到项目中,然后更新 fuchsia_driver_component
以指向该清单:
fuchsia_driver_component("component") {
component_name = "my-driver"
manifest = "meta/my-own-manifest.cml
deps = [
":driver",
":bind",
]
}
在 build 中包含驱动程序。
为了将驱动程序纳入 build 中,您需要将其放入两个特殊位置。
第一种是 //build/drivers/all_drivers_list.txt
。如果您不这样做,系统会显示一条构建错误,提醒您注意这一点。
all_drivers_list.txt
文件应包含 Fuchsia 代码库中包含的所有驱动程序标签。此列表会及时更新,以便驱动程序框架团队确保所有驱动程序都能继续获得支持和更新。
如果您的驱动程序只能为 x64 构建,请将其添加到:
//build/drivers/all_drivers_lists_x64.txt
如果您的驱动程序只能为 arm64 构建,请将其添加到:
//build/drivers/all_drivers_lists_arm64.txt
第二个位置是://bundles:drivers-build-only
。
如果您忘记在此处添加驱动程序,也会出现 build 错误。
如需添加到此列表,您应确保将驱动程序组件添加到源位置中的本地驱动程序组。
例如,对于在 //src/ui/input/drivers
下添加的新驱动程序,您需要向 //src/ui/input/drivers
添加一个条目。
对于 drivers-build-only
目标,您需要确保包含 fuchsia_driver_components()
目标的路径,而不是直接指向 fuchsia_cc_driver()
目标。
在映像中包含驱动程序
如果您想将驱动程序包含在要刷入设备的映像中,有两种选择:
1) 通过程序集输入软件包 (AIB) 包含驱动程序 2) 通过主板输入软件包 (BIB) 包含驱动程序
在这两种情况下,您都可以将驱动程序放在启动软件包或基本软件包中。
通过 Assembly Input Bundle 包含驱动程序
如果驱动程序是平台的一部分,则这是正确的方法。在 //bundles/assembly/BUILD.gn
中添加新的 assembly_input_bundle
目标。
示例如下:
assembly_input_bundle("my_driver") {
boot_driver_packages = [
{
package_target = "//path/to/my/driver:package"
driver_components = [ "meta/my_driver.cm" ]
},
]
}
如果您想将驱动程序作为基本软件包而非启动软件包进行添加,请将代码段中的 boot_driver_packages
替换为 base_driver_packages
。
接下来,在 //src/lib/assembly/platform_configuration/src/subsystems/
下的相关子系统文件中添加一些逻辑,以便仅在必要时包含 AIB。
if context.board_info.provides_feature("fuchsia::my_driver") {
builder.platform_bundle("my_driver");
}
最后,对于应包含此驱动程序的板,请将 fuchsia::my_driver
添加到其 board_input_bundle
的 provided_features
部分。您可以在 //boards/${board_name}/BUILD.bazel
下找到此功能。
包括通过 Board Input Bundle 提供的
一般来说,要直接包含在主板输入中的驱动程序应使用 Bazel build 规则,而不是 GN。因此,本指南未提供有关如何完成此任务的说明。在这种情况下,请考虑将驱动程序移植为使用 Bazel。