30

我刚拿到我的 BeagleBoard-Xm,我想知道是否有详细的分步教程介绍如何在硬件上运行一个非常简单的裸机软件?

我问的原因是我想深入了解硬件架构是如何工作的,从引导加载程序、链接器、中断、异常、MMU 等一切。我认为最好的方法是让一个简单的 hello world 程序在 beagleboard xm 上执行而无需一个操作系统。没什么先进的,只需启动板并在屏幕上获得“hello world”输出。就是这样!

下一步是运行一个微型操作系统,它可以安排一些非常简单的任务。不需要文件系统,只需了解操作系统的基础知识。

4

2 回答 2

44

绝对没问题...

首先让串行端口启动并运行,我有一个较旧/较早的 beagleboards 并记住串行端口以及关于 I/O 的所有内容都是痛苦的,但是在其上安装一个串行端口以便您可以看到它启动。

我认为它会启动 uboot,您可以按一个键或 esc 或类似的东西来中断正常启动(进入 linux)。从 uboot 提示符很容易加载您的第一个简单程序。

我现在手头有一些 beagleboard 代码,但我的 beagleboard 本身没有方便尝试它们。因此,请访问http://sam7stuff.blogspot.com/了解如何为无 OS 嵌入式程序混合一些启动汇编程序和 C 代码(对于 arm,我有许多其他 thumb/cortex-m3 的示例平台,但那些启动略有不同)。

用于事物和内存地址空间的 sam7 端口与 beagleboard/omap 完全不同。以上是您可以更改或重新发明的框架。

您将需要 ti.com 提供的 OMAP 35x 技术参考手册。在他们的网站 OMAP3530 上搜索 omap 部分。

还有 beagleboard 文档。例如这个语句:

BeagleBoard 上提供了一个 RS232 端口,可访问 UART3 的 TX 和 RX 线

所以在 omap 的 trm 中搜索 UART3 显示它位于 0x49020000 的基地址。(通常很难找出某个东西的整个地址,因为手册通常在这里有一部分内存映射,另一部分在那里,在寄存器描述附近只有地址的低几位被调用。)

查看 uart 寄存器 THR_REG 是您写入要发送到 uart 的字节的位置,请注意它是一个 16 位寄存器。

知道了这一点,我们可以制作第一个程序:

.globl _start
_start:
    ldr r0,=0x49020000
    mov r1,#0x55
    strh r1,[r0]
    strh r1,[r0]
    strh r1,[r0]
    strh r1,[r0]
    strh r1,[r0]
hang: b hang

这是它的生成文件:

ARMGNU = arm-none-linux-gnueabi

AOPS = --warn --fatal-warnings
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 

uarttest.bin : uarttest.s
    $(ARMGNU)-as $(AOPS) uarttest.s -o uarttest.o
    $(ARMGNU)-ld -T rammap uarttest.o -o uarttest.elf
    $(ARMGNU)-objdump -D uarttest.elf > uarttest.list
    $(ARMGNU)-objcopy uarttest.elf -O srec uarttest.srec
    $(ARMGNU)-objcopy uarttest.elf -O binary uarttest.bin

以及使用的链接描述文件:

/* rammap */
MEMORY
{
    ram : ORIGIN = 0x80300000, LENGTH = 0x10000
}

SECTIONS
{
    .text : { *(.text*) } > ram
}

请注意,从 codesourcery 调用了 linux 版本,您不需要那个版本的 gnu 交叉编译器,实际上这个 asm 代码只需要一个汇编器和链接器(binutils 的东西)。arm-none-eabi-... 类型的交叉编译器也可以工作(假设您从 codesourcery 获得 lite 工具)。

一旦你有一个 .bin 文件,请查看 uboot 的帮助,我不记得确切的命令,但它可能是 l 0x80300000 或 load_xmodem 或类似的东西。基本上,您希望通过串行端口将 .bin 文件调制解调器 x 或 y 或 z 调制解调器到处理器的内存空间,然后使用 go 或任何命令告诉 uboot 分支到您的程序。

运行时,您应该会看到一些 U 字符(0x55 是“U”)从串行端口出来。

您的主要目标是建立一个简单的串行端口例程,以便您可以打印一些东西进行调试,或者查看您的程序在做什么。稍后您可以进入图形等,但首先使用串行端口。

发生了一些作弊行为。由于 uboot 启动并初始化了我们不需要的串行端口,只需将字节推入 thr。但很快你就会溢出 thr 的存储并丢失字节,所以你需要读取 omap 的 trm 并找到某种指示发送器为空的位,它已经发送了所有内容,然后创建一个 uart_send 类型的函数来轮询发送器空然后发送一个字节。

也忘了 printf(),你需要创建自己的打印数字(八进制或十六进制是最简单的),也许打印字符串。我整天整夜都在做这种工作,99% 的时间我使用的只是一个小例程,它在 uart 上打印 32 位十六进制数字。从我可以调试的数字中查看程序的状态。

所以采用 sam7 模型或类似的模型(注意编译器和链接器命令行选项很重要,链接命令行上的文件顺序也很重要,如果你想拥有第一条指令,第一个文件必须是你的入口点/ .bin 文件中的单词是您的入口点,这通常是一个好主意,因为您想知道如何控制它以从 rom 引导)。

您可以在不删除或替换 uboot 的情况下做很多事情,如果您开始查看基于 linux 的 uboot 引导命令,您会发现它正在将几乎 .bin 文件从闪存或某处复制到 ram 中的某个位置,然后分支到它。现在分支到 linux,esp arm linux 涉及一些 arm 表和可能设置一些寄存器,您的程序不会想要或不需要它。基本上,在您将程序复制到 ram 之后,您想使用的任何命令都是您将在 uboot 的启动脚本中编写的脚本,如果您选择让板子启动并像使用 linux 一样运行。

说您可以使用 jtag 而不是依赖 uboot 来工作,当您走这条路时,尽管在启动时可能需要做一些事情才能使芯片启动并运行,特别是配置 uart 可能是某个地方很少有时钟分频器,时钟使能,I/O 使能,诸如此类的各种事情。这就是为什么 sam7 示例以闪烁 LED 事物而不是 uart 事物开头的原因。amotek jtag-tiny 是一个很好的 jtag wiggler,我很高兴,每天在工作中整天使用这些。beagleboard 可能使用 TI 引脚而不是标准 ARM 引脚,因此您可能需要更改电缆。而且我不知道 OMAP 是否可以让您直接访问手臂抽头控制器,或者您是否必须做一些特定的事情。你最好暂时走 uboot 路线。

一旦你有了一个框架,你有少量的 asm 来设置堆栈并分支到你的入口点 C 代码,你就可以开始把那个 C 代码变成一个操作系统或者做任何你想做的事情。如果你查看 chibios 或 prex 或其他类似的东西,你会发现它们有小的 asm 引导代码,可以让它们进入他们的系统。同样,那里有 uart 调试和非调试例程。许多 rtose 会想要使用中断而不是轮询 thr 是否为空。

如果这篇文章没有让你开始使用你的 hello world(让你做一些工作),请告诉我,我会挖掘出我的 beagleboard 并创建一个完整的示例。我的电路板与您的电路板不完全匹配,但就 hello world 而言,它应该足够接近。

于 2011-07-29T14:34:48.480 回答
4

您也可以尝试 TI StarterWare:

http://www.ti.com/tool/starterware-sitara

于 2013-08-03T03:42:56.230 回答