亚马逊AWS官方博客

借助 AWS Graviton 实现 Android Automotive 虚拟化,打造高效虚拟化车载系统

摘要

随着智能网联汽车时代的到来,软件定义汽车(SDV)和车载信息娱乐系统(IVI)等技术正在重塑整个汽车行业。开发嵌入式汽车系统,尤其是 IVI 应用程序,具有极高的复杂性。Android Automotive OS(AAOS)凭借其一致的 API 和操作系统,成为开发和交付 IVI 应用程序的主流平台,为跨车型平台开发奠定了基础。本文聚焦在基于 AWS Graviton 芯片的实例运行 Android Automotive 虚拟化系统,打造高效的虚拟化车载系统。

AAOS 是基于 Android 的开放平台,它提供了跨车辆平台的一致性开发接口。借助 AAOS 开发者可以使用统一的 API,减少学习成本,并加速应用程序开发。这对于 OEM 和供应商来说,能够通过 UI 和功能定制来打造独特的品牌体验,而无需从底层操作系统重新构建。

如果没有 AAOS 这一统一平台,OEM 和供应商将不得不自行开发操作系统,或仅基于底层 API 构建,这无疑将增加开发难度和成本。基于 AAOS 构建的定制化 UI 不仅能缩短开发时间,还可利用已完成的验证工作,从而提高效率。然而,使用 AAOS 进行系统测试和验证往往需要为每个开发人员购买并管理特定的硬件开发系统,而在软件开发初期,这些硬件可能存在暂未就绪的情况。

为解决硬件依赖问题,开发人员可利用虚拟设备代替真实硬件。这种虚拟设备不仅提供了可扩展的机制,供多个开发和验证团队使用,还能与持续集成和交付(CI/CD)流水线无缝集成。AAOS 推出的虚拟设备项目“Trout”允许开发人员根据目标 IVI 系统进行配置和运行,从而加速开发进程。Trout 是一个虚拟化环境,允许开发人员在不依赖真实硬件的情况下,进行系统的开发、测试和验证。将 Trout 等虚拟设备部署在 AWS 云服务器上,虚拟设备通过 VIRTIO 虚拟化标准与底层硬件分离,增强了灵活性,使开发人员能够轻松切换硬件平台,提高开发效率。通过 Trout 虚拟设备,开发者可以在云端环境中运行和配置虚拟 IVI 系统,支持并行开发和验证多个软件版本,这样就打破了对硬件设备的依赖。这种云端解决方案还支持无缝集成 CI/CD 管道,从而进一步简化开发周期,确保高效、可靠的软件交付流程,从而满足质量保证工程师的测试和验证需求。

这种方式为开发带来了多方面的好处:

  • 并行开发:硬件开发和软件开发可以同步进行,开发者不再需要等待硬件到位后才能开始编码和测试。
  • 可扩展性:在云环境中,虚拟设备可以快速扩展,满足多个开发和质量保证团队的需求。开发者可以轻松创建多个虚拟设备实例,用于测试不同的软件版本和用例。
  • CI/CD 集成:虚拟设备还可以与持续集成和交付(CI/CD)流水线集成,自动化测试流程,从而加速开发周期并提高质量。

本博客旨在展示如何在基于 AWS Graviton  EC2实例上构建并运行 Trout 虚拟设备,以及通过 WebRTC 连接到该实例,从而加速开发、测试、CI/CD 管道集成及验证工作。AWS Graviton 处理器基于 ARM 指令集架构,这一架构广泛应用于车载信息娱乐系统(IVI)及其他电子控制单元(ECU),因此开发人员能够在云端模拟与车辆硬件一致的开发环境,从而缩短硬件依赖并加快开发流程。

在 AWS Graviton 上运行 Android Automotive OS (AAOS) 能充分体现其多项优势。首先,Graviton2 和 Graviton3 处理器提供高性能和多核架构,能够高效处理 AAOS 的复杂任务,如实时导航、语音识别和多媒体播放,同时具有更高的性价比,降低运营成本。其次,基于 ARM 架构的 Graviton 处理器具备高能效和低功耗,适合长时间运行和大规模部署,减少电力消耗和碳排放,助力实现更环保的计算环境。此外,Graviton 处理器与大多数现代操作系统和应用程序兼容,并得到广泛的开源社区支持,使得在 Graviton 实例上运行和优化 AAOS 变得更加容易和高效。安全性方面,Graviton 处理器内置多种硬件级安全特性,并与 AWS 的各种安全服务无缝集成,确保系统和数据的安全。最后,Graviton 实例适合大规模云计算部署,能够灵活扩展以满足不断增长的计算需求,并结合 AWS 的弹性伸缩服务,动态调整计算资源,确保 AAOS 系统在各种使用场景下都能高效运行。通过这些优势,AWS Graviton 为 AAOS 提供了一个高性能、低成本、高能效和安全可靠的运行环境,还减少了开发者在早期开发阶段对物理开发硬件的依赖。

为了成功完成此实验步骤,需要具备以下基本知识和工具:

  • 熟悉 AWS 控制台和 AWS 命令行界面(CLI) 的基本操作;
  • 掌握典型的软件构建流程及 Linux 和 Android 的基本命令;
  • 对 Android 应用开发和 Android Studio 的基本使用有所了解;
  • 拥有一个 AWS 账户,并具备创建 EC2 实例和 S3 存储桶的权限,您还需要配置 AWS CLI 并具备账户凭证。

本实验的三大步骤:

  1. 构建:启动 EC2 实例,用于构建 AAOS(Android Automotive OS)、Trout 虚拟设备,以及运行虚拟设备所需的 Cuttlefish 主机包。
  2. 创建虚拟设备实例:在基于 AWS Graviton 的 EC2 .metal 实例上启动、配置并部署虚拟设备。使用 .metal 实例可以实现对硬件近乎原生的访问,尤其适用于性能要求较高的任务。
  3. 连接与调试:通过 WebRTC 连接到虚拟设备,实现图形化界面可视化。使用 Android Debug Bridge(ADB) 工具进行调试,与 Android Studio 集成以进行应用开发和控制操作。这使开发者能够在无需物理硬件的情况下完成大部分开发和测试工作。

方案概述

在这篇技术文章中使用一个独立的构建实例来创建虚拟设备和将在主机实例上部署的软件包(在步骤 2 中需要这些软件包来在容器中启动虚拟设备软件)。由于构建当前(Android 12)版本的主机软件包需要 x86_64 架构,因此使用了 x86_64 架构的构建实例。由于 Android 开源项目(AOSP)的构建过程可能需要很长时间并占用大量(超过 250GB)的磁盘空间,因此采用了一台大型多核云机器(m6a.12xlarge)来将构建时间缩短至大约一小时。

该架构图展示了在 AWS 云环境中如何构建和运行 Trout 虚拟设备,并通过 WebRTC 和 ADB 进行连接和调试的流程。

  • EC2 构建实例

用于构建虚拟设备,通过 SSH 与开发者的桌面进行连接。下载 AOSP 源码,配置构建环境,执行构建任务,并将构建的映像文件上传到 S3 存储桶。

  • S3 存储桶

用于存储和传输构建的映像文件,从 EC2 构建实例上传映像文件,并将映像文件传输到 EC2 Graviton 实例。作为中介存储,确保构建的映像文件可以在不同实例之间传输。

  • EC2 Graviton 实例

用于运行虚拟设备,通过 WebRTC 与开发者的桌面连接,并通过 S3 存储桶接收映像文件。部署和运行 Trout 虚拟设备,提供开发和测试环境。

  • 开发者桌面

用于开发、测试和调试环境。通过 SSH 连接到 EC2 构建实例,通过 WebRTC 连接到 EC2 Graviton 实例,并通过 ADB over IP 进行调试。运行 SSH 客户端、ADB 应用程序和 Android Studio,浏览虚拟设备的 WebRTC 界面,进行调试和控制活动。

实验目标

能够在主机实例上成功运行 Trout 虚拟设备。主机实例采用 Cuttlefish 主机包和 CrosVM 虚拟机管理器,它们是 AOSP 软件系统的一部分,运行虚拟设备所必需的环境。Cuttlefish 主机包内置了一个 WebRTC 服务器包,便于远程查看虚拟设备。

Cuttlefish 是由 Google 开发的开源 Android 虚拟设备(AVD)。其目的是在基于 Linux 的系统上运行 Android 作为虚拟机,用于测试和开发。它利用了 QEMU(一种广泛使用的开源模拟器)和 KVM(硬件辅助虚拟化技术),以实现高效的 Android 设备虚拟化和仿真。这使得开发者、研究人员和测试人员在没有物理设备的情况下也能使用 AOSP 进行工作。

CrosVM 是一个轻量级的虚拟机监视器(Hypervisor),主要用于在 Chrome OS 和其他基于 Linux 的系统上运行虚拟机。它由 Google 开发,最初是为了在 Chrome OS 上支持 Android 应用和 Linux 应用而设计的。CrosVM 的设计目标是提供高性能和安全的虚拟化环境。

下图展示了本教程中将在主机实例上构建的各个组件的安排。由于 CrosVM 虚拟机管理器依赖于基于 Linux 内核的虚拟机(KVM),虚拟设备主机需要使用裸金属(‘.metal’)实例类型。这种架构被称为嵌套虚拟化,AWS 在其他非metal类型的 EC2 实例上不支持该类型的虚拟化。

逻辑图

整个架构展示了如何在 AWS EC2 实例上使用 Cuttlefish 组件运行和模拟 Android Automotive OS(AAOS)系统,包括从底层硬件到上层应用的各个部分。通过这种架构,可以实现高效的虚拟化和远程开发、调试和测试。

实验步骤

1. 启动一个 x86 架构的实例,用于构建适用于 ARM64 架构的 Android Automotive OS(AAOS)Trout 版本

这个步骤的目的是确保有一个适当的构建环境来生成目标二进制文件和相关资源。

登录 AWS console,导航到 EC2 服务,运行并启动实例,配置如下:

名称:aaos-builder
AMI: Ubuntu Server 22.04 LTS(HVM)
实例类型:m6a.12xlarge
密钥:选择相应的keypair
网络:选择VPC、子网、安全组(允许22端口流量)
存储:EBS GP3 500GB

2. 通过 ssh 或 session manager 连接到该实例 aaos-builder

ssh -i "xxx.pem" ubuntu@ec2-107-21-152-xx.compute-1.amazonaws.com

3. 在构建实例上按照 AOSP 文档描述设置构建工具

在使用 AOSP 之前,您必须安装 OpenJDK、Make、Python 3 和 Repo。Android 的 AOSP 主分支附带了 OpenJDK、Make 和 Python 3 的预构建版本,因此无需执行其他安装步骤。以下部分介绍了如何安装 Repo。

在 SSH 会话中,输入以下命令:

sudo apt-get update
sudo apt-get install repo
git config --global user.name <姓名> 
git config --global user.email <邮箱> 
repo version

输出应指示 2.4 或更高版本,例如:

repo launcher version 2.45

4. 安装必需的软件包

要构建 Android 11 或更高版本运行以下命令安装所需的软件包:

sudo apt-get install git-core gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig

注意:此命令适用于 Ubuntu 18.04 或更高版本。对于早期版本的 Ubuntu 的软件包安装,请参阅 “Android 开发环境设置(AOSP 2.3 – 8)”。

5. 将 AAOS 的源代码同步到您的版本控制库中

浏览 source-code-tags-and-builds 源代码,选择要使用的版本标记。在本文中,我们使用 android-14.0.0_r74,因为它是撰写本文时的最新稳定版本。Trout 虚拟化是在 Android 12 版本中引入的,所以需要使用 12 版本之后的更新,输入这些命令将源代码拉取到您的构建实例:

进入主目录

cd ~ 

创建并进入 aosp14目录

mkdir aosp14 && cd aosp14

初始化 repo 并指定 android-14.0.0_r74 版本

repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r74

同步代码

repo sync

如果同步过程中出现问题,重复执行 repo sync 直到同步成功。成功的标志是终端显示以下信息:

repo sync has finished successfully.

通过以上步骤,您可以成功初始化和同步 Android 14 的代码库。如果在同步过程中遇到网络问题或者其他错误,可以多次执行 repo sync 直到完成。

6. 修改主机包的源代码以包含 STUN 服务器的 IP 地址

这个步骤的主要目的是为了确保虚拟设备能够顺利使用 WebRTC 功能。WebRTC 依赖于 STUN(Session Traversal Utilities for NAT)服务器来帮助网络设备发现自己的公共 IP 地址,并穿过NAT设备。通过显式指定 STUN 服务器的 IP 地址,可以避免 DNS 解析问题,从而确保 WebRTC 功能的正常运行。

定位文件,在文件中找到 #LaunchWebRTC()method

device/google/cuttlefish/host/commands/run_cvd/launch/streamer.cpp

在以下代码行之后,添加 STUN 服务器 IP

sig_server.AddParameter("-http_server_port=", config.sig_server_port());

添加以下代码行

sig_server.AddParameter("-stun_server=", "142.250.9.127");

该 IP 地址 142.250.9.127 是 stun.l.google.com 的一个定位地址,它在 device/google/cuttlefish/host/frontend/webrtc_operator/server.cpp 文件中被定义为 STUN 服务器。通过添加这一行代码,您可以避免 DNS 解析问题并为虚拟设备启用 WebRTC。

7. 浏览目标列表并选择一个目标进行构建,使用 lunch 命令不带参数可以列出可用的目标

在此使用 aosp_cf_arm64_auto-userdebug 作为构建目标。分别输入以下命令以开始构建:

source build/envsetup.sh
lunch cd ..
m

在本文档所用的实例 m6a.12xlarges 上面,整个构建过程大概需要 1 个小时。

当看到以下消息时,表示构建成功:

#### build completed successfully ####

8. 生成分发文件

make dist

在推荐的实例类型(m6a.12xlarge)上,构建大约需要 10 分钟。与之前一样,验证成功的构建消息:

#### build completed successfully (08:11 (mm:ss)) ####

构建完毕后可以关闭该构建实例,以节约成本。

9. 将生成的构建产物复制到 Amazon S3 存储中

这一步确保您的构建产物可以被后续步骤访问和使用。创建 S3 存储桶,并将主机包 cvd-host_package、设备镜像aosp_cf_arm64_auto-img-eng 和预构建的引导加载程序 bootloader 拷贝到 S3:

aws s3 cp out/dist/cvd-host_package.tar.gz s3://aaos-test/
aws s3 cp out/dist/aosp_cf_arm64_auto-img-eng.root.zip s3://aaos-test/
aws s3 cp ./device/google/cuttlefish_prebuilts/bootloader/crosvm_aarch64/u-boot.bin s3://aaos-test/

10. 需要启动一个基于 AWS Graviton 处理器的实例,通过这个实例托管 AAOS 目标

Graviton 处理器基于 ARM 架构,因此适合运行 ARM64 架构的 AAOS。

名称:aaos
AMI: Ubuntu Server 22.04 LTS(HVM)
实例类型:m7g.metal
密钥:选择相应的keypair
网络:选择VPC、子网、安全组
存储:EBS GP3 500GB

安全组设置:

Protocol Port Range Source
TCP 22 your IP/32 SSH — added when instance was launched
TCP 6444 your IP/32 VNC — if using
TCP 8443 your IP/32 main entry page for virtual device
TCP 6520 your IP/32 ADB for Android Studio or shell
TCP 15550 – 15559 your IP/32 WebRTC
UDP 15550 – 15559 your IP/32 WebRTC

11. 使用以下命令通过 SSH 连接到主机实例

ssh -i <pemfile> ubuntu@<host ip>

12. 检查虚拟化支持,如果返回值大于 0,那么进行下一步

grep -c -w "vmx\|svm" /proc/cpuinfo

13. 目标环境需要一些设置以便主机包运行

这些包作为 Debian 包从 Google 仓库提供。在 SSH 会话中输入以下命令:

sudo apt update
sudo apt install -y git devscripts config-package-dev debhelper-compat golang

安装 Bazel,用于自动处理项目中的依赖关系,确保所有依赖项科研正确的下载、配置和编译。

sudo apt update && sudo apt install bazel

在主目录下执行以下命令:

cd ~
git clone https://github.com/google/android-cuttlefish
cd android-cuttlefish

编译并安装 Cuttlefish 包:

for dir in base frontend; do
    pushd $dir
    dpkg-buildpackage -uc -us
    popd
done

sudo apt install ./cuttlefish-base_*.deb ./cuttlefish-user_*.deb

将当前用户添加到所需的用户组,并重启系统:

sudo usermod -aG kvm,cvdnetwork,render $USER
sudo reboot

在 .metal 实例上重启可能需要 10 分钟或更长时间。此外,注意在此过程中公共 IP 可能会更改,因此您可能需要在重新连接之前重新获取该 IP。实例重新运行后,通过 SSH 重新连接到实例并继续操作。

14. 将构建的产物从 S3 拷贝到以上 Graviton 实例

创建工作目录并进入目录:

mkdir -p ~/workspace/cf && cd $_

下载并解压主机包:

# 主机包
aws s3 cp s3://$s3_bucket_name/cvd-host_package.tar.gz ./
tar xvf cvd-host_package.tar.gz 

下载并解压设备镜像:

# 设备镜像
aws s3 cp s3://$s3_bucket_name/aosp_cf_arm64_auto-img-eng.ubuntu.zip ./
unzip aosp_cf_x86_auto-img-eng.ubuntu.zip

下载引导加载程序:

# 引导加载程序
aws s3 cp s3://$s3_bucket_name/u-boot.bin ./bootloader

验证并创建空的 misc.img 文件:

ls -l misc.img || touch misc.img

注:创建空的 misc.img 文件是为了确保在启动和运行虚拟设备时,系统能够找到并使用该文件,从而避免潜在的启动错误或操作失败。具体来说 misc.img 文件在 Android 和其他基于 Linux 的系统中通常用于存储一些临时数据或元数据,这些数据在设备启动、恢复或其他操作过程中可能会用到。

15. 安装 u-boot 工具

Cuttlefish 构建的 android-12.1.0_r11 版本的 cvd-host_package 包含了 x86_64 平台预构建的 u-boot 工具二进制文件。要为 arm64 安装包括 mkenvimage 在内的 u-boot 工具,在 ssh 会话中输入以下命令(每次扩展主机包时都需要执行这些命令):

sudo apt -y install u-boot-tools
rm ./bin/mkenvimage
ln -s $(which mkenvimage) ./bin/mkenvimage

16. 启动 AAOS 虚拟设备

cd ~/workspace/cf
HOME=$PWD ./bin/launch_cvd -start_webrtc=true 

如果输出如下,代表 AAOS 虚拟设备启动成功:

VIRTUAL_DEVICE_DISPLAY_POWER_MODE_CHANGED
VIRTUAL_DEVICE_BOOT_STARTED
VIRTUAL_DEVICE_BOOT_COMPLETED
Virtual device booted successfully

如果要停止该 AAOS 虚拟设备,执行以下命令:

HOME=$PWD ./bin/stop_cvd

17. 通过浏览器和 WebRTC 协议查看 AAOS 虚拟设备并进行交互、测试和调试

借助 WebRTC 流式传输功能,用户可通过浏览器远程控制 Cuttlefish 虚拟设备,而无需在客户端计算机上安装任何其他软件。WebRTC 流式传输功能的其他优势包括:

  • 编码效率高于 VNC
  • 浏览器内 ADB
  • 可扩展协议(摄像头数据流、麦克风、传感器数据都可以通过 WebRTC 实现)

在 Chrome 浏览器中导航到 https://<host ip>:8443,其中 <host ip> 是 Graviton 的 public IP 地址。会看到列出设备的网页以及一个 “Connect” 按钮并点击。

稍等片刻则可以看到如下图所示的虚拟设备加载界面。

现在已经获得在 AWS Graviton 实例上运行的云主机,该主机运行与你的嵌入式开发套件是完全相同的设备镜像,能够在云中直接测试和验证设备及其上的任何应用程序。您可以在 Android Studio 中通过 Android Debug Bridge(ADB)进行远程应用开发、调试和测试等工作。

18. 同样可以通过以下命令启动 VNC server,通过 VNC viewer IP:6444 进行连接:

root@ip-192-168-11-201:~/workspace/cf# HOME=$PWD ./bin/launch_cvd -start_vnc_server

19. 使用 ADB 将 Android Studio 连接到 AWS 上的 AAOS 设备,定为到 ADB 安装位置:C:\Users\Administrator\AppData\Local\Android\Sdk\platform-tools

20. 建立 ADB 连接

C:\Users\Administrator\AppData\Local\Android\Sdk\platform-tools>adb.exe connect 3.86.116.80:6520

Output:

connected to 3.86.116.80:6520

21. 一旦你验证了与 AAOS 设备的 ADP 端口的连接,如前图所示,你的远程设备也应该出现在 Android Studio 的设备管理器的 “物理设备” 标签下,它将被列为 “Cuttlefish arm64 auto”,并且有一个绿色指示器表示连接成功,如下图所示

22. 双击“Cuttlefish arm64 auto”设备,同样可以获得虚拟设备的交互

23. 现在可以开始开发一个车载 Android 应用程序,如下图所示

为了简化,我们将以 Android “apk” 应用程序格式部署一个名为“AWS”的应用程序,打开后可以显示 “Hello 亚马逊云科技” 的应用程序,更多详细信息可以在 Android Studio 附带的文档中找到。示例应用代码可以参考:GitHub 保持以上步骤对于虚拟设备到连接状态,在调试并编译完代码后,可以通过右上角绿色“Run”按钮,将应用部署到虚拟设备中。

24. 部署成功后,可以在虚拟设备中找到该示例应用

25. 点击打开该应用,结果如下

总结

通过这种云端虚拟化的方式,开发团队可以轻松并行处理多个项目实例,有效加速软件开发的迭代周期,减少开发瓶颈,并为复杂的汽车软件系统提供了灵活、可扩展的验证环境,同时可以减少由于指令集架构变化而导致的迁移问题,并且无需交叉编译。这类现代化的开发工具不仅推动了汽车行业的软件创新,还为开发人员提供了灵活的云端开发环境,大大减少了开发复杂性和硬件依赖。

参考链接

  1. https://source.android.com/docs/automotive
  2. https://aws.amazon.com/blogs/industries/deploy-android-automotive-on-aws-graviton-using-aws-cloudformation  

本篇作者

王维超

亚马逊云科技解决方案架构师,负责基于 AWS 的云计算方案的架构设计,同时致力于 AWS 云服务在汽车行业的应用和推广。

Scott Nelson

亚马逊云科技专业服务(ProServe)的高级行业专家顾问。