基于ARMv8的固件系统体系结构

The architecture of ARMv8-based firmware systems

自2011年发布以来,ARMv8处理器架构在移动设备市场上已经相当普及。根据ARM有限公司首席执行官的预测,到2020年,这一代处理器将获得高达25%的世界市场份额。通过继承历史上形成的基础设施的特性和一般原则,软件支持得以建立并得到进一步发展,这是很自然的。

在服务器细分市场上,观察到了一种根本不同的情况。基于X86的服务器在这一领域占据主导地位已有很长一段时间,而ARMv8只是找到了自己的路(而且只进入了特定的业务领域)。ARM市场的新颖性以及大多数公认的标准和规范(主要是ACPI和UEFI)直到最近才适用于ARM系统,这一点在软件基础设施的开发上留下了印记。

本文着重于对基于ARM的服务器系统和处理器特性的概述,并不声称是详尽的描述。作者还想提请读者注意这样一个事实:所提供的数据可能很快就会过时——很快,新的处理器将带来新的技术解决方案,可能需要采用不同的方法来实现软件基础设施。

首先,我们应该指出,当前ARMv8服务器系统的固件实现由几个相对独立的组件组成。这提供了许多优点,例如在服务器和嵌入式系统固件中使用相同组件的可能性,以及引入的更改的相对独立性。

那么,这些系统使用了哪些模块和组件,它们的功能是什么?模块的加载和交互的总体图如图1所示。这个过程从初始化子系统开始,比如RAM和处理器间接口。在当前的实现中,这是由EL3S模式下的一个单独的模块在打开主CPU电源后立即执行的。因此,系统的这个组件拥有最大的权限。它通常不与操作系统直接交互。

图1. 模块的加载和交互。

之后,控制权被转移到下一个组件,通常是ARM可信固件(ATF)模块,该模块在相同的模式下执行。ATF控制可以直接从上一段描述的0级加载器传输,也可以通过实现PEI(PreEFI初始化)的特殊UEFI模块间接传输。ATF由几个在不同时间接收控制的模块组成。

BL1启动模块执行分配给安全处理器模式的平台部件的初始化。由于基于ARMv8的系统对可信和非可信资源(包括RAM)使用硬件分离,BL1模块为可信代码的执行准备了一个环境。具体而言,这种类型的初始化包括存储器/高速缓存控制器的配置(通过对这些设备中的寄存器的编程来标记可信和非可信区域)和片上设备的标记(能量无关的内存控制器)。这个标记还引入了基于设备类型(可信/不可信)的DMA事务过滤。考虑到所有这些,内存的写入/读取只能从安全设置与设备的安全设置相匹配的区域进行。可信环境的实现可能相当复杂;例如,它们可以包含一个单独的操作系统。但是,这种实现的描述超出了本文的范围。

BL1模块配置MMU地址转换表和异常处理程序表,其中最重要的元素是安全监视器调用(SMC)指令的异常处理程序。在这一点上,处理程序是最小的,实际上只能将控制权转移到加载到RAM中的映像。运行时,BL1模块将下一级(BL2)加载到RAM中,并将控制权转移给它。BL2模块在EL1S模式下工作,权限减少。因此,使用“ERET”指令执行向该模块的控制转移。

BL2模块的目的是加载剩余的固件模块(BL3部件)并将控制权转移给它们。降低的特权级别用于避免可能损坏内存中已有的代码和EL3S数据。这些部件的代码是通过使用SMC指令调用位于BL1阶段的EL3S代码来执行的。

ATF加载和初始化的第三阶段可包括三个阶段,但第二阶段通常被省略。因此,事实上,只剩下两个。BL3-1模块是可信代码的一部分,通用软件(OS等)可以在运行时访问它。这个模块的关键部分是由“SMC”指令调用的异常处理程序。模块本身有实现标准SMC调用的功能:实现标准PSCI接口(设计用于控制整个平台,例如启用/禁用处理器核心、平台范围内的电源管理和重新启动)以及处理特定于供应商的调用(提供有关平台的信息,管理嵌入式设备等)。

如上所述,BL3-2模块的存在是可选的;其代码(对于模块而言)是在EL1S模式下执行的。通常,它作为平台操作期间发生的事件(来自某些计时器、设备等的中断)的专用服务/监视器

实际上,BL3-3不是ATF模块,而是在非安全模式下执行的固件映像。它通常在EL2模式下获得控制权,并表示类似于众所周知的U-Boot的引导加载程序的映像,或者表示UEFI环境的映像,UEFI环境是服务器系统的标准配置。

ATF模块初始化的总体图如图2所示。

图2. ATF模块初始化。

在某些基于ARMv8的服务器系统中可以使用另一个初始化路径:ATF在UEFI PEI阶段启动,之后转换到UEFI DXE阶段。

armv8uefi与x86上的有很大不同。PEI和DXE(驱动程序)阶段同时用于x86和ARMv8。然而,在许多ARMv8系统上,PEI阶段显著减少,并且在此期间不执行硬件初始化。该阶段包括设置MMU转换表、配置中断控制器和CPU定时器(根据UEFI规范,此环境中唯一处理的中断是定时器中断)、构建EFI切换块(HOB)和执行DXE内核。在这个阶段,本地UEFI模块倾向于使用上面描述的特定于平台的SMC调用。

UEFI的大部分工作在DXE阶段执行。首先,这涉及到加载和启动硬件驱动程序,包括片上外围设备和通过PCIe、USB、SATA等接口连接的外部设备。

应该注意的是,基于ARMv8的系统在配置、设备检测机制等方面与基于x86体系结构的类似系统有很大的不同。例如,x86的主要设备检测机制是扫描PCI配置空间并为设备分配内存地址,这些设备必须对其进行解码。在基于ARMv8的系统中,内置外设几乎总是在内存空间中有固定地址(端口是未使用的,因为它们不受CPU体系结构的支持),并且在某些情况下在PCI配置空间中不可见。对于这样的系统,有一个由平坦的设备树组成的硬件描述,设备连接的树状描述也描述了诸如与这些设备相关联的存储器范围和中断号等资源。

在更高级的系统中,soc支持通过PCI配置空间进行访问,并包含通过增强配置访问机制(ECAM)实现对该空间的访问的控制器。由于这些单元的内存地址是固定的,因此通用的PCI设备配置机制不适用。具体而言,对于具有固定PCI设备地址窗口的系统,开发了增强的分配PCI功能,解决了这一矛盾。可以单独写一篇文章来介绍这种功能的独特属性。简言之,它可以描述为一组替代寄存器,其中包含有关内存地址、总线号(对于内置PCI-PCI桥)等的信息。

UEFI与另一种传递平台配置信息的方法ACPI是分不开的。目前,为改进对ARMv8体系结构的支持而开发和完善ACPI规范的工作正在进行中。根据现有信息,ACPI应该成为描述ARMv8平台及其管理的基本信息(主要是处理器内核、PCI/PCIe控制器的数量和配置)及其管理的关键方法。一些计划发布的ARMv8操作系统只支持ACPI机制。

DXE阶段包括设备检测和它们在UEFI中的初始化和注册,以及操作系统启动的准备。后者包括准备系统内存映射和配置信息,即加载、生成和发布ACPI表,修改这些表以反映平台的当前配置,对FDT进行类似的更改,以及检查和生成校验和。在此阶段加载的模块可以实现UEFI运行时服务(UEFI Runtime Services),这些功能可在运行时从操作系统调用。值得注意的是,在本文作者使用过的所有系统中,设备检测都是通过PCI-ECAM机制实现的。

完成此阶段后,启动设备选择(BDS)开始。在这个阶段通常使用一个单独的模块来处理“BootOrder”、“BootNext”和其他相关变量的值。通常,此模块实现(伪)图形用户界面。此时,基于x86的系统有许多共同点:使用相同的引导方法–PXE、iSCSI、块设备(如SATA/SAS/USB驱动器、SSD和NVME设备)等。

有必要提醒读者注意ARMv8 UEFI的外部设备(通常是PCIe设备)的驱动程序。它们可以以模块的形式实现,这些模块位于存储设备(FAT32文件系统)中,也可以直接驻留在设备中(可选ROM)。在某些情况下,将ARMv8添加到支持的体系结构列表中会给供应商带来问题。简单地重新编译ARMv8的源代码并不总是足够的,因为有些模块并没有设计成在完整的64位地址空间中工作。由于在ARMv8系统中广泛使用PCI总线到处理器地址的转换,反之亦然,也可能会出现困难。这是由于决定放弃位于内存地址空间低32位的旧“窗口”造成的。在支持增强方面,用EBC字节码编译的驱动程序可以提供所需的兼容性级别。然而,在撰写本文时,ARMv8的EBC解释器处于开发的早期阶段。

控制权转移到加载到内存中的模块(引导加载程序或直接进入操作系统内核)是根据UEFI规范执行的:模块的UEFI句柄在X0寄存器中,系统表指针在X1中,返回地址在X30(LR)中。

操作系统内核使用UEFI服务执行一些准备步骤,然后设置自己的转换表并调用UEFI方法ExitBootServices()和SetVirtualAddressMap()。这是必要的,因为UEFI代码在与操作系统内核相同的地址空间中执行。此外,定时器中断和任何可能的DMA传输都必须被禁用。armv8linux操作系统设计有一个值得注意的方面:主内核代码在EL1模式下执行,而EL2模式只保留给KVM管理程序代码的一部分。因此,在初始化期间,内核将其特权级别从EL2降到EL1。之后,只有运行时服务(所有UEFI服务的子集)可用于内核。如前所述,ARMv8上的Linux内核在ATF模块中实现时广泛使用PSCI接口。这尤其是多核系统的特点。接口本身和二级CPU核心初始化过程可以简单地描述为以PSCI函数号和初始化函数的入口点为参数发出SMC调用。事实上,对UEFI和SMC服务的调用是当前操作系统和固件之间交互的主要方式。有其他固件事件通知设施的规范草案,但到目前为止(2015年)还没有任何完成实施的报告。

总而言之,应该提到的是,本文没有详尽地描述基于ARMv8的固件组件的功能和交互。

基于ARMv8的固件系统体系结构的更多相关文章

  1. Android的系统体系结构

    目录: Android的系统体系结构 Android的四种常用组件 Activity的启动流程 Android的系统体系结构 在入门了一个简单的Android的Hello World以后,我们首先来看 ...

  2. 基于Web在线考试系统的设计与实现

    这是一个课程设计的文档,源码及文档数据库我都修改过了,貌似这里复制过来的时候图片不能贴出,下载地址:http://download.csdn.net/detail/sdksdk0/9361973   ...

  3. 基于s5pv210嵌入式linux系统sqlite3数据库移植

    基于s5pv210嵌入式linux系统sqlite3数据库移植 1.下载源码 http://www.sqlite.org/download.html 最新源码为3080100 2.解压 tar xvf ...

  4. 基于xml文件实现系统属性配置管理

    文章标题:基于xml文件实现系统属性配置管理 . 文章地址: http://blog.csdn.net/5iasp/article/details/11774501 作者: javaboy2012 E ...

  5. 基于Vue实现后台系统权限控制

    原文地址:http://refined-x.com/2017/08/29/基于Vue实现后台系统权限控制/,转载请注明出处. 用Vue/React这类双向绑定框架做后台系统再适合不过,后台系统相比普通 ...

  6. 基于 OS X Mavericks 系统

    基于 OS X Mavericks 系统远景论坛黑苹果区新手引导 常见疑难解答 以及必要知识普及帖 请善用论坛搜索功能 认真仔细地阅读置顶帖里的教程以及注意事项 前言:之前建立10.9区求助规范帖时, ...

  7. JS基础:基于原型的对象系统

    简介: 仅从设计模式的角度讲,如果我们想要创建一个对象,一种方法是先指定它的类型,然后通过这个类来创建对象,例如传统的面向对象编程语言 "C++"."Java" ...

  8. 基于jeesite的cms系统(一):开发环境搭建

    基于jeesite的cms系统系列,是对基于jeesite进行二次开发的博客模块开发过程的总结.涉及入门安装,二次开发,部署等 一.概况: JeeSite 是一个 Java 企业级快速开发平台,基于经 ...

  9. 在TensorFlow中基于lstm构建分词系统笔记

    在TensorFlow中基于lstm构建分词系统笔记(一) https://www.jianshu.com/p/ccb805b9f014 前言 我打算基于lstm构建一个分词系统,通过这个例子来学习下 ...

随机推荐

  1. hdu2363 枚举最短路

    (1) 二分     把所有的高度都拿过来,组合起来,sort一遍,然后二分,找到能连通的最小的那个,但这里存在一起情况,就是遇到高度差相等的时候会bug.... (2) 枚举 连通直接break   ...

  2. hdu4020简单想法题

    题意:       给你一些人,这些人有很多广告,每个广告有自己的点击率和长度,每次有m组询问,问每个人点击率前K名的广告的总长度是多少. 思路:       数据很大,很容易超时,总的想法还是先so ...

  3. hdu 1814 字典序最小的2sat(暴力深搜)

    题意:      题意就是最基础的2sat,关系只有矛盾关系,然后二选一,关键是这个题目是输出字典序最小的那组解. 思路:      输出字典序最小,用强连通那个实现不了(起码没看到有人实现),其实我 ...

  4. 基于frida框架Hook native中的函数(1)

    作者:H01mes撰写的这篇关于frida框架hook native函数的文章很不错,值得推荐和学习,也感谢原作者. 0x01 前言 关于android的hook以前一直用的xposed来hook j ...

  5. hdu3449 有依赖的背包问题

    题意:       给你一些物品,每个物品有自己的价值和花费,每个物品都对应一个箱子,每个箱子有价钱,买这个物品必须买相应的箱子,给你一个价钱,问最多可以获得多少价值 <提示:多个物品可能同时对 ...

  6. 关于PHP动态的接收传递的GET,POST和COOKIE变量

    0x01 我们知道 PHP 接收的变量最常用的是 GET,POST,COOKIE 这三个变量.GET变量是附在 url 后传输的,而 POST 变量是放在 http 包中传输的,COOKIE 则是浏览 ...

  7. Linux中su、sudo、sudo -i的用法和区别

    sudo :暂时切换到超级用户模式以执行超级用户权限,提示输入密码时该密码为当前用户的密码,而不是超级账户的密码.缺点是每次执行超级用户权限都要在命令前加上 sudo ,优点是在当前终端再使用 sud ...

  8. 【JavaScript】Leetcode每日一题-青蛙过河

    [JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...

  9. window 下如何安装redis

    1.官方没有 Windows版本的 Redis,但是微软开发并维护了针对Win64的Windows版本. Windows版本下载地址:https://github.com/MicrosoftArchi ...

  10. java面试一日一题:如何判断一个对象是否为垃圾对象

    问题:请讲下在java中如何判断一个对象是否为垃圾 分析:该问题主要考察对java中的垃圾回收,用什么方式去识别一个对象是垃圾: 回答要点: 主要从以下几点去考虑, 1.GC回收的是什么,回收发生在内 ...