AAOS 中为支持 VirtIO 所需进行的大部分更改都涉及到 Android 通用内核中 HAL 实现级别及以下级别的更改。Android 框架使用 AAOS 客户机虚拟机内核中的 VirtIO 驱动程序与一个与硬件无关的通用 HAL 进行通信,而 VirtIO 驱动程序使用 VirtIO 协议与主机端的 VirtIO 设备进行通信。主机端的 VirtIO 设备可以使用 SoC 专用设备驱动程序来访问物理硬件。
VirtIO 驱动程序与 VirtIO 设备之间的通信是通过 virtqueue
进行的,virtqueue 是分散聚集表的类似于 DMA 的环形缓冲区。多种传输方式(如 MMIO 或 PCI)可用于在虚拟机之间交换 VirtIO 消息。
在某些情况下,vsock
已被用于虚拟机间通信。通过 vsock
接口使用与独立虚拟机上的对等代理的连接来支持车载 HAL、音频控制和转储状态通信。GRPC-vsock
用于访问这些非标准化子系统。Android 源代码树中的 GRPC 已经过修改,可以与 vsock
(地址格式为 vsock:CID:PORT_NUMBER
)搭配使用。
![虚拟化架构](https://source.android.google.cn/static/docs/devices/automotive/images/trout_arch_01.png?authuser=9&hl=cs)
音频
在虚拟化 AAOS 中,Android 客户机虚拟机可以使用 virtio-snd
访问音频。virtio-snd
会向 Android 虚拟机提供虚拟化 PCM 设备,以便音频 HAL 实现可以与带有 TinyALSA 库的虚拟化声音设备进行互动。
默认的音频 HAL 实现位于 AOSP 中的 /device/google/trout/hal/audio/6.0
下。OEM 可以为其平台修改 ro.vendor.trout.audiohal.{in,out}_period_{ms,count}
。此外,OEM 还可以通过替换 /device/google/trout/aosp_trout_common.mk.
中与音频相关的变量来实现他们自己的音频 HAL。
音频控制 HAL 管理 AAOS 中的音频焦点。例如,当系统正在播放紧急声音时,正在播放的背景音乐可能需要静音。在这种情况下,音频控制 HAL 将通知那些正在播放音乐的应用静音。在虚拟化系统中,声音可能来自其他虚拟机。在参考实现中,AAOS 客户机虚拟机运行一个音频控制服务器守护程序,该守护程序使用 GRPC-vsock
接收来自其他虚拟机的音频焦点请求。
主机虚拟机可以使用 device/google/trout/hal/audiocontrol/2.0/libandroid_audio_controller
将音频控制请求发送到 AAOS。当 libandroid_audio_controller
持有音频焦点时,它将继续向 AAOS 发送检测信号,直到释放焦点。
![音频架构](https://source.android.google.cn/static/docs/devices/automotive/images/trout_audio_05.png?authuser=9&hl=cs)
蓝牙
蓝牙实现基于下面的设计示意图。
![蓝牙架构](https://source.android.google.cn/static/docs/devices/automotive/images/trout_bt_06.png?authuser=9&hl=cs)
蓝牙免触摸配置文件
为了在 trout
上启用蓝牙免触摸配置文件 (HFP),我们扩展了 VirtIO 声音设备规范以支持音频控件。借助此方法,主机/Hypervisor 端的 VirtIO 声音设备提供了三个与 HFP 相关的音频控件:
hfp_enable
hfp_set_sampling_rate
hfp_volume
当 AAOS作为客户机虚拟机运行时,AAOS 会使用 TinyAlsa 设置这些音频控件。为了启用 HFP 用例,主机/Hypervisor 会相应地执行特定于供应商的路由和校准。
蓝牙实现基于下面的设计示意图。
![蓝牙架构](https://source.android.google.cn/static/docs/devices/automotive/images/trout_bt_06.png?authuser=9&hl=cs)
转储状态
在为虚拟化 AAOS 生成 bug 报告时,包括主机虚拟机信息很有用,这样开发者就可以更全面地了解系统。为此,trout
参考实现实现了 IDumpstateDevice
HAL,该 HAL 可通过 GRPC-vsock
收集主机虚拟机信息。以“tar”格式打包的主机虚拟机信息在 bug 报告中命名为 dumpstate_board.bin
,而转储日志位于 dumpstate_board.txt
。
如需配置要执行的命令,请执行以下操作:
- 将配置详细信息从下面的文件复制到一个 XML 文件中,例如
config.xml
。<dumpstateHalConfiguration version="1.0"> <services> <service name="coqos-virtio-blk" command="/bin/journalctl --no-pager -t coqos-virtio-blk"/> <service name="coqos-virtio-net" command="/bin/journalctl --no-pager -t coqos-virtio-net"/> <service name="coqos-virtio-video" command="/bin/journalctl --no-pager -t coqos-virtio-video"/> <service name="coqos-virtio-console" command="/bin/journalctl --no-pager -t coqos-virtio-console"/> <service name="coqos-virtio-rng" command="/bin/journalctl --no-pager -t coqos-virtio-rng"/> <service name="coqos-virtio-vsock" command="/bin/journalctl --no-pager -t coqos-virtio-vsock"/> <service name="coqos-virtio-gpu-virgl" command="/bin/journalctl --no-pager -t coqos-virtio-gpu-virgl"/> <service name="coqos-virtio-scmi" command="/bin/journalctl --no-pager -t coqos-virtio-scmi"/> <service name="coqos-virtio-input" command="/bin/journalctl --no-pager -t coqos-virtio-input"/> <service name="coqos-virtio-snd" command="/bin/journalctl --no-pager -t coqos-virtio-snd"/> <service name="dumpstate_grpc_server" command="/bin/journalctl --no-pager -t dumpstate_grpc_server"/> <service name="systemd" command="/bin/journalctl --no-pager -t systemd"/> <service name="systemctl" command="/bin/systemctl status"/> <service name="vehicle_hal_grpc_server" command="/bin/journalctl --no-pager -t vehicle_hal_grpc_server"/> </services> <systemLogs> <service name="dmesg" command="/bin/dmesg -kuPT"/> </systemLogs> </dumpstateHalConfiguration>
- 在启动时,将新 XML 文件的路径传递给转储状态服务器。例如:
--config_file my_config.xml
增强型视觉系统 (EVS)
增强型视觉系统 (EVS) 用于显示由后视摄像头和环视摄像头拍摄的视频。在虚拟化 AAOS 中,EVS 堆栈可以从使用 VirtIO-video 驱动程序的虚拟化 V4L2 流式传输设备访问视频流。
车库模式
如需了解详情,请参阅什么是车库模式?。
进入和退出车库模式由车载 HAL 发送的 AP_POWER_STATE_REQ
属性触发。在虚拟化模式下,车库模式从主机端触发。主机虚拟机应保持开机状态,以便为 Android 虚拟机提供虚拟设备,直到 Android 关机。主机虚拟机上的 VHAL 服务器会向 AAOS 客户机虚拟机发送关闭信号。收到信号后,VHAL 客户端(即 AAOS 虚拟机)会进入车库模式,并开始发送检测信号,使主机虚拟机保持活动状态。
全球导航卫星系统 (GNSS)
在 trout
1.0 中,添加了对通过 virtio-console
进行 GNSS 虚拟化的支持。该实现支持从主机到客户机交换原始测量数据和位置修复。
数据交换格式是 GnssLogger 应用所使用的 CSV。在参考实现中,由于原生 GNSS 驱动程序不可用,因此提供了模拟数据,但无需任何客户机端更改即可实现原生驱动程序。trout
源代码中提供了示例模拟主机代理。
当前的实现要求 GNSS 初始化和辅助 GNSS (AGNSS) 由主机操作系统环境处理。
![GNSS 架构](https://source.android.google.cn/static/docs/devices/automotive/images/trout_gnss_01.png?authuser=9&hl=cs)
图形
当 AAOS 作为客户机虚拟机与其他汽车操作系统一起运行时,Android 可能无法直接访问 GPU 或显示控制器。在这种情况下,Android 客户机虚拟机以及 virtio-gpu
设备上的 Mesa 或 goldfish-opengl
和 virtio-gpu
驱动程序可用于访问 GPU。
在 Android 客户机虚拟机上,Mesa 或 goldfish-opengl
将 OpenGLES 命令分别编码为 Gallium 流或自动生成的 GLES 流。virtio-gpu
内核驱动程序可用来传输。在主机端,virglrenderer
(对于 Mesa)和 vulkan-cereal
(对于 goldfish-opengl
)会在现有 GPU 驱动程序之上重新执行已解码的命令流。AAOS 参考平台 trout
仅支持 OpenGL ES,预计会在未来的版本中支持 Vulkan。
![图形架构](https://source.android.google.cn/static/docs/devices/automotive/images/trout_graphics_02.png?authuser=9&hl=cs)
传感器
当 AAOS 作为客户机虚拟机与其他汽车操作系统一起运行时,Android 可能无法直接访问传感器。在这种情况下,Android 客户机虚拟机上的 Virtio-SCMI 驱动程序和主机虚拟机上的 VirtIO-SCMI 设备用于访问传感器。AAOS 虚拟化参考平台提供了一个与硬件无关的通用传感器 HAL,它可用于基于 ARM 的 SoC 以访问传感器。
传感器 HAL 与 Linux 内核 IIO 子系统中的 IIO SCMI 驱动程序进行通信,该驱动程序使用 ARM 系统控制和管理接口 (SCMI) 规范提供的 SCMI 传感器管理协议来发现和配置传感器、读取传感器数据,以及接收有关传感器值变化的通知。
IIO SCMI 驱动程序使用 VirtIO SCMI 驱动程序,后者使用 virtio-scmi
规范中指定的 VirtIO 传输协议来与主机虚拟机上的 VirtIO SCMI 设备交换 SCMI 消息。VirtIO SCMI 设备可以通过 SoC 专用传感器驱动程序直接访问传感器。
![传感器架构](https://source.android.google.cn/static/docs/devices/automotive/images/trout_sensors_03.png?authuser=9&hl=cs)
传感器 HAL 位置
传感器 HAL 的参考实现(使用 VirtIO SCMI)位于 device/google/trout/hal/sensors
。
传感器 HAL 配置
传感器 HAL 可能需要修改从主机虚拟机接收的传感器数据,以符合 Android 汽车传感器坐标系。传感器配置的架构可以在 device/google/trout/hal/sensors/2.0/config/sensor_hal_configuration.xsd
中找到。
OEM 可以在 sensor_hal_configuration.xml
中提供传感器配置(如方向和位置),还能复制 /odm/etc/sensors/
或 /vendor/etc/sensors/
下的文件。下面提供了一个传感器配置示例:
<sensorHalConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"> <modules> <module halName="android.hardware.sensors@2.0-Google-IIO-Subhal" halVersion="2.0"> <sensors> <sensor name="scmi.iio.accel" type="1"> <configuration> <!-- Attribute rotate denotes if HAL needs to modify the sensor data to comply with // the Android car sensor coordinate system --> <orientation rotate="true"> <!-- Attribute map denotes the indexes of data in sensor data received --> <!-- Attribute negate denotes if data needs to be negated --> <x map="0" negate="false"/> <y map="1" negate="true"/> <z map="2" negate="true"/> </orientation> <location> <!-- Attribute x, y, z denotes location of the sensor placement --> <x>10</x> <y>15</y> <z>20</z> </location> </configuration> </sensor> </sensors> </module> </modules> </sensorHalConfiguration>
车载 HAL
车载 HAL 实现由两个组件组成:
- 客户端 - 提供 Android 在虚拟化 AAOS 中使用的 API。
- 服务器 - 直接与车载总线等硬件(或模拟器)进行通信。
在虚拟化环境中,VHAL 服务器在主机虚拟机上运行。VHAL 客户端和服务器通过 GRPC-vsock
进行通信(如需了解详情,请查看 device/google/trout/hal/vehicle/2.0/proto/VehicleServer.proto
)。OEM 可以通过替换通信 API 来使用除 GRPC 之外的其他传输协议。有关示例,请查看 device/google/trout/hal/vehicle/2.0/GrpcVehicle{Client,Server}.cpp
。
其他子系统
VirtIO 已经为块存储、网络、控制台、输入、套接字和熵等组件提供了明确定义的接口。对于这些子系统,AAOS 按原样使用驱动程序,如 virtio-blk
、virtio-input
、virtio-console
和 virtio-net
。
在虚拟化 AAOS 参考平台中,系统会使用 mac80211_hwsim
支持 Wi-Fi 以启用 VirtWifi
无线网络,该网络随后使用 virtio-net
隧道将网络流量发送到主机虚拟机,主机虚拟机可以直接访问实际 Wi-Fi 网络。