组件是在 Google Cloud 控制台中运行的软件的基本构建块, 紫红色。每个组件都是一个可组合的沙盒模块 其他组件。这有助于提高系统安全性和 在各个组件之间创建清晰的接口,使它们更易于 更新或替换。
在 Fuchsia 中,一切都是组成部分(几乎)。从上一个之前的回忆中 讨论 Zircon 时,特意将内核的表面积特意设为较小 大多数核心服务都是在用户空间中实现的。这意味着 在 Fuchsia 上运行的软件是使用组件框架实现的, 包括:
- 面向用户的应用
- 设备驱动程序
- 文件系统
- 媒体编解码器
- 网络堆栈
在内核之外,只有几个低级别异常未使用
组件框架,例如引导加载程序和 userboot
进程。
组件管理器
组件框架的核心是组件管理器。时间是 负责协调所有组件实例的执行, 提供他们的能力,以及 组件。
组件可通过显式方式(例如从某个网址)或隐式方式启动 调用特定 capability。组件管理器会执行 确定是否启动新组件或路由所需的分辨率 向现有实例发出请求。要实现此路由, 组件必须声明它向系统提供的所有功能 及其消耗的任何数据。
<ph type="x-smartling-placeholder">组件管理器通过解析每个组件的声明来确定如何 运行组件并提供必要的功能。组件是 通常通过以下目录中的组件清单文件向系统声明: 该组件包中。
以下是描述 ELF 的组件清单的简单示例 可执行文件,以及一些额外的命令参数:
program: {
runner: "elf",
binary: "bin/hello",
args: [ "Hello", "World!" ],
},
请注意,运行时声明告知组件管理器 组件需要 ELF 运行程序。 这是一个 capability 的示例!
组件功能
组件获得访问更广泛系统各个部分的权限 功能。每个组件都可以声明新功能, 它们提供给系统的功能及其他组件提供的功能 以及它们正常运行所需的资源。
如您所见,runner
是一个用于声明运行时的功能的示例。
由组件使用的资源常见功能类型的其他示例包括
directory
用于访问文件系统资源,protocol
用于通信
与其他组件相关联
开发者使用
组件清单。下面是一个请求
两项功能:对 example-data
目录和服务的读取权限
(请参阅 fuchsia.example.Foo
FIDL 协议)。
use: [
{
directory: "example-data",
rights: [ "r*" ],
path: "/example/data",
},
{
protocol: "fuchsia.example.Foo",
},
]
组件管理器使用功能声明来填充每个组件的
具有必要目录句柄的命名空间。在本示例中,组件
会在其命名空间中收到 /example/data
和 /svc/fuchsia.example.Foo
。
组件组织
系统中的所有组件都组合成单个已启用 root 权限的组件, 组件实例树。这种树结构管理着 组件行为的各个方面。
树中的父组件负责创建 作为其子项,并为这些组件提供必要的 功能。同时,子组件也可以公开功能 返回给父级。子组件可通过以下两种方式之一创建:
- 静态:父级在自身中声明子级存在 组件声明。
- 动态:父级会在
使用
fuchsia.component.Realm
协议运行时。
在树中,所有父组件及其所有子组件构成一个组,称为
一个 realm。领域让父级可以控制流入哪些功能
从其组件子树中移出,从而形成功能边界。
组件可决定是否使用
expose
个关键字:
expose: [
{
protocol: "fuchsia.example.Foo",
from: "self",
},
],
一旦某个 capability 被公开给该领域,父级就可以与其他
组件。这是使用 offer
关键字实现的:
offer: [
{
protocol: "fuchsia.example.Foo",
from: "self",
},
],
组件管理器 将负责解决 使用 组件。这称为功能路由。 组件管理器只能解析公开的功能和 在同一领域中提供。
<ph type="x-smartling-placeholder">
练习:组件
在本练习中,您将探索组件实例树并详细了解 功能路由的实际运用。
启动模拟器
如果您尚未运行实例,请启动模拟器:
ffx emu start --headless
启动完成后,模拟器将输出以下消息和 返回:
Logging to "$HOME/.local/share/Fuchsia/ffx/emu/instances/fuchsia-emulator/emulator.log"
Waiting for Fuchsia to start (up to 60 seconds)........
Emulator is ready.
探索系统组件
打开另一个终端窗口,然后使用 component list
命令转储
系统组件树:
ffx component list
您应该会看到类似于以下(截断)列表的输出:
/
/bootstrap
/bootstrap/archivist
/bootstrap/base_resolver
/bootstrap/console
/bootstrap/console-launcher
/bootstrap/decompressor
/bootstrap/device_name_provider
/bootstrap/driver_manager
/bootstrap/fshost
/bootstrap/kernel_debug_broker
/bootstrap/miscsvc
/bootstrap/netsvc
/bootstrap/power_manager
/bootstrap/ptysvc
/bootstrap/pwrbtn-monitor
/bootstrap/shutdown_shim
/bootstrap/sysinfo
/bootstrap/virtual_console
/core
/core/activity
...
/core/detect
/core/font_provider
/core/log-stats
/core/remote-control
/core/sampler
/core/system-update-committer
/core/temperature-logger
/core/test_manager
/core/full-resolver
/startup
此列表代表组件实例树,其组织结构
构成子树的 bootstrap
、core
和 startup
等组件
根节点。
component show
命令提供了有关每个组件的更多详细信息。
使用此命令可查看 http-client
的详细信息,该组件可提供以下功能:
HTTP 请求服务:
ffx component show http-client.cm
该命令会输出以下报告:
Moniker: /core/network/http-client
URL: #meta/http-client.cm
Type: CML static component
Component State: Resolved
Incoming Capabilities: config
fuchsia.logger.LogSink
fuchsia.net.name.Lookup
fuchsia.posix.socket.Provider
pkg
Exposed Capabilities: fuchsia.net.http.Loader
Merkle root: d9e73f5b061f2f227e596e2e0079ff3a095fc69e192cf85e0d7621826c76356c
Execution State: Running
Start reason: '/core/feedback' requested capability 'fuchsia.net.http.Loader'
Running since: ...
Job ID: 41268
Process ID: 41311
Outgoing Capabilities: fuchsia.net.http.Loader
请注意此处报告的一些详细信息:
- 组件实例的唯一标识符(称为标记)。
- 加载该组件的软件包网址。
- 组件的执行状态。
- 实例的当前作业/进程 ID。
- 为组件请求和公开的一组功能。
跟踪功能路由
上一个输出中列出了三个功能组:
- 传入的功能:组件通过
use
。这些内容通过组件的命名空间提供给组件。 - 传出功能:组件已发布到其 传出目录。
- 公开的功能:组件声明的功能
expose
。这些是组件的公开服务。
http-client
向其父级 realm 公开的功能之一是
fuchsia.net.http.Loader.
这使其他组件能够发出 HTTP 请求。
使用 component select
命令确定有多少组件
此功能:
ffx component capability fuchsia.net.http.Loader
该命令会列出所有匹配的组件:
Exposed:
/core/network/http-client
/core/network
Used:
/core/cobalt
/core/feedback
/core
这表示 cobalt
和 feedback
组件使用此功能
(即,将其列在传入功能下)。共同祖先实体
core
,用于处理此功能的路由
必需的子级。