-2

我目前正在尝试了解 AT91 和裸机应用程序如何协同工作。我将尝试描述我所拥有的:

  • IAR 作为开发环境
  • 一个简单的应用程序,我可以通过调试器将其下载到 SRAM 并切换一些 LED(工作!)
  • 使用 SAM-BA,我可以将此应用程序写入 SRAM,它会正确启动(LED 正在切换)
  • 我的硬件平台是 ATSAMA5D3x-EK

现在我希望这个应用程序首先运行 AT91 引导程序来初始化所有低级硬件(如 DDR-RAM),然后跳转到我的应用程序并运行它。我还没有成功地做到这一点。我可以启动预构建的 uboot 二进制文件,所以我认为不是复制或跳转失败,而是我的应用程序设置不正确。

据我了解,如果我跳转到一个应用程序(我假设这是某种“LDR pc,appstart_address”),地址 appstart_address 处的操作将被执行。

现在,在 ARM 中,前 7 个字节左右是为中止/中断向量保留的,而第一条指令通常是某种“LDR pc,=main”。如果我的应用程序被复制到 RAM 并从那里执行,这些是否需要?我不知何故有一种感觉,将我的应用程序复制到 RAM 后,地址指针不再匹配(尽管它们应该是相对的——这完全正确吗?)

所以我的问题基本上可以归结为:

  • AT91 初始化硬件并跳转到我的应用程序后会发生什么
  • 我需要以某种特定方式设置我的应用程序吗?我是否需要告诉链接器或任何其他组件它将被重新定位到其他内存位置(at91 引导程序将其复制到 0x2600 0000 而 0x2000 0000 是 DDR 的起始地址)。
  • 有谁知道一个很好的教程,它准确地解释了这一步(从 at91 引导程序跳转到我的应用程序)?

我可能可以回答自己的另一个问题:

  • 是否可以安全地假设我不需要在我的应用程序开始时执行 board_startup.s 中的指令,这些指令启用浮点单元,设置 sys 堆栈指针等等。我会说硬件本身已经由 AT91 Bootstrap 设置,因此不需要这样的设置。

考虑了几件事后,它归结为:

  • 告诉链接器它应该将 main 链接到地址 0x0 是否有意义(因为这是引导程序将跳转到的地方) - 我该怎么做?
4

1 回答 1

1

现在,在 ARM 中,前 7 个字节左右是为中止/中断向量保留的,而第一条指令通常是某种“LDR pc,=main”。如果我的应用程序被复制到 RAM 并从那里执行,这些是否需要?我不知何故有一种感觉,将我的应用程序复制到 RAM 后,地址指针不再匹配(尽管它们应该是相对的——这完全正确吗?)

前 8 个 WORDS 是异常入口点。其中一个是未定义的,所以 7 个真实的......

重置向量不想直接进入暗示 C 代码的主要内容,您还没有设置堆栈或调用 C 代码所需的任何操作。此外,重置向量通常足够接近以使用分支 b 而不是 ldr pc,但由于您只有一个单词/指令可以退出异常表,因此它需要是分支或 ldr pc 之类的。

如果您的二进制文件是位置相关的,那么您为该位置构建它,然后您可以将其放置在非易失性存储中,如果您愿意,可以复制并运行它没有问题。如果您为其非易失性地址构建它,但您在不同的地址空间中运行它并且它不是位置独立的,那么您是对的,它根本不会工作。

AT91 初始化硬件并跳转到我的应用程序后会发生什么

您的应用程序运行

我需要以某种特定方式设置我的应用程序吗?我是否需要告诉链接器或任何其他组件它将被重新定位到其他内存位置(at91 引导程序将其复制到 0x2600 0000 而 0x2000 0000 是 DDR 的起始地址)。

要么独立构建它,要么将其链接到它将运行的地址。

有谁知道一个很好的教程,它准确地解释了这一步(从 at91 引导程序跳转到我的应用程序)?

我假设当您说 at91 引导程序(需要使用更正确的术语)时,您的意思是特定于某些部分(at91 是一个长期存在的设备系列),您实际上是指某些特定于 atmel 部分的代码或特定于 IAR 部分的代码。您的问题的答案在他们的示例或文档中。在发布这样的问题之前,您需要展示您发现的内容、示例等。

是否可以安全地假设我不需要在我的应用程序开始时执行 board_startup.s 中的指令,这些指令启用浮点单元,设置 sys 堆栈指针等等。我会说硬件本身已经由 AT91 Bootstrap 设置,因此不需要这样的设置。

如果您依赖其他人的代码来设置 ddr,那么他们设置堆栈可能是一个安全的赌注。fpu,那是另一个故事。但是,如果该文件名特定于他们的项目并且是他们调用/使用的东西,那么他们调用它或使用它。同样,这是特定于这个神奇的 AT91 Bootstrap 的东西,你没有展示过你看过、通过或阅读过的东西。请对该主题进行更多研究,展示您尝试过的内容等。例如,在此引导代码之后读取启用 fpu 的寄存器或仅使用它并查看您所看到的内容应该很简单。这是判断它是否已运行的简单方法。或者在该代码中插入一个无限循环,如果代码在无限循环中挂起,则重新构建。他们正在运行它。

告诉链接器它应该将 main 链接到地址 0x0 是否有意义(因为这是引导程序将跳转到的地方) - 我该怎么做?

此处理器的异常表位于众所周知的位置(可能是两个位置之一,具体取决于捆绑)。异常处理程序需要位于正确的位置,处理器才能正确启动。通常是链接器进行代码的最终安排,并且链接器特定于您如何告诉链接器将东西放在哪里,因此答案在链接器的文档中,也可以在项目中的某个地方指定此信息(链接器脚本、makefile 等)或默认值用于全局默认值或某个变量或命令行选项告诉工具之一在哪里查找此信息。所以你怎么做就是阅读文档并按照文档所说的去做。

于 2014-03-20T01:04:35.213 回答