麦斯科技 · 2021年10月31日

在SystemReady IR兼容硬件上部署Yocto

https://developer.arm.com/documentation/dui1102/latest

概述

SystemReady IR是一个基于一组硬件和固件标准的合规性认证计划,可实现与通用现成操作系统和虚拟机监控程序的互操作性。这些标准包括基本系统架构(BSA)和基本引导要求(BBR)规范,以及特定于市场的补充。

Yocto项目(YP)是一个行业标准开发工具,用于为嵌入式设备构建基于Linux的软件堆栈。YP提供了创建定制解决方案的灵活性,但是大多数YP构建需要定制工程在特定硬件平台上运行。因此,很难用单个配置支持多个目标。在SystemReady IR平台上,YP构建依赖于一致的引导行为、固件提供的系统描述和主线Linux支持,以消除每个平台的启用。SystemReady IR减少了维护工作量,可以用一个映像支持多个平台。

在本指南中,了解SystemReady IR兼容平台如何使YP解决方案的构建、部署和维护更加容易。本指南主要介绍SystemReady计划的SystemReady红外波段。该频带满足嵌入式Linux生态系统的需求,并与YP开发人员相关。本指南中的所有示例均使用SystemReady IR兼容平台。

本指南将向您介绍以下内容:

  • SystemReady IR启动流
  • 基于Arm的NXP板上的参考部署示例
  • 有关在何处找到必要组件的信息,以便在SystemReady IR兼容平台上启动并运行YP

您可以使用相同的YP配置支持SystemReady SR和ES认证平台,但本指南中未介绍此配置。

什么是SystemReady IR?

云本机软件开发对于实现大规模物联网部署至关重要。按照云本地原则,您可以构建云和边缘协同工作的系统,并利用每种计算类型的优势。

为了帮助云原生边缘生态系统的发展并支持物联网的持续增长和创新,Arm启动了卡西尼计划。Cassini项目是一项开放、协作、基于标准的倡议,由三大支柱组成:标准化、安全和生态系统。SystemReady IR构成了Cassini项目的标准化支柱,将成为本指南的重点。有关卡西尼计划的更多信息,请参阅卡西尼计划。

物联网设备通常基于Linux,用于从复杂智能摄像头到小型工业控制器等行业。为了实现这些用例,需要一个灵活的SoC生态系统来实现独特的功能集,以满足特定的需求。这种灵活性可能导致碎片化,系统缺乏一套通用特性和接口的标准。因此,碎片化影响开发者和更广泛的物联网生态系统。

物联网软件通常需要针对特定硬件目标开发。每个平台都有不同的依赖项,需要一个独特的软件堆栈。调试和日常维护成本可能会很高,但SystemReady IR解决了物联网中的碎片问题。

SystemReady是一个合规性认证计划,针对Arm生态系统的不同部分,有单独的波段。对于所有频段,符合SystemReady的平台都使用标准固件接口,简化了引导过程,无需特定于平台的引导支持。SystemReady IR为Linux和其他使用devicetree规范的操作系统提供标准。这些标准使您能够轻松地跨所有SystemReady兼容平台部署标准软件堆栈。创建特定于平台的软件堆栈所花费的精力可以重定向到更重要的任务,例如构建与众不同的功能。

SystemReady IR认证平台使用最少一组硬件和固件功能,并且必须符合以下要求:

  • 基于Arm的64位系统体系结构(BSA)

https://developer.arm.com/documentation/den0094/latest

  • 嵌入式基本引导要求(EBBR)

https://developer.arm.com/architectures/platform-design/embedded-systems

  • EBBR Arm基本引导要求的配方

https://developer.arm.com/documentation/den0044/latest

设备树规范

使用相关SystemReady频带的架构合规套件(ACS)工具测试平台的合规性。有关SystemReady IR认证流程的更多信息,请参阅SystemReady IR-物联网集成、测试和认证。

基于Arm的系统架构

基于Arm的系统架构(BSA)为SoC设计者提供了一个标准的硬件架构。该体系结构允许您针对特定用例优化SoC,并保留最小的功能集以实现软件可组合性。删除特定SOC的附加硬件功能所节省的成本被跨不同硬件开发软件的复杂性所抵消。满足BSA定义的最低硬件规格简化了此优化过程。

BSA规定了基于Arm体系结构的64位硬件系统,基线要求包括处理元件、内存子系统、中断、内存管理单元(MMU)、PCIe、外围设备以及其他电源和安全功能。BSA描述了操作系统启动和运行所需的最少功能集。对于特定细分市场,可以在这些基线要求的基础上添加更多要求,例如,BSA服务器补充。基线BSA规范足以用于物联网。

在用于SystemReady IR合规性的AARC64平台上,必须运行ACS测试工具中包含的BSA测试并报告结果。然而,结果是信息性的,平台不需要通过所有BSA认证测试。BSA没有规定32位硬件要求,AArch32平台也没有BSA测试用例。

嵌入式基本引导要求

嵌入式基本引导要求(EBBR)解决嵌入式引导序列中的碎片问题。嵌入式平台传统上实现定制引导序列,因此需要对操作系统进行特定于平台的修改。EBBR指定了引导功能,以确保OSs可以不经修改地引导。随着嵌入式部署变得越来越大、越来越多样化,标准化引导行为变得越来越重要。

EBBR规范定义了固件与操作系统或虚拟机监控程序之间接口的功能。EBBR兼容平台为操作系统提供了一致的固件接口,允许兼容操作系统在未经修改的情况下启动,并采用包括安全启动和固件更新在内的高级功能。EBBR使用统一可扩展固件接口(UEFI)规范定义操作系统或虚拟机监控程序期望的引导和运行时服务。

Arm基础引导要求(BBR)涵盖所有SystemReady波段。本规范包括一个EBBR配方,该配方规定了在实施EBBR要求时如何满足BBR合规性。

设备树规范

devicetree规范定义了描述特定系统硬件组件的数据结构。引导加载程序同时加载内核映像和Devicetree Blob(DTB)。然后,操作系统内核读取devicetree信息,允许它使用和管理硬件组件。Devicetrees将硬件描述移出内核二进制文件,有助于减少支持特定硬件所需的内核分叉的数量。

传统上,在嵌入式Linux系统中,devicetree是作为操作系统映像的一部分包含的,操作系统需要为每个支持的平台包含devicetree。SystemReady IR与SystemReady IR的区别在于需要固件来提供适合引导Linux内核的默认devicetree,这样操作系统就不需要提供自己的副本。这使得在更广泛的硬件上部署单个映像成为可能。

默认devicetree要求是固件上的要求,而不是操作系统上的要求。操作系统不需要使用默认的devicetree,如果需要,可以在启动时安装替换设备。

UEFI概述

UEFI标准定义了操作系统使用的固件公开的应用程序二进制接口(ABI)。UEFI选择加载和执行哪个二进制文件,定义一组用于访问控制台、网络、存储器和其他设备的抽象接口,并详细说明如何将控制权从固件移交给操作系统。最著名的UEFI兼容固件开源实现是Tianocore EDK2参考实现。U-Boot还实现了UEFI ABI的一个子集。大多数与IR兼容的平台都使用U-Boot实现。

UEFI固件能够查找、加载和执行UEFI应用程序。此固件提供对设备的基本访问,直到操作系统准备好控制平台并使用自己的设备驱动程序。UEFI应用程序是PE/COFF格式的可执行代码。固件不需要知道应用程序的功能。当UEFI应用程序运行时,它可以运行到完成并将控制权返回到固件,或者将控制权转移到承担硬件控制权的操作系统。第一种类型的应用程序包含独立的实用程序、启动菜单或其他工具。第二种类型的UEFI应用程序称为操作系统加载程序。UEFI应用程序还可以加载和执行另一个UEFI应用程序。例如,像GRUB这样的引导菜单应用程序可以加载和执行操作系统加载程序,比如嵌入Linux内核映像中的UEFI存根。

UEFI应用的示例如下:

  • GRUB,Linux发行版用于显示引导选项菜单的引导系统
  • Memtest86,一个行业标准的内存压力测试应用程序
  • UEFI Shell
  • Linux内核。Linux内核本身就是一个UEFI应用程序。内核包含一个UEFI存根,该存根调用ExitBootServices(),并在跳入内核之前设置执行环境。
  • Tianocore EDK2 SCT,标准UEFI自我认证测试套件
  • Doom

通过设计,UEFI是一个简化的执行环境。应用程序是使用简单内存管理的单线程应用程序。UEFI不提供调度服务。一次运行一个UEFI应用程序。UEFI旨在为操作系统提供足够的功能,以便在将控制权交给操作系统之前执行引导前操作,例如选择特定的内核版本或加载其他文件。定义的ABI(也称为协议)提供对网络、存储、控制台、变量和内存管理服务的抽象访问。

UEFI中还包括分区块设备的GUID分区表(GPT)格式。GPT取代了MBR(主引导记录)分区方法,因为GPT支持更大的设备,可以处理更多的分区,并且对损坏具有鲁棒性。

UEFI引导过程

本节解释设备通电时UEFI引导的发生方式。UEFI组件和操作系统是通用的,独立于系统固件。没有特定于平台的定制。本节中的信息适用于任何符合SystemReady的平台。

当平台从重置中释放时,固件在执行引导设备选择以定位和运行UEFI应用程序之前执行内部初始化。引导设备选择首先使用BootOrder和BootXXX变量来查找合适的UEFI应用程序。每个BootXXXX变量都包含引导选项的名称和UEFI可执行文件的路径,格式为/Device/path/in Device。在Linux上使用efibootmgr实用程序查看BootXXXX项的示例,例如以下示例代码:

root@toybrick-debian:~# efibootmgr -v
BootCurrent: 0001
BootOrder: 0001
Boot0001* Debian    VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/eMMC(0)/eMMC(1)/HD(3,GPT,5f6b0000-0000-403e-8000-0d7d00000b89,0x6000,0x100800)/File(EFI\debian\shimaa64.efi)
root@toybrick-debian:~#

BootOrder是一个数字列表,格式为0001、0004、0002。BootOrder对应于BootXXXX变量,这些变量告诉固件在哪里可以找到UEFI应用程序。在代码示例中,固件尝试按该顺序加载和执行由Boot0001、Boot0004和Boot0002指向的UEFI应用程序。固件将尝试按BootOrder顺序执行每个BootXXXX条目。如果找不到应用程序,或者应用程序退出并返回固件,固件将继续执行下一个引导顺序条目,直到列表完成。

通常,BootXXXX条目指向存储在EFI系统分区(ESP)中的文件。ESP是一个FAT格式的分区,固件用于存储启动应用程序和其他实用程序。安装操作系统后,操作系统会将引导应用程序复制到ESP中,以便固件可以查找和读取这些应用程序。

如果未定义BootOrder或BootXXXX目标都无法运行,固件将返回默认引导目标。这些目标是任何带有ESP的设备上的/EFI/BOOT/BOOT<ARCH>.EFI的可移动设备路径,或者是网络引导路径。默认引导目标的顺序由实现定义,通常由用户控制。大多数EDK2实现都向用户提供引导菜单。在U-Boot实现中,默认引导顺序通常由Boot_targets变量定义,如下代码所示:


U-Boot 2021.07-dirty (Aug 06 2021 - 21:43:32 +0100)
 
SoC: Rockchip rk3399
Reset cause: RST
Model: Rockchip RK3399 Toybrick ProD Board
DRAM:  2 GiB
PMIC:  RK8090 (on=0x40, off=0x00)
MMC:   mmc@fe320000: 1, sdhci@fe330000: 0
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Model: Rockchip RK3399 Toybrick ProD Board
Net:   
Warning: ethernet@fe300000 (eth0) using random MAC address - ce:82:85:cf:61:0d
eth0: ethernet@fe300000
Hit any key to stop autoboot:  0 
=> printenv boot_targets 
boot_targets=mmc0 mmc1 usb0 pxe dhcp sf0 
=>

创建SystemReady IR可引导操作系统映像

本节介绍操作系统如何使用UEFI固件进行引导。Linux、BSD和其他操作系统包含对UEFI ABI的支持。要构建可引导的操作系统映像,可执行文件必须位于正确的位置。

对于初始配置,设备将不会设置BootOrder或BootXXXX变量,平台将从默认引导目标之一引导。最常见的引导目标使用块设备上的可移动媒体引导路径,或使用DHCP/TFTP、iSCSI或HTTPS通过网络引导。目前,U-Boot实现TFTP引导,iPXE可用于iSCSI引导。U-Boot没有HTTPS引导的实现。在本指南中,我们从块设备(如USB驱动器)启动。

对于要将块设备视为可引导的固件,固件需要能够找到包含/efi/boot/boot<architecture>.efi文件的ESP分区。例如,在AArch64上,引导文件是/efi/boot/bootaa64.efi。对于GPT格式的磁盘,ESP必须采用FAT格式,并使用分区类型0xef00进行标记。ISO磁盘映像不需要单独的ESP,但必须包含/efi/boot/bootaa64.efi文件。

要在GRUB中创建可引导映像,请将GRUB.efi复制到/efi/boot/bootaa64.efi,并将GRUB配置文件放在同一目录中。其他UEFI引导应用程序(如systemd boot)也以类似的方式安装。有关更多信息,请参阅引导应用程序的文档。

将操作系统复制到本地存储后,它可以用BootXXXX变量替换可移动引导路径。此变量允许操作系统指定安装路径和UEFI引导目标的选择。Linux发行版安装程序在将引导加载程序复制到ESP后,使用SetVariable()UEFI API设置BootXXXX。

Yocto项目概述

Yocto项目帮助开发人员构建定制的嵌入式Linux发行版。它因其模块化而广受欢迎,它允许您优化速度、占地面积和内存利用率。Yocto项目包含以下关键要素:

  • Linux开发工具
  • Poky,一个参考嵌入式发行版
  • 开放嵌入构建系统

Poky是Yocto的稳定参考操作系统,它展示了嵌入式系统的基本功能。Poky结合了Yocto项目的核心组件,经过测试和支持,并经常收到更新。开发人员可以使用POKY作为基础并适应它的需求。Yocto模块化的基础是层模型,它允许将功能逻辑组织到层中。图层将相关的配方分组,并告诉构建系统要制作什么。Recipes是元数据的一种形式,其中包含有关在何处查找源代码的说明以及有关依赖项和编译选项的信息。

OpenEmbedded层索引提供了一种查找层的简单方法,例如Board Support Packages(BSP)、GUI、中间件和Poky层。Yocto项目兼容层索引包括经验证可与Yocto合作的层的管理。将预构建层与自定义构建层相结合,开发人员可以构建整个发行版。层系统创建了一个逻辑层次结构,它支持代码的协作和重用,同时简化了软件的整体视图。

示例层次结构可以包括以下层:

  • 开发人员特定层,针对特定产品需求的自定义功能
  • POKY,一个作为基础的参考操作系统
  • 硅供应商或ODM提供的特定于硬件的BSP
  • Yocto特定层,是Yocto构建的特定配置

OpenEmbedded core,一组在OpenEmbedded派生构建中保持一致的基础配方

OpenEmbedded构建系统使用BitBake工具。BitBake解析配方,通过本机编译或交叉编译编译最终图像。有关Yocto的更多详细信息,请参阅Yocto文档。https://docs.yoctoproject.org/

Yocto的SystemReady IR

Yocto提供了一种构建自定义操作系统映像的简单方法。嵌入式开发人员通常支持具有不同硬件和固件的许多平台,为每个配置创建定制的Yocto映像。SystemReady IR旨在解决这一复杂性。SystemReady IR兼容平台向操作系统公开了一组标准化的接口,这样Yocto构建和其他现成的Linux发行版就可以在不做修改的情况下启动。嵌入式平台可以针对SystemReady IR,但是Yocto构建可以在与SystemReady兼容的平台之间启动,而无需修改。例如,可以在符合SystemReady SR的服务器上开发Yocto构建,然后无缝地移植到SystemReady IR的生产硅上。

SystemReady IR为嵌入式开发人员提供了解决碎片问题的有效解决方案,提供了一种软件体验,同时保留了Yocto所熟知的可定制性。通过这种组合,您可以大大减少工作量,支持大型、多样化的部署。

示例:在NXP板上部署

开始之前,您将需要以下内容:

  • NXP i.MX 8M迷你EVK板
  • 2GB或更大的micro SD卡
  • 运行Linux环境的计算机

使主板SystemReady IR兼容

1,确保您有一个NXP帐户。

2,从嵌入式Linux for i.MX应用程序处理器下载并提取i.MX 8M Mini EVK启动映像(SystemReady IR认证)。https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX?tab=In-Depth_Tab

3,从mfgtools GitHub存储库下载uuu工具。该工具用于对车载eMMC进行编程。https://github.com/NXPmicro/mfgtools/releases

4,在NXP板上,将电源开关滑到关闭位置,并将引导模式开关设置为下载模式。下表显示了开关设置:

1.png

1=向上切换,0=向下切换,X=任意一个

1,将USB-C电源线连接到电源,将USB-C USB电缆连接到电脑,将USB微型电缆连接到电脑(串行)。下图显示了电缆的连接方式:

cable-connection.png

1,将电源开关滑到on(接通)位置并闪存引导固件,如以下代码段所示:

$ sudo uuu -b emmc imx-boot-imx8mmevk-sd.bin-flash_evk
车载eMMC上安装了与SystemReady IR兼容的U-Boot版本。

2,将电源开关滑到断开位置,并将引导模式开关设置为eMMC模式,如下表所示:

2.png

1=向上开关,0=向下开关

该板现在可以从SD卡或USB启动SystemReady IR兼容的操作系统。

构建一个通用的SystemReady IR Yocto映像

既然主板与SystemReady IR兼容,下一步就是构建一个基本的通用Yocto映像,该映像将在任何SystemReady兼容平台上启动。

1,确保满足所有Yocto构建先决条件,如Yocto项目快速构建中所述。

2,使用以下代码设置Poky和meta arm层:

$ git clone git://git.yoctoproject.org/poky
$ git clone git://git.yoctoproject.org/meta-arm 
$ cd poky
$ source oe-init-build-env
$ bitbake-layers add-layer ../../meta-arm/meta-arm-toolchain
$ bitbake-layers add-layer ../../meta-arm/meta-arm

3,将conf/local.conf config文件中的机器配置值更改为generic-arm64,如以下代码段所示:

$ sed -i 's/qemux86-64/generic-arm64/' conf/local.conf

通用arm 64是通用SystemReady IR aarch64机器。

4,将init系统从sysvinit更改为systemd,如下代码所示:

$ echo 'DISTRO_FEATURES += " systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED += "sysvinit"' >> conf/local.conf

该系统能够从内核正确地检测控制台tty。

5,使用以下代码构建Yocto映像:

$ bitbake core-image-base

6,使用以下代码将图像复制到micro SD卡:

6.       Copy the image to a micro SD card using the following code:
sudo dd if=tmp/deploy/images/generic-arm64/core-image-base-generic-arm64.wic 
of=/dev/sdX bs=4M

7,将microSD卡插入开发板并打开电源。如以下屏幕截图所示,电路板显示U-boot、systemd boot菜单和Yocto的登录shell:

boot.png

Yocto映像现在安装在NXP板上。

推荐阅读
关注数
5822
内容数
525
定期发布Arm相关软件信息,微信公众号 ArmSWDevs,欢迎关注~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息