介绍 :
引导过程是任何 SoC 在复位解除后进行各种设备配置(调整位、设备安全设置、引导向量位置)和内存初始化(如 FLASH/SRAM/GRAM)的过程。在引导过程中,各种模块/外设(如时钟控制器或安全处理模块和其他主/从)根据 SoC 架构和客户应用进行初始化。在多核 SoC 中,首先主要核心(也称为引导核心)在引导过程中启动,然后辅助核心由软件启用。
引导过程从上电复位 (POR)开始,硬件复位逻辑强制 ARM 内核(Cortex M 系列)从片上引导 ROM 开始执行。引导 ROM 代码使用给定的引导选择选项以及各种 FUSE/straps 和 GPIO 设置的状态来确定 SOC 的引导流程行为。
什么是多核 SoC:
多核 SoC 有多个处理器,每个处理器都有自己的特定应用。
在网络/汽车应用等复杂 SoC 中,大多数行业 SoC 将主内核(启动内核)、应用程序/系统内核、网络内核集成在单个芯片上,以处理来自不同外设(主/从)的各种数据。主内核是任何处理启动和最大功能的 SoC 的核心,但对于大流量数据(以太网/TDM)和高频(CSI-2,QSPI)应用程序,我们需要有特定的应用程序内核,如 CORTEX-A 内核来处理数据.
图 1:多核 SoC 的架构
多核 SoC 的引导流程:
当设备获得 POR 时,主内核跳转到复位向量位置。复位向量是映射到 ROM 起始地址(也称为引导 ROM)的位置,内核将在 POR 后从此处开始执行。ARM 处理器(如 Cortex-M 系列)使用位于 0x00000000 的复位向量。该决定是通过配置输入信号做出的,因此在不同的 SoC 之间可能会有所不同。
一旦主核心(如 ARM Coretx-M)脱离复位,它将从内存地址位置 0x00000000 开始执行。主内核加载程序计数器并从地址 0xSP 开始执行(主内核堆栈指针,在 0xSP 位置的 ROM 内部,它将加载堆栈指针),这指示内核加载其重置处理程序(堆栈指针,向量表)和读取处理器Start Address(PSA)获取应用程序引导地址并跳转到该位置。
在PSA中,hex 文件或映像由引导加载程序加载。该地址可以是 SRAM/GRAM 或 FLASH。
CORE 将执行来自 PSA 的 Image/.hex,它可能会按照引导加载程序的指示加载到 SRAM/GRAM 或 FLASH。
将 Image/.hex 加载到内存(FLASH/SRAM/GRAM)中是由引导加载程序完成的。该加载程序可以内置在 BOOT ROM 中,也可以是外部加载程序。
在 SoC 验证中,hex 文件/图像是由 .c 文件(模式)通过编译器 -> 汇编程序 -> 链接器 ->.ELF->.HEX 生成的。
图 2:多核 SoC 中主核的启动顺序
主内核已经启动并准备好移除其余部分以重置其他外设以及辅助内核,因为默认情况下辅助内核被禁用,由软件启用。
一旦软件决定启用辅助内核,相应的寄存器(取决于 SoC 架构,启用辅助内核和时钟控制寄存器)需要使用主内核进行编程。一旦启用辅助内核,这将开始从复位中获取数据向量位置(这与主核的复位向量位置不同,主核的复位向量位置是 0x00000000,而次级核的复位向量位置可以是 0x00000004)。
实际上,辅助核心也从 0x00000000 启动,并且通过使用虚拟化概念(从 0x00000000 到 0x00000004 的内存映射)或总线探测概念,它必须将 0x00000000 地址映射到 0x00000004 并从该地址获取第一条指令。
现在辅助内核加载程序计数器并从地址 0xSP(辅助内核堆栈指针)开始执行,它指示内核加载其重置处理程序(堆栈指针、向量表)并读取 PSA 以获取应用程序引导地址并跳转到该位置。
图 3:多核 SoC 中辅助内核的启动顺序
图 4:启用多核
初级核心和次级核心有单独的 Image/.hex。Image/.hex 应该为所有核心存储不同的内存位置(即 GRAM/SRAM/FLASH)。这表明 PSA 对于所有内核都是不同的。此设置是 SoC 架构的一部分,由所有内核的链接器文件决定。例如,告诉 Image/.hex 文件地址和起始地址的链接器文件将是 PSA 。
例如:根据链接器文件生成的图像/十六进制开始和结束地址。
CORE1-0X3E800000-0X3E80FFFF
CORE2-0X3E810000-0X3E81FFFF
CORE3- …..
什么是引导加载程序:
根据 SoC 架构和实现,引导加载程序可以是引导 ROM 的一部分或在引导 ROM 之外。引导加载程序是根据 Fuse/straps 配置将图像/十六进制加载到内存中的程序。Boot loader 是一个程序,它具有所有外设和引导接口的数据结构。引导加载程序是高度特定于内核和电路板的。引导加载程序将在 POR 到 SoC 时执行。
Bootrom的职责:
执行必要的初始化,包括对 PLL、时钟、堆栈、中断设置、看门狗定时器等进行编程。
启用不同的一级缓存。
根据 Fuses/Straps 引脚值配置 I/O 元件和引脚多路复用。
将闪存控制器初始化为默认设置。
从闪存(NOR、NAND)、外部存储器、SD/MMC、USB 或 UART 加载用户代码。引导顺序和选项由保险丝/带针设置。
ROM 的特点包括:
支持从各种启动设备启动
串行下载器支持(USB、Flex CAN 和 UART 等)
主引导数据(初始接口的配置数据)
从低功耗模式唤醒
唤醒二级核心
Boot ROM 可以支持以下引导设备:
闪光
标清/多媒体卡
QuadSPI
串行 ROM 设备(通过 I2C 和 SPI 接口)
PCI/USB/UART等
重置向量表或重置处理程序:
处理器复位后,它将在异常向量表中的复位向量位置(地址 0x00000000)开始执行。
重置处理程序代码满足以下目的。
在多核架构中,将所有次核置于睡眠/禁用状态
异常向量的初始化
内存/缓存/TLB 初始化
堆栈和处理器模式寄存器初始化
对 IO 设备执行必要的初始化并启用中断
ARM M 系列内核的典型向量表:
引导顺序中的挑战和问题:
以下是与引导顺序相关的主要挑战和问题。
1. 核心之间的同步:在 SoC 设计中是否有启动时存在多少个核心的信息?哪个核心是初级核心?
如果所有内核同时退出复位状态,它们通常都从同一个复位向量开始执行。然后引导代码读取集群 ID 以确定哪个核心是主要核心。主要核心执行初始化,然后向次要核心发出一切准备就绪的信号。另一种方法是在主核进行初始化时将辅助核保持在复位状态。该方法需要硬件支持来协调复位。CP15: MPIDR Multiprocessor Affinity Register 提供了多核系统中的识别机制。
2. 堆栈设置问题:通常,在单核系统中,启动堆栈被初始化以跳转到BootROM。稍后,系统堆栈被初始化,整个系统都使用该堆栈。当支持多核系统时,一种方法可能是让每个内核重复临时和系统堆栈操作。然而,更好的方法是将一个主内核设置为所有内核的系统堆栈。这将减少辅助核心上的初始化代码。
3. 在地址零或复位向量处启动一个带有未初始化内存的处理器:
在复位时,处理器总是从地址为零的复位向量位置启动。
对于地址为零的未初始化内存(例如,未编程的闪存或未初始化的 GRAM/SRAM),处理器将从地址 0x0 读取虚假的初始主堆栈指针值,并从该地址读取虚假的代码入口点,可能包含非法指令集状态位 [0] 中的说明符(ESPR.T 位)。
处理器可能会立即锁定,或者可能会执行一些虚假的操作码,但在后一种情况下,锁定仍然是可能的结果。
4. 多个内核在同一复位向量共享同一引导 ROM:
多个核心在地址 0x0 处共享相同的引导 ROM 并不常见,因为这意味着多个核心将使用相同的初始主堆栈指针 (MSP) 地址启动,这将导致堆栈损坏(包括 NMI 或任何故障异常)。
在 SoC 的启动序列中处理挑战的战略方法:
为克服上述问题,必须相应地更新多核 SoC 中所有内核的链接器文件。每个内核都有单独的链接器。典型的链接器文件包含有关 Image/hex 中地址的信息,即要生成的 Hex/image 文件的起始地址和范围,还有堆栈相关信息。链接器文件设置取决于 SoC 架构。
ARM 链接器文件如下所示:
必须控制初级核心和次级核心的初始化顺序,以免堆栈损坏。因此,首先必须初始化主要核心(保持其他核心处于重置/暂停状态),而不是其他核心。
结论:
VLSI 芯片设计行业正朝着集成多个内核的单芯片中越来越复杂的设计迈进。多核启动顺序有助于理解,SoC 的实际工作方式以及 POR 断言后 SoC 唤醒的顺序是什么。在此paper,我们已经讨论了基于ARM的SoC中的多核启动顺序以及相关描述
引导 ROM、引导加载程序、使用链接器文件生成图像/十六进制、引导选项(从 SPI/SDIO/PCI 等不同设备引导)。还谈到了从各种存储器(SRAM/GRAM/FLASH)形成的多核引导。除此之外,还讨论了在初始级别的多核引导期间面临的挑战和面临的问题以及处理这些问题/挑战的方法。