7

我是一个新手,从微控制器编程开始。这里感兴趣的芯片是 cortex-a9。在重置或加电时,我的读数中必须有 0x0000000 处的代码。我的问题虽然听起来太微不足道,但会帮助我正确看待一些概念。

内存地址 0x0000000 是否驻留在 ROM 中?从该地址读取代码后会发生什么?是否应该存在某种引导加载程序?如果有,它应该在哪个地址?它是否也应该驻留在 ROM 中?最后,内核在什么时候启动以及内核代码驻留在哪里?

4

2 回答 2

9

ARM 销售的是内核而不是芯片,该地址中的内容取决于购买 ARM 内核并将其放入芯片的芯片供应商。实现方式因供应商、芯片与芯片而异。

传统上,ARM 将从地址零启动,更准确地说,复位异常向量位于地址零。与其他处理器系列不同,传统的 ARM 模型不是异常入口点的地址列表,而是 ARM 在该地址执行指令,这意味着您需要使用相对分支或加载 pc 指令。较新的 cortex-m 系列,仅是 thumb/thumb2(它们不能执行 ARM(32 位)指令)使用传统的(非 ARM)类似地址列表,零地址也不是异常向量,它是要加载堆栈指针的地址,然后重置第二个条目,依此类推。此外,cortex-m 异常列表不同,该系列有 128 个单独的中断,而传统的 ARM 有两个,快速和正常。最近有一个基于 cortex-m 的问题,或者可能被表述为在 thumb2 ARM 上运行 linux 的 thumb2 问题。我认为 cortex-m 实现都是微控制器类芯片,只有几十 kb 的片上内存,基本上这些不属于你所询问的类别。无论如何,您都在询问Cortex-a9。

许多内核或所有内核都有一个引导选项,其中引导地址可以是 0x00000000 或类似 0xFFFF0000 作为备用地址。使用它对于 ARM 用户来说会非常混乱,但它提供了例如在一个地址有一个 rom 并在另一个地址有一个 ram 的能力,允许您在启动时从 rom 启动,然后将异常表切换到 ram 以进行运行时操作。您可能有一个带有内核的芯片可以做到这一点,但是否使用这些核心功能的边缘或将它们硬连接到某些设置而不为您提供这种灵活性取决于芯片供应商。

您需要查看相关芯片的数据表/文档。找出 ARM 内核的名称是什么,正如您提到的 cortex-a9。理想情况下,您还想知道 rev 以及 r0p0 之类的东西,然后访问 ARM 的网站并找到该内核的 TRM 技术参考手册。您还需要获得一份 ARM ARM,ARM 架构参考手册。(传统的)ARM 异常向量在 ARM ARM 以及更多信息中进行了描述。您还需要芯片供应商的文档,并查看他们的引导方案。有些人会在开机时将地址 0 指向引导程序,然后引导加载程序需要做一些事情,在寄存器中翻转一个位,并且内存控制器会将地址 0 切换到 ram。有些地址 0 可能始终配置为 ram,而其他一些地址始终配置为 rom,例如,假设 0x80000000,芯片会在启动前将一些项目从 rom 复制到 ram,或者芯片可能只是将复位向量的上电设置设置为 rom 的分支,然后由引导加载程序决定修补向量表。尽可能多的不同方案,很可能有人已经尝试过了,所以你必须研究芯片供应商的文档或示例代码才能理解基本上你的 rom 问题的答案,这取决于你必须与芯片供应商。

内核的 ARM TRM 应描述内核上的带选项(如果有)(例如能够从备用地址引导),连接供应商实现的那些带选项(如果有)。ARM ARM 不会像 TRM 那样真正涉足这一领域。值得购买的供应商将拥有一些他们自己的文档和/或代码,以显示他们基于 rom 的引导策略是什么。

对于注定要成为 linux 系统的系统,您将拥有一个引导加载程序,一些非 linux 代码(非常类似于您的台式机/笔记本电脑上的 bios),它们会启动系统并最终启动 linux。Linux 将需要相当数量的内存(相对于微控制器和其他众所周知的 ARM 实现),该 ram 最终可能是 sram 或 dram,并且引导加载程序可能必须在启动 linux 之前初始化内存接口。有流行的引导加载程序,如 redboot 和 uboot。两者都是显着的矫枉过正,但为开发人员和用户提供功能,例如能够重新刷新 linux 等。

ARM linux 有 ATAGs(ARM TAGs)。您可以使用传统的 linux 命令行来告诉 linux 引导信息,例如找到根文件系统的地址和 ATAG。Atags 是内存中的结构,我认为当您从引导加载程序分支到 linux 时设置为 r0 或类似的东西。虽然一般概念是芯片上电,从 rom 或 ram 启动,如果准备好 ram 以便它可以使用,linux 可能希望/需要从 rom 复制到 ram,如果是单独的根文件系统,可能需要被复制到ram中的其他地方。如果需要,ATAGs 准备告诉 arm 在哪里解压 linux,以及在哪里可以找到命令行,或者在哪里可以找到诸如根文件系统之类的东西,

于 2011-07-17T17:36:59.500 回答
6

您必须在硬件开始执行的地址处提供可用的引导代码。

这通常是通过让硬件将某种闪存或引导 ROM 映射到引导地址并从那里开始运行来实现的。

请注意,在微控制器中,在启动时开始运行的代码的寿命相当长 - 尚未初始化任何硬件,并且没有硬件我的意思是即使是控制对 RAM 访问的 DDR 控制器也无法正常工作......所以你的代码需要在没有 RAM 的情况下运行。

在初始引导代码设置足够的硬件(例如设置 RAM 芯片、设置 TLB 等、编程 MAC 等)之后,您就可以运行引导加载程序。

在某些系统中,初始引导代码只是引导加载程序的第一部分。在某些系统中,专用的引导代码会设置好东西,然后从闪存读取引导加载程序并运行它。

引导加载程序的工作是将内核/操作系统的映像带入 RAM,通常来自闪存或网络(但也可以与另一块板、PCI 总线等共享内存,尽管这种情况比较少见)。一旦引导加载程序在 RAM 中获得内核/OS 二进制文件的映像,它可能会选择性地解压缩它,并移交控制(调用)内核/OS 映像的起始地址。

有时,内核/操作系统映像实际上是一个小型解压缩器和压缩内核的 blob。

无论如何,最终结果是内核/操作系统在 RAM 中可用,并且引导加载程序(可选地通过搭载解压缩器)已将控制权传递给它。

然后内核/操作系统开始运行并且操作系统启动。

于 2011-07-16T07:44:58.540 回答