亚马逊AWS官方博客

使用基于 Arm 的 Graviton 实例、Yocto Project 和 SOAFEE 为边缘和云构建汽车嵌入式 Linux 映像

嵌入式软件开发人员在汽车行业一直沿用传统的开发方法,主要原因是嵌入式目标系统资源有限,包括有限的内存、计算能力和输入/输出能力。另外,用于开发全新电子控制单元(ECU)和片上系统(SoC)架构的嵌入式开发系统价格昂贵,是开发团队的稀缺资源。

因此,软件开发人员通常避免直接在嵌入式平台上开发软件,而是依赖功能更强大的开发机或主机进行软件开发。用于在主机上创建可执行软件的编译器和工具链无法直接用于嵌入式目标机的部署。很多时候,目标嵌入式操作系统本身也无法在主机上运行。开发人员需要依赖主机上的操作系统模拟工具和交叉编译器(使用特殊编译器为目标系统创建可执行代码)。

一旦代码安装到开发系统上,就可以进行最后的集成和验证测试,但测试的扩展受限于物理硬件平台的数量。目前,嵌入式系统的典型开发、集成和验证工作流程如下:

  1. 在主机上使用模拟器和交叉编译器开发和测试软件
  2. 将软件部署到嵌入式目标系统进行集成测试
  3. 在有限的嵌入式硬件平台上进行验证测试

这种传统方法的主要挑战是开发效率低下、测试覆盖面有限,且需要昂贵的嵌入式硬件资源。

本博客将介绍一种云边结合的汽车软件开发概念,它可以帮助开发人员使用云创建、测试和调试本地编译的软件,从而大大简化工作流程。这一概念通常被称为对等环境,您可以从 Arm 和亚马逊云科技白皮书 中了解更多信息。环境对等是实现云原生软件定义车辆目标的一个重要因素。

Arm、亚马逊云科技和 SOAFEE

Arm 技术正在定义计算的未来。Arm 的高能效处理器设计和软件平台已在超过 2250 亿个芯片中实现了先进计算, Arm 技术在为从传感器到智能手机和超级计算机的各种产品提供安全支持。在网络安全领域,Arm正在为数字世界(从芯片到云)的信任奠定基础。Arm 架构在现代汽车中的应用最为广泛,从信息娱乐单元到车身控制,甚至包括非常精细的功能安全计算的工作负载。 2021 年,Arm、亚马逊云科技和其他创始成员宣布成立嵌入式边缘可扩展开放架构(SOAFEE) 小组,该小组将汽车制造商、半导体和云技术领导者聚集在一起,共同定义基于开放标准的新架构,以实现软件定义汽车堆栈的最底层。它提供了一个参考实施方案,使微服务、容器和编排系统等云原生技术首次与汽车功能安全相结合,并保持了环境对等性。

利用 SOAFEE 实现从云到嵌入式边缘的 ISA 平等性

亚马逊云科技与 Arm 的合作关系源远流长。例如在亚马逊云科技定制 SoC 内使用 64 位 arm 处理器,这些处理器用于 Amazon Graviton 处理器,可为云工作负载提供最佳性价比。通过在越来越多的实例类型上提供这些处理器,汽车开发人员可以使用与嵌入式汽车平台相同的 Arm 知识产权(IP)和工具来开发和运行云原生应用程序和工具链。通过在云和边缘使用这一 IP,开发人员可以在指令集架构(ISA)层面实现第一级的环境对等。然而,要实现更高水平的平价,我们将需要一个汽车级的操作系统、抽象层和协调层实现对等,SOAFEE 正在努力支持这一点。下图显示了不同的对等环境以及与这些方法相关的开发人员角色及开发任务的关系。

正如我们将在接下来的章节中解释的那样,实现这样的对等将有助于开发和验证嵌入式软件的全新工作流程。

使用 ISA 对等促进操作系统级对等

为演示本文中涉及概念的参考操作系统,我们将使用 Yocto 项目 创建一个自定义 Linux 发行版。Yocto 项目是一个开源协作项目,可帮助开发人员创建基于 Linux 的自定义系统,而无需考虑硬件。许多嵌入式项目都在使用它,包括 Linux 基金会的 Automotive Grade Linux(AGL)以及 SOAFEE 的参考实现方案。

为了实现操作系统级的奇偶校验,Arm 与亚马逊云科技合作,基于 Yocto 项目为 Graviton 实例创建了亚马逊机器映像(AMI)。AMI 是一个包含软件配置(包括操作系统和应用软件)的模板。它可用于启动亚马逊 EC2 实例,该实例是 AMI 的副本,作为虚拟服务器在云中运行。开发的 AMI 还包括 Arm 的边缘工作负载抽象和协调层(Edge Workload Abstraction and Orchestration Layer, 下文称 EWAOL),它是 SOAFEE 架构的开源参考实现,可进一步促进应用、容器和操作系统环境的对等性。

EWAOL 提供了一个标准的框架,使用容器来部署和协调嵌入式应用程序。这种方法可帮助开发人员在云中开始编写和测试代码,显著改善和扩展工作流程。更具体地说,SOAFEE 有助于 一整个嵌入式软件栈(从嵌入式操作系统开始)的云端开发,而不仅仅是开发中的软件单元的云端开发,从云到嵌入式边缘的无缝移植不再需要交叉编译或仿真(从而解决随之而来的编译错误或性能下降等问题)。

请访问 Amazon Web Services EWAOL 的 demo 实现,了解有关 EWAOL 的更多信息。

既然我们已经引入了操作系统级和 ISA 对等的概念,我们现在就可以修改嵌入式开发人员的工作流程,减少许多不再需要的步骤,如下图所示:

在本博文的其余部分,我们将介绍一个演示教程,详细说明如何使用 Yocto Project 为基于 Amazon Graviton 的实例创建自己的基于 Linux 的自定义 AMI。本教程的目的不仅仅是教授如何在亚马逊云科技上部署已创建的 AMI,而是为开发人员提供一种方法,将他们自己用于嵌入式系统的 Linux 映像带到云上。

如何使用 Yocto 项目为 Amazon Graviton 处理器创建自定义 Linux AMI

本指南将介绍如何创建可用于启动 Amazon EC2 实例的自定义 Linux AMI。首先需要您已经可以访问具有适当权限的亚马逊云科技账户,以创建所需的资源。如果没有,请创建/激活一个账户。 在开始之前,请查看 Amazon Web Services EWAOL GitHub Repo。该版本库包含有关如何创建包括 EWAOL 在内的自定义 Linux AMI 的最新信息和说明。 使用 Yocto 创建自定义 AMI 有五个主要步骤。我们将逐步完成这些步骤,并构建出如下所示的架构:

1. 配置亚马逊云科技资源

首先,我们需要使用 Amazon CloudFormation 对亚马逊云科技账户进行一些设置和配置,通过将基础架构视为代码,您可以亚马逊云科技和第三方资源进行建模、调配和管理。这里使用 Amazon CloudFormation 通过配置文件调配 亚马逊云科技资源,以节省时间。

  1. 转到 Amazon CloudFormation 面板
  2. 点击 “创建堆栈。
  3. 选择”上传模板文件”,选择在步骤 1 中下载的模板文件,然后点击 “下一步”继续。
  4. 在堆栈名称中输入 “yocto-build”。将创建 S3 存储桶切换为 “yes”,并输入任何唯一的存储桶名称。同时选择。CreateVMImportRole 为 “yes”,并填入 policyName “vmimport-policy”选择 “下一步”继续。
  5. 将此页面保留为默认设置,然后选择 “下一步”。
  6. 最后,查看设置,确认身份和访问管理(资源创建),并选择 “创建堆栈”。
  7. 创建过程需要几分钟。当在堆栈状态中看到 “CREATE_COMPLETE”时,就可以进入下一步了。

2. 创建一个 Yocto build 亚马逊 EC2 实例

现在,我们将创建一个 Amazon EC2 实例并将其作为开发环境,使用 Yocto 项目编译和构建自定义 Linux 映像。

  1. 进入亚马逊 EC2 控制面板
  2. 点击侧边栏菜单中的 “实例”。
  3. 点击橙色的 “启动实例”按钮。
  4. 选择 “Ubuntu Server 22.04 LTS”,并选择 “64 位(Arm)”。
  5. 选择 “c6g.4xlarge”实例类型。选择 c6g.4xlarge 实例类型是因为它是 CPU 优化的实例,将用于编译,但也可根据需求使用其他实例类型。
  6. 创建并下载新的密钥对。稍后您将使用该密钥对 SSH 会话进行加密。
  7. 选择正确的 VPC 及子网。将根卷调整为 150GiB 的 gp3(通用固态硬盘)。
  8. 在 “高级详细信息”下,我们需要选择在 CloudFormation 步骤中创建的 “IAM 实例配置文件”,以便为我们的实例提供以下步骤所需的 亚马逊云科技权限。它应该以 “yocto-build-VMBuilder”开头,后面跟着随机字符。
  9. 将所有其余设置保留为默认值,然后选择 “启动实例”。
  10. 最后,你可以选择 “查看实例”按钮,等待实例进入 “运行状态”。

3. 使用 Yocto 项目构建自定义 Linux 映像

接下来,应通过 Amazon Session Manager 登录步骤 2 中创建的构建实例。

sudo su ubuntu
sudo apt update
sudo apt install -y gawk wget git diffstat unzip texinfo gcc build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev xterm python3-subunit mesa-common-dev make python3-pip jq zstd liblz4-tool qemu-utils pylint

在安装了上述软件包后,重启机器。

sudo reboot
curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "/tmp/awscliv2.zip"
unzip /tmp/awscliv2.zip -d /tmp
sudo /tmp/aws/install
sudo pip3 install sphinx sphinx_rtd_theme pyyaml kas==3.0.2
git clone https://github.com/aws4embeddedlinux/meta-aws-ewaol.git
cd meta-aws-ewaol
nohup kas build kas/machines/ewaol-graviton2-ami.yaml &

构建可能会超过一个小时,在构建结束后,调用下面的命令,来创建 image,其中<S3_BUCKET_IMPORT_IMAGES>选择在 CloudFormation 中填写的 S3 桶, 选择需要的磁盘大小。

bash scripts/create-ami.sh <S3_BUCKET_IMPORT_IMAGES> <AMI_DISK_SIZE_IN_GB>

返回结果:

Registering AMI with Snapshot snap-0339855d2042c9644
AMI name: ewaol-baremetal-kirkstone-v1.0-20240926030531-aarch64
AMI ID: ami-0727635a07147018e

查看 EC2 -> AMI, 可以看到对应的 ami 镜像已经创建出。

4. 使用 Yocto AMI 构建 Yocto Linux EC2 Instance

这时我们可以选中 Ami,并且点击 从 AMI 启动实例。 注意因为该 Ami 没有提前预置 SSM Agent,所以为了方便访问,请将该 EC2 放置在公网并且准备 SSH Key。

登录用户名为 ewaol 后,查看 os 信息

ewaol@ip-10-1-1-232:~$ uname -r
5.15.164-yocto-standard

查看 docker,以及 k3s 工具链

ewaol@ip-10-1-1-232:~$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
ewaol@ip-10-1-1-232:~$ sudo kubectl get nodes 
NAME            STATUS   ROLES                  AGE   VERSION
ip-10-1-1-232   Ready    control-plane,master   15d   v1.22.6-k3s1

5. 清理环境

当实验结束后,清理 CloudFormation Stack 以及对应的 EC2 资源(build machine 和 Yocto Linux)。

EWAOL kas YAML 和 Kernel 配置探秘

kas/machines/ewaol-graviton2-ami.yaml 描述了如何通过 Yocto Project 构建一个Linux OS 镜像。

Header

header:
  version: 10
  includes:
    - repo: meta-ewaol
      file: meta-ewaol-config/kas/baremetal.yml

此部分告知 kas 我们正在使用的文件架构版本,并包含了一些来自 EWAOL 仓库的其他 YAML 文件(稍后会进行解释)。这些包含的文件加载了 EWAOL 的基本配置以及一些标准的 ARM 机器定义。

Repository

repos:
  meta-arm:
    url: https://git.yoctoproject.org/git/meta-arm
    path: layers/meta-arm
    refspec: kirkstone
    layers:
      meta-arm: included
      meta-arm-toolchain: included
  meta-ewaol:
    url: https://gitlab.com/Linaro/ewaol/meta-ewaol
    path: layers/meta-ewaol
    refspec: v1.0
  meta-aws:
    url: https://github.com/aws4embeddedlinux/meta-aws.git
    path: layers/meta-aws
    refspec: kirkstone
  meta-virtualization:
    refspec: kirkstone
  meta-ewaol-ext:
    path: meta-ewaol-ext
    refspec: kirkstone
  meta-openembedded:
    refspec: kirkstone
    layers:
      meta-multimedia:
  poky:
    refspec: kirkstone

此部分告知 kas 我们要使用哪些 Yocto 层、从哪里下载它们、使用哪些版本以及将它们存储在哪里。在本示例中,我们使用了 meta-ewaol(SOAFEE 参考实现层)和 aws-meta(提供 亚马逊云科技边缘软件功能的配方)。在文件头部包含了“ewaol-base.yml”,该文件中包含了更多的仓库。此文件还加载了 ‘poky’ 和 ‘meta-openembedded’,它们是标准的 Yocto 层。此外,meta-ewaol-ext 层通过使用补丁和 bbappend 文件,对 cloud-init 和 OpenSSH 的配方进行了定制。需要注意,在 meta-openembedded 中,我们手动添加了 meta-multimedia 层,这是因为 meta-aws 依赖 multimedia-layer 层。

Machine

machine: generic-arm64

这行代码告知 Yocto 我们要为哪种机器生成镜像。在此示例中,使用了 generic-arm64。它会创建一个能够在大多数支持通用启动机制(在此情况下是 UEFI)的 Arm 设备上启动的镜像。

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 = " git rng-tools aws-cli cloud-init cloud-init-systemd e2fsprogs e2fsprogs-resize2fs e2fsprogs-tune2fs e2fsprogs-e2fsck e2fsprogs-mke2fs parted sudo sudo-sudo openssh-sftp-server python3-netifaces python3-charset-normalizer canutils"
    IMAGE_FSTYPES += " wic wic.vhdx"
    DISTRO_FEATURES:append = " ewaol-baremetal"

这一部分配置了该示例特定的自定义配置设置: – 添加 cloud-init:用于在启动时将 AMI 配置为特定的 Amazon EC2 实例。 – 添加一些额外的内核配置:以满足特定需求。 – 添加一些额外的功能:例如 SSH 服务器和亚马逊云科技命令行界面(Amazon Web Services CLI),这是一个统一的工具,用于管理亚马逊云科技服务。

Kernel configuration

为了使 Yocto 在 Amazon Graviton2 处理器上运行,需要激活一些额外的内核配置。这些配置包含在 gravitonKernelConfigs.cfg 文件中。

CONFIG_ENA_ETHERNET NA 是 Amazon EC2 上的一种高速网络接口,这个配置项会使内核支持这种网络接口
CONFIG_BLK_DEV_NVME 使内核支持 NVMe 协议,用于高速 SSD 存储。启用后,内核可以直接与 NVMe 设备
CONFIG_SERIAL_8250_PCI 支持通过 PCI 总线连接的串行端口(常见的 UART),使内核能够处理串行通信
CONFIG_CAN 启用 CAN(Controller Area Network)总线协议支持
CONFIG_CAN_VCAN vcan 是一种虚拟的 CAN 设备驱动,用于模拟 CAN 总线通信,方便在无实际硬件时进行开发和测试
CONFIG_CAN_GW 使内核支持 CAN 网关,允许在不同 CAN 网络之间转发消息或修改消息内容。网关功能用于复杂的 CAN 网络通信场景
CONFIG_CAN_VXCAN VXCAN 是两个虚拟 CAN 设备之间的点对点连接,类似于虚拟的“电缆”,用于将 CAN 帧在虚拟 CAN 设备之间传递
CONFIG_CAN_ISOTP ISO-TP 是一种 CAN 协议,用于在 CAN 网络上传输长帧数据,特别是用于汽车诊断协议(如 UDS)。启用后,内核支持这种分段传输协议

总结

在这篇博客中,我们介绍了环境对等的高层次概念,以及 Arm、亚马逊云科技和其他合作伙伴的工作方向:构建一个软件定义的系统,并加速汽车软件开发。我们还提供了一个演示教程,展示了如何使用 Yocto Project 为基于 Arm 的 Amazon Graviton 处理器创建自定义 AMI,以便用于您自己的开发工作流程。 如果您想深入了解这一概念,可以访问这个详细的 workshop,了解如何使用本文中创建的 AMI 为汽车开发创建一个自动化的软件开发流水线,并演示环境对等的概念。关于嵌入式边缘可扩展开放架构(SOAFEE)项目的更多信息,请访问 soafee.io

原文链接

https://aws.amazon.com/blogs/industries/building-an-automotive-embedded-linux-image-for-edge-using-arm-graviton-yocto-project-soafee/

本篇译者

陆云飞

亚马逊云科技解决方案架构师。主要专注汽车行业解决方案的落地,如 Alexa 生态的技术落地,车联网的设计实施等。他拥有丰富的开发经验,曾参与 Amazon EC2 等核心产品及系统的研发及上线工作,对 DevOps 有深入的理解。

孙健

亚马逊云科技行业解决方案架构师,10+ 年汽车行业从业经验,从事汽车电子电器分析、自动驾驶解决方案相关领域,对自动驾驶、软件定义汽车等云架构设计及应用有丰富经验。