作者:Luke Harvey, Marcio da Ros Gomes, Sebastian Goscik
2022年6月16日
汽车行业的嵌入式软件开发人员使用了传统的嵌入式开发方法,这种方法几十年来基本没有改变。编写软件的嵌入式目标系统本质上是资源受限的,内存、计算资源和输入/输出容量有限。此外,嵌入式开发系统通常价格昂贵,对于开发全新电子控制单元(ECU)和片上系统(SoC)架构的开发团队来说,这是一种稀缺商品。随着最近全球汽车行业芯片短缺,这种稀缺性变得更加明显。
这意味着软件开发人员避免直接在嵌入式平台上开发软件,而是依赖于在功能强大的开发机器或主机上开发软件。在主机上创建用于开发和测试的可执行软件的编译器和工具链不能直接用于在嵌入式目标上的部署。很多时候,目标嵌入式操作系统(OS)本身不能在主机上使用。开发人员依赖于主机上繁琐的操作系统仿真工具和交叉编译过程,交叉编译过程使用特殊编译器为目标系统创建可执行代码。一旦代码在开发系统上,就可以执行最终的集成和验证测试,但扩展限于物理硬件平台的数量。目前,嵌入式系统的典型开发、集成和验证工作流如下所示:
本博客将介绍一种新的汽车软件开发概念,帮助开发人员使用云创建、测试和调试本机编译的软件,大大简化了此工作流程。这一概念通常被称为环境对等,您可以在Arm和亚马逊网络服务(AWS)的白皮书(https://armkeil.blob.core.windows.net/developer/Files/pdf/white-paper/arm-aws-edge-environmental-parity-wp.pdf)以及Kevin Hoffman的《超越十二要素应用程序》(https://www.oreilly.com/library/view/beyond-the-twelve-factor/9781492042631/)一书中了解更多。
“环境对等的目的是让您的团队和整个组织相信应用程序将在任何地方都能工作。”- Kevin Hoffman
环境对等是实现云原生软件定义车辆目标的一个主要因素。
Arm、AWS和SOAFEE
Arm技术正在定义计算的未来。Arm的节能处理器设计和软件平台已在超过2250亿个芯片中实现了高级计算,我们的技术安全地为从传感器到智能手机和超级计算机的产品赋能。我们与1000多家技术合作伙伴一起,使人工智能能够在任何地方工作,在网络安全方面,我们正在为数字世界——从芯片到云——提供信任基础。Arm架构在现代车辆中最为广泛,从信息娱乐单元到车身控制,以及更多,包括非常精细的功能安全相关计算负载。
2021,Arm、AWS和其他创始成员宣布了可扩展的嵌入式边缘开放架构(SOAFEE)特别利益小组(https://soafee.io/),该小组将汽车制造商、半导体和云技术领导者聚集在一起,定义一种新的基于开放标准的架构,以实现软件定义的车辆堆栈的底层架构。它提供了一个参考实现,使云原生技术(如微服务、容器和编排系统)首次与汽车功能安全相结合,保持环境对等。
利用SOAFEE实现云到嵌入式边缘的ISA对等
AWS和Arm有着悠久的历史。这包括在AWS定制SOC中使用64位处理器,这些SOC用于AWS Graviton处理器,为云工作负载提供最佳性价比。通过在越来越多的实例类型上提供这些处理器选项,汽车开发人员可以使用同样的Arm知识产权(IP)和工具开发和运行云原生应用程序和工具链,这些工具也用于嵌入式汽车平台,如AWS合作伙伴ADLINK的AVA开发者平台。
通过在云和边缘中使用此IP,开发人员可以在指令集架构(ISA)级别实现第一级环境对等。然而,为了实现更高级别的对等,我们需要一个操作系统、抽象层和编排层,这些层都是自动级别的,SOAFEE正在努力支持这些层。下图显示了与这些方法相关的不同级别的环境对等和开发人员角色。
正如我们将在下一节中解释的那样,实现这样的对等级别将促进嵌入式软件开发和验证的全新工作流。
使用ISA对等促进操作系统级对等
作为演示本博文中解释的概念的参考操作系统,我们将使用Yocto项目创建一个自定义Linux发行版,这是一个开源协作项目,帮助开发人员创建基于Linux的自定义系统,而不考虑硬件。它被许多嵌入式项目使用,包括作为Linux基金会一部分的汽车级Linux计划以及SOAFEE参考实现。
为了实现操作系统级的对等,Arm和AWS合作基于Yocto项目为Graviton实例创建了一个亚马逊机器映像(AMI)。AMI是包含软件配置的模板,包括操作系统和应用软件。这可以用来启动一个AmazonEC2实例,它是在云中作为虚拟服务器运行的AMI的副本。开发的AMI还包括Arm的边缘工作负载抽象和编排层(EWAOL),这是SOAFEE体系结构的开源参考实现,有助于进一步实现应用程序、容器和操作系统环境对等。
eWal提供了一个基于标准的框架,使用容器部署和编排嵌入式应用程序。这种方法可以帮助开发人员开始在云中编写和测试代码,从而显著改进和扩展工作流。更具体地说,SOAFEE促进了:
. 整个嵌入式软件栈的云实现,从嵌入式操作系统开始,而不仅仅是开发中的软件单元;
. 从云到嵌入式边缘的无缝移植不再需要交叉编译或仿真(以及编译错误或性能下降等相关问题)。
访问Arm GitLab(https://git.gitlab.arm.com/ewaol/meta-ewaol)以获取有关EWAOL的更多信息。
既然我们已经引入了操作系统级和ISA级对等的概念,我们现在可以修改嵌入式开发人员的工作流程,以减少许多现在不再需要的步骤,如下图所示:
在本博客的其余部分,我们将提供一个教程,详细介绍如何使用Yocto项目为基于AWS Graviton的实例创建自己的自定义基于Linux的AMI。本教程的目的不仅仅是教如何在AWS上部署已经创建的AMI,而是为开发人员提供一种方法,让他们将自己用于嵌入式系统的Linux镜像带到云中。
如何使用Yocto项目为AWS Graviton处理器创建自定义Linux AMI
本指南将描述如何创建可用于启动Amazon EC2实例的自定义Linux AMI。您应该已经有权访问具有创建所需资源的适当权限的AWS帐户。如果没有,请创建/激活一个帐户(https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)。
在开始之前,请查看GitHub上的详细说明。此存储库包含有关如何创建自定义Linux AMI(包括eWal)的最新信息和说明。
使用Yocto创建自定义AMI有五个主要步骤。我们将一步一步地介绍它们,并构建如下所示的体系结构:
根据本博客中的说明部署的系统架构图。
1.配置AWS资源
首先,我们需要使用AWS CloudFormation进行一些AWS帐户设置和配置,通过将基础设施视为代码,您可以对AWS和第三方资源进行建模、配置和管理。AWS CloudFormation在这里用于使用配置文件配置AWS资源,以节省您的时间。
- 将此AWS CloudFormation从GitHub repo下载到您的本地计算机。
2.转到AWS CloudFormation仪表板。
3.点击“创建堆栈”
4.选择“上载模板文件”,选择在步骤1中下载的模板文件,然后单击“下一步”继续。
5.输入“yocto build”作为堆栈名称。将creates3bucket切换为“yes”,并输入任何唯一的bucket名称。选择“下一步”继续。
6.将此页面保留为默认页面,然后选择“下一步”
7.最后,检查设置,确认身份和访问管理(资源创建),并选择“创建堆栈”
8.这应该需要几分钟来创建。当您在堆栈状态中看到“CREATE_COMPLETE”时,您可以进入下一步。
2.创建一个Yocto构建Amazon EC2实例
现在,我们将创建一个AmazonEC2实例并将其保护到该实例中,该实例将用作我们的开发环境,用于使用Yocto项目编译和构建我们的自定义Linux镜像。
1.转到Amazon EC2仪表板。
2.单击侧栏菜单中的“实例”。
3.单击橙色的“启动实例”按钮。
4.选择带有“64位(Arm)”的“Ubuntu服务器20.04 LTS”
5.选择“c6g.4xlarge”实例类型。c6g。选择4xlarge实例类型是因为它是一个CPU优化的实例,将用于编译,但也可以根据您的需求使用其他实例类型。
6.创建并下载新的密钥对。稍后,您将使用此密钥加密SSH会话。
7.在“创建安全组”下,选择“允许SSH通信”。在下拉菜单中,选择“我的IP”
8.在“配置存储”下,将根卷调整为100GiB的gp2(通用SSD)。
9.在“高级详细信息”下,我们需要选择在cloudformation步骤中创建的“IAM实例配置文件”,为我们的实例提供以下步骤所需的AWS权限。它应该以“yocto-build-VMBuilderEC2Role-”开头,然后是随机字符。
10.将所有剩余设置保留为默认设置,然后选择“启动实例”。
11.最后,您可以选择“查看实例”按钮,等待实例进入“运行状态”
3.使用Yocto项目构建自定义Linux映像
接下来,您应该使用SSH连接到步骤2中创建的构建实例中。您可以使用任何希望连接到此实例的SSH客户端。
1.通过选择列表中的实例并单击“连接”按钮来查找SSH命令。
1.使用SSH客户端,使用所示命令连接到服务器。例如:ssh-I“keypair.pem”ubuntu@ec2-[ip-address].compute-1.amazonaws.com。
2.按照GitHub存储库中的说明安装构建依赖项。https://github.com/aws4embedd...
3.从同一存储库中完成“构建eWal”部分。该存储库配置了一个基本的Yocto Project Linux发行版,其中包括用于支持我们的AMI的cloud init、meta eWal、meta aws和SSH。
注意:花时间检查YAML配置文件,并针对您的项目进行必要的修改。
4.在完成上述“kas构建”步骤后,完成新Linux发行版的构建大约需要50分钟。
5.至此,我们可以选择深入研究本项目中使用的YAML文件和内核配置。
(可选Deep Dive)kas、YAML和内核配置说明
这个YAML文件(https://github.com/aws4embeddedlinux/meta-aws-ewaol/blob/main/kas/machines/ewaol-graviton2-ami.yaml)向kas描述了Yocto项目应该如何构建我们的Linux镜像。
Header
header:
aversion: 10
includes:
– repo: meta-ewaol
file: meta-ewaol-config/kas/ewaol-base.yml
– repo: meta-ewaol
file: meta-ewaol-config/kas/arm-machines.yml
本节将告诉kas我们使用的文件模式的版本,以及其他一些要从eWal repo中包含的YAML文件(稍后解释)。其中包括加载在eWal基本配置中的文件和一些标准Arm机器定义。
Repositories
repos:
meta-ewaol:
url: “https://git.gitlab.arm.com/ewaol/meta-ewaol.git”
path: layers/meta-ewaol
refspec: v0.2.4
meta-aws:
url: https://github.com/aws/meta-aws.git
path: layers/meta-aws
refspec: hardknott
meta-virtualization:
refspec: hardknott
meta-ewaol-ext:
path: meta-ewaol-ext
refspec: hardknott
meta-openembedded:
refspec: hardknott
poky:
refspec: hardknott
本节告诉kas我们要使用哪些Yocto层,在哪里下载它们,使用哪些版本,以及在哪里存储它们。在本例中,我们使用了meta-ewaol(参考SOAFEE实现层)和aws元,后者提供了aws边缘软件功能的配方。在标题中包含了“eWal base.yml”,它包含了更多的存储库。该文件还加载“poky”和“meta openembedded”,这是标准的Yocto层。此外, meta-ewaol-ext
层通过使用补丁和bbappend文件向cloud init和OpenSSH recipes
添加定制。
Machine
machine: generic-arm64
这行命令告诉Yocto我们要将图像定位在哪台机器上。在本例中,使用了“generic-arm64”。它创建了一个映像,可以在大多数支持通用启动机制的Arm设备上启动(本例中为UEFI。您将在稍后的AMI映像中看到此集合)。
Custom config
Custom config
local_conf_header:
meta-custom: |
FILESEXTRAPATHS_prepend_pn-linux-yocto = “${TOPDIR}/../kernelconfig/:”
SRC_URI_append_pn-linux-yocto = ” file://gravitonKernelConfigs.cfg “
INHERIT += “extrausers”
# Hardening: Locking the root password. Creating the ewaol without password for ssh key-based login only
EXTRA_USERS_PARAMS = “usermod -L root; useradd -p ‘*’ ewaol”
EXTRA_IMAGE_FEATURES_append = “ssh-server-openssh”
# Forcing removal of debug-tweakes as ewaol includes it in all targets by default and that leads to reversing some sshd_config hardening done in our bbappend when do_rootfs runs
EXTRA_IMAGE_FEATURES_remove = “debug-tweaks”
IMAGE_INSTALL_append = ” rng-tools awscli cloud-init cloud-init-systemd e2fsprogs e2fsprogs-resize2fs e2fsprogs-tune2fs e2fsprogs-e2fsck e2fsprogs-mke2fs parted sudo sudo-sudo openssh-sftp-server”
IMAGE_FSTYPES += ” wic wic.vhdx”
本节配置特定于此示例的自定义配置设置:
. 添加cloud init,用于在启动时将AMI配置到特定的Amazon EC2实例
. 添加一些额外的内核配置
.添加了一些额外功能,如SSH服务器和AWS命令行界面(AWS CLI),这是一个管理AWS服务的统一工具
Target
Target:
– ewaol-image-docker
这告诉Yocto要构建哪些目标图像。在这种情况下,我们只希望它构建docker映像(而不是podman映像)
Kernel configuration fragment
要将Yocto配置为在AWS Graviton2处理器上工作,必须激活一些额外的内核配置。它们包含在gravitonKernelConfigs.cfg中。
. 要使NVME存储工作,需要CONFIG_BLK_DEV_NVME。
. ENA_ ETHERNET是网络工作所必需的。
. 串行端口需要CONFIG_SERIAL_8250_PCI。
4.从图像文件创建AMI
1.既然已经构建了映像,我们需要创建AMI本身。
2.按照GitHub存储库中的说明运行创建ami。sh脚本。
3.这将在您的AWS帐户中自动生成新的AMI。
4.最后,您不再需要这个构建Amazon EC2实例,因此可以关闭它:
$ sudo poweroff
5.使用新的AMI启动EC2实例
使用新创建的AMI启动实例就像本指南前面设置EC2实例一样。
1.转到Amazon EC2仪表板。
2.通过单击左侧菜单中的AMI打开AMI窗格。
3.选择先前创建的AMI。
4.单击“从图像启动实例”按钮。从本指南的第一部分开始,应熟悉以下屏幕。
5.在先前创建的下拉菜单中选择相同的密钥对。
6.在“创建安全组”下,选择“允许SSH通信”,并在下拉列表中选择“我的IP”
7.您可以保留其他实例设置的默认设置,然后单击“启动实例”
8.现在,我们将使用SSH实用程序连接到我们的自定义Linux实例。通过选择列表中的实例并单击“连接”按钮来查找SSH命令。但是,您必须自己将用户名修改为“ewaol”,如下所示:
例如:ssh -I “keypair.pem” ewaol@ec2-[ip-address].compute-1.amazonaws.com
9.让我们用以下命令确认该实例是我们使用Yocto项目构建的:
$ uname –r
10.107-yocto-standard
最后,当您不再需要堆栈和本教程中创建的所有资源时,请务必删除它们,以避免将来产生成本。
恭喜!现在,您已经能够使用Yocto项目构建和启动自己的自定义Linux映像,该项目现在可以在云中用于开发以及验证和验证。
如果自定义映像遇到任何问题,可以访问实例串行控制台进行调试。这在默认情况下不被激活。详情可在此处找到:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-serial-console.html
汽车的未来是软件定义的
在本博客中,我们介绍了环境平等的高级概念以及Arm、AWS和其他合作伙伴正在努力实现的目标:构建软件定义的系统并加速汽车软件开发。我们还提供了一个教程,介绍了如何使用基于Arm的AWS Graviton处理器为自己的开发工作流使用Yocto项目创建自定义AMI。
如果您想更深入地了解这个概念,请访问这个实践研讨会,详细介绍如何使用本博客中创建的AMI为汽车开发创建自动化软件开发管道,并演示环境对等。
有关嵌入式边缘可扩展开放体系结构(SOAFEE)项目的更多信息,请访问SOAFEE.io(http://soafee.io/)。