啥都吃的豆芽 · 2020年09月16日

AWS Graviton处理器为嵌入式Linux开发人员扩展选择

image.png
Jason Andrews 2020年9月15日

正在进行的一个重大变化是ARM架构向桌面和云的迁移。

Docker Desktop和QEMU可用于在x86机器上构建和运行针对ARM架构的Linux应用程序,但开发人员体验与在ARM计算机上开发不同。使用AWS Graviton处理器,嵌入式Linux开发人员可以更灵活地在更短的时间内执行许多任务。

嵌入式Linux系统主要由Linux内核和根文件系统两部分组成。传统的开发过程包括在x86机器上交叉编译软件,然后对SD卡或eMMC模块等存储设备进行编程。一旦编程过程完成,嵌入式系统就会引导并运行Linux。树莓派是这一过程的一个很受欢迎的例子,但也有许多系统以类似的方式运行。

嵌入式系统通常具有一些与硬件紧密耦合的软件。这意味着开发人员直接在目标硬件上运行软件。AWS Graviton处理器会改变这一点。让我们通过两个示例来了解使用AWS Graviton处理器进行嵌入式Linux开发的好处。

在采用AWS Graviton处理器的EC2实例上使用ARM文件系统

恩智浦S32V汽车开发平台面向视觉和传感器融合应用。恩智浦的软件以基于ARM Cortex-A53设备的电路板支持包(BSP)的形式提供。下载内容包含Linux内核映像、文件系统和其他构件,如Linux设备树和引导加载程序。

使用基于Graviton的EC2实例,可以提取文件系统并使用chroot命令检查和修改文件系统的内容。由于S32V和AWS Graviton处理器共享共同的ARM架构,因此文件系统中的应用程序可以在任一系统上执行。让我们看看如何确定S32V文件系统中安装了哪个版本的GCC,并使用一个EC2实例编译和运行一个C语言示例。

首先,创建一个新的EC2实例。实例可以是采用Graviton处理器的任何实例类型,包括A1、T4G、M6G、C6G或R6G。有许多AWS教程介绍如何创建AWS帐户并使用AWS控制台配置和启动新的EC2实例。请确保在您使用的任何教程中替换上述实例类型之一。

在本例中,我创建了一个运行Ubuntu18.04的t4g.media,它有一个公共IP地址,可以从我的桌面通过ssh访问。

我使用上面的链接下载了S32V BSP,并从包含根文件系统的包中解压了tar文件。我忽略了所有其他Linux内核文件和SD卡镜像。

将文件系统tar.gz文件复制到创建的EC2实例并解压缩。在命令中使用您的密钥文件和EC2 IP地址。

$ scp -i key.pem fsl-image-auto-s32v234evb.tar.gz ubuntu@<ec2-ip-address>:~/
$ ssh -i key.pem ubuntu@<ec2-ip-address>

在连接到EC2实例之后,设置根文件系统

$ mkdir fs ; cd fs
$ tar xvf ../fsl-image-auto-s32v234evb.tar.gz ; cd ..
$ sudo chroot fs /bin/bash 

现在,我在S32V文件系统中,bash提示符会更改。

检查安装的GCC的版本

bash-4.4# gcc --version
gcc (Linaro GCC 6.3-2017.06~dev) 6.3.1 20170509

下面是一个简单的test.c程序,可以在chroot中编译和运行。编辑新文件test.c并添加内容。这可以在ec2机器上完成并复制到根fs目录中,也可以直接在chroot中运行vi并创建文件

#include <stdio.h>
#include <stdlib.h>

int main()
{
    srand(1);

    double a1[1000] __attribute__((__aligned__(16)));
    double a2[1000] __attribute__((__aligned__(16)));
    double a3[1000] __attribute__((__aligned__(16)));

    double sum = 0;

    for (int i = 0; i < 1000; i++) {
        a1[i] = (rand() % 2000) - 1000;
        a2[i] = (rand() % 2000) - 1000;
    }


    for (int i = 0; i < 1000; i++) {
        a3[i] = a1[i] * a2[i];
    }

    for (int i = 0; i < 1000; i++) {
        sum += a3[i];
    }

    printf("Sum: %f\n", sum);

    return 0;
}

退出chroot并将test.c复制到fs/目录,然后重新输入chroot

$ cp test.c fs/home/root
$ sudo chroot fs /bin/bash
bash-4.4# cd /home/root

甚至vi也在chroot内部工作以编辑test.c

bash-4.4# gcc -O3 -g test.c -o test
bash-4.4# ./test
Sum: 258936.000000

使用objdump反汇编程序。此处显示了部分输出

bash-4.4# objdump -S test | more
    double sum = 0;

    for (int i = 0; i < 1000; i++) {
        a1[i] = (rand() % 2000) - 1000;
  4004fc:       5289ba74        mov     w20, #0x4dd3                    // #19923
{
  400500:       a9025bf5        stp     x21, x22, [sp, #32]
        a1[i] = (rand() % 2000) - 1000;
  400504:       72a20c54        movk    w20, #0x1062, lsl #16
{
  400508:       a90363f7        stp     x23, x24, [sp, #48]
  40050c:       910103b5        add     x21, x29, #0x40
  400510:       8b0303b6        add     x22, x29, x3
    srand(1);
  400514:       d2800018        mov     x24, #0x0                       // #0
        a1[i] = (rand() % 2000) - 1000;
  400518:       5280fa13        mov     w19, #0x7d0                     // #2000
    for (int i = 0; i < 1000; i++) {
  40051c:       d283e817        mov     x23, #0x1f40                    // #8000
    srand(1);
  400520:       97ffffe8        bl      4004c0 <srand@plt>
        a1[i] = (rand() % 2000) - 1000;
  400524:       97ffffdb        bl      400490 <rand@plt>
  400528:       9b347c01        smull   x1, w0, w20
  40052c:       9367fc21        asr     x1, x1, #39
  400530:       4b807c21        sub     w1, w1, w0, asr #31
  400534:       1b138020        msub    w0, w1, w19, w0
  400538:       510fa000        sub     w0, w0, #0x3e8
  40053c:       1e620000        scvtf   d0, w0
  400540:       fc386aa0        str     d0, [x21, x24]

它的外观和感觉就像一台原生的ARM Linux计算机。没有交叉编译,并且使用了来自S32V文件系统的完全相同的工具。

有些应用程序需要特定的硬件,不能在通用计算机上正常运行,但许多应用程序可以按预期运行。很容易看出如何使用BSP提供的相同工具和库构建和测试应用程序。在花时间对电路板进行编程和启动之前,可以检查所有内容,结果发现没有包含某些内容或功能不正常。

Docker从头开始是利用基于Graviton的EC2实例进行嵌入式Linux开发的另一种方式。

退出chroot,让我们从头开始尝试Docker。

将Docker与嵌入式文件系统配合使用

Docker提供了另一种使用嵌入式Linux文件系统的方法。

在同一个t4g.media实例上安装Docker,并确保它可以运行hello-world

$ sudo apt update
$ sudo apt upgrade -y
$ curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh
$ sudo usermod -aG docker ubuntu ; newgrp docker
$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

要使用S32V文件系统从头开始构建坞站映像,请使用您喜欢的编辑器创建Dockerfile

FROM scratch
ADD fsl-image-auto-s32v234evb.tar.gz /
ADD test.c /home/root
CMD /bin/bash

使用Dockerfile和当前目录下的根文件系统构建docker镜像

$ docker build -t s32v -f Dockerfile .

运行Docker映像并编译软件

$ docker run -it  s32v
bash-4.4# cd /home/root
bash-4.4# gcc -O3 -g test.c -o test
bash-4.4# ./test
Sum: 258936.000000
bash-4.4# exit

当容器退出时,Docker不会自动保存修改后的镜像。要保存修改后的容器,请获取容器ID并使用COMMIT命令写入新映像

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS               NAMES
fb2481cfe668        s32v                "/bin/sh -c /bin/bash"   23 seconds ago       Exited (0) 2 seconds ago                        elastic_liskov
$ docker commit fb2481cfe668 s32v

图像可以保存在Docker Hub或AWS ECR中。还可以保存图像的tar文件,然后在计算机之间手动复制

$ docker save s32v | gzip > s32v-fs.tgz

Docker save中的tar文件是每个图像层的tar文件,可以放回我们开始时所做的修改的文件系统中。

与chroot相比,Docker还可以方便地在机器之间传输图像,并提供了一些易用性。

Docker和chroot与采用Graviton处理器的EC2实例相结合,是嵌入式Linux开发人员的强大工具,简化了ARM的开发体验。通过多种EC2配置,可以为任务调整合适的CPU数量和内存大小。编译大型项目可以比在开发板上或通过交叉编译更快、更容易地完成。

恩智浦S32V根文件系统使用的技术几乎可以应用于任何嵌入式Linux开发板。

总结

AWS Graviton处理器改善了嵌入式Linux系统的开发人员体验。像chroot和docker这样的命令从头开始改进了开发人员体验,因为它不需要在开发板上完成所有工作。当构建机器为x86,目标系统为ARM时,交叉编译、复制、运行、调试循环更加耗时。A1、T4G、M6G、C6G和R6G实例种类繁多,让您可以轻松选择合适的硬件以获得最佳性能。

值得考虑的是,AWS Graviton处理器如何适应您在ARM上开发Linux的工作流程。现在是试验新的T4G EC2实例并利用2020年前免费试用的最佳时机。

推荐阅读
关注数
23554
内容数
1003
Arm相关的技术博客,提供最新Arm技术干货,欢迎关注
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息