【问题标题】:How can I boot bare metal from SD card on PocketBeagle?如何从 PocketBeagle 上的 SD 卡启动裸机?
【发布时间】:2018-01-25 00:07:19
【问题描述】:

我正在尝试做的事情:

我正在尝试将我的新 PocketBeagle 启动到一个普通的汇编程序中。

.equ GPIO_BANK1, 0x4804C000
.equ GPIO_OE, 0x134
.equ GPIO_USR_SETPIN0, 0x194
.equ GPIO_USR_PIN0, 0x13C

.globl _start

_start:
    ldr r0, =GPIO_BANK1 
    ldr r1, =GPIO_OE    @ Get the output enable register
    add r0, r1
    mov r1, #0          @ Set all of the GPIO1 Pins to output
    str r1, [r0]
_main:
    ldr r0, =GPIO_BANK1    
    ldr r1, =GPIO_USR_PIN0 @ Get the output register
    add r0, r1
    mov r1, #1
    lsl r1, #24
    str r1, [r0]           @ Set the USR LED to hi.
loop:
    ldr r2, =0x00010000
    sub r2, #1
    cmp r2, #0
    beq _main
    mov r1, #0
    str r1, [r0]
_hang:
    b _main

我使用下面的 makefile 编译这个文件

ARMGNU = arm-eabi

boot.bin: boot.asm
    $(ARMGNU)-as boot.asm -o boot.o
    $(ARMGNU)-ld -T linker.ld boot.o -o boot.elf
    $(ARMGNU)-objdump -D boot.elf > boot.list
    $(ARMGNU)-objcopy boot.elf -O srec boot.srec
    $(ARMGNU)-objcopy boot.elf -O binary boot.bin

根据the manual 第 26.1.6 节(SD 启动为 26.1.8.5),如果我将文件命名为 MLO,我可以从具有 FAT 文件系统的 SD 卡启动到此代码。现在,如果我在汇编代码中正确设置了寄存器,那么 PocketBeagle 上的 USR0、USR1、USR2 和 USR3 LED 应该会亮起。 (见此处USR to PIN Mappings)这是因为 GPIO1_21、22、23 和 24 引脚对应于这 4 个 LED,而这些引脚是我(试图)设置为高电平的引脚。

但是 LED 不亮。所以我做错了什么,但我无法弄清楚。

我的尝试:

关于 PocketBeagle 的在线文档很少。显然 PocketBeagle 在电气上应该与 BeagleBone Black 非常相似。

  • 我试过 TI StarterWare,它应该包含正常运行的二进制文件。我使用了 MLO 和一个示例程序,但没有成功。此外,我没有成功让项目自己编译。 Code Composer Studio 让我很沮丧。我曾尝试研究如何修复 CCS 的工具链,但不可否认,我对该主题的了解还不够,甚至不知道从哪里开始。
  • 我尝试了社区驱动的StarterWareFree。这不附带二进制文件,但是,就像上面一样,我无法编译,因为我的工具链不正常。
  • 我已经确定我的 PocketBeagle 仍然可以工作。我安装了 BeagleBone 社区建议的 linux 发行版,我在 USR0 LED 上得到了心跳。所以董事会工作。
  • 我尝试使用那个 Linux 的 MLO,但我无法在我使用的映像中找到 MLO...
  • 我尝试改用 GPIO_SETDATAOUT 寄存器;根据文档,它应该完成我在程序集中尝试做的同样的事情。 (手册第 25.4 节。)
  • 我通过验证 0xAA55 的存在确保开发板可以识别 FAT 文件系统 在 SD 卡的偏移 0x01FE 处(我使用 HxD 来执行此操作)。所以FAT MBR就在那里。 (第 26.1.8.5.7.1 节)

我在寻找什么:

一些方向。我从这里去哪里?我已经接受了这样一个事实,即我可能无法让 USR LED 闪烁。我认为该手册对我没有任何帮助,而且网络上也没有任何资源。我仍在学习嵌入式编程,并且我在 Arduino 和 Atmel Studio 方面取得了成功。我并不完全是新手,但非常感谢您的指导。

在哪里可以找到有关嵌入式系统引导的信息? 有没有我可以解决的类似的更简单的问题来帮助我理解?

对于stackoverflow,这可能是一个格式不正确的问题,但我对这个主题知之甚少。请指教。

上下文 - 什么是 PocketBeagle:

我链接到上面的 PocketBeagle 网站。对于那些不想离开的人,这里有一些信息。 它类似于 BeagleBoneBlack。它具有三个主要组件,一个微型 USB 端口、一个 SD 读卡器和 Octavo Systems OSD3358 1GHz ARM® Cortex-A8 片上系统。 OSD3358 包含 AM3358 TI 处理器;手册在上面。 PocketBeagle 的配置很方便,因此它可以从 SD 卡启动,而无需担心 SYSCONFIG 引脚。所以你可以把代码放在 SD 卡上,把它放在 PocketBeagle 中,它就会启动到那个代码中……希望如此。

【问题讨论】:

  • 可能是想在bootloader级别攻击它,可能是u-boot,找到bootloader使用的是哪个uart,通常你按一下键,停止,然后取决于那里的u-boot构建可能是一个负载,例如下载您的程序然后运行它。
  • 下一个(重新)-从源代码为这个目标构建 uboot,然后开始修改它。或基于此以及如何将其加载到卡或闪存中,然后将其替换为您的程序。但它可能不像只是向 gpio 写一点那么简单。

标签: assembly arm embedded beagleboard bare-metal


【解决方案1】:

经过一番挖掘,我意识到我的代码是准确的,但我忘记了一步。我需要在 GPIO1 总线输出信号之前打开 GPIO1 总线时钟。控制此时钟的寄存器可以在the manual 的第 8.1.12.1.29 节中看到。此外,我在TI Website 的论坛上发现了这一点。

我做了什么:

我放弃了从 FAT 文件系统启动的尝试,转而采用“原始模式”启动。请参阅手册的第 26.1.8.5.5 节。我最初避免使用这种方法是因为细节较少,但它最终更容易。

不过,这种方法有点棘手,因为我必须将原始字节写入 SD 卡。我使用HxD 来做到这一点。 在地址 0,我放了以下代码……这是手册第 26.1.10 节中描述的魔术代码。为方便阅读,请在十六进制编辑器中查看。

40 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00  @...............
00 00 00 00 43 48 53 45 54 54 49 4E 47 53 00 00  ....CHSETTINGS..
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
C1 C0 C0 C0 00 01 00 00 00 00 00 00 00 00 00 00  ÁÀÀÀ............
00 [0x50-0x1FF]...

那么在地址 0x200(512 字节)之前必须有零。 我将二进制代码放在地址 0x200 上,并添加了手册第 26.1.10.2 节中描述的 GP 标头。 GP Header 由 2 个字组成(每个字 4 个字节)。第一个字是“图像”(又名您的二进制文件)的大小,第二个字是 ROM 引导加载程序将放置您的代码的内存目标。 由于 AM335x 芯片的公共 RAM 从 0x402F0400 开始,我们希望将代码放在那里。 (手册第 26.1.4.2 节)。请记住,这是小端。我将 FF 放入我的图像大小,但实际上,它比我的图像大。

FF 00 00 00 00 04 2F 40

紧接着,我将编译后的汇编代码的二进制文件放在原始问题中。 (所以我的代码从 0x208 开始) 总之,从 0x200 开始,十六进制转储看起来像

FF 00 00 00 00 04 2F 40 50 00 9F E5 AC 10 A0 E3 
01 00 80 E0 02 10 A0 E3 00 10 80 E5 40 00 9F E5
4D 1F A0 E3 01 00 80 E0 00 10 A0 E3 00 10 80 E5 
2C 00 9F E5 4F 1F A0 E3 01 00 80 E0 00 10 E0 E3
00 10 80 E5 01 28 A0 E3 01 20 42 E2 00 00 52 E3 
F6 FF FF 0A 00 10 A0 E3 00 10 80 E5 F3 FF FF EA 
00 00 E0 44 00 C0 04 48 00 00 00 00 00 00 00 00

我的最终组装看起来像这样

.equ GPIO1, 0x4804C000
.equ GPIO_OE, 0x134
.equ CM_PER, 0x44E00000
.equ CM_PER_GPIO1_CLKCTRL, 0xAC
.equ GPIO_DATAOUT, 0x13C

.globl _start

_start:
    ldr r0, =CM_PER                @Clocks control register bus.
    ldr r1, =CM_PER_GPIO1_CLKCTRL  @Offset of the clock register for GPIO1
    add r0, r1
    mov r1, #2                     @Set the enable bit. Man 8.1.12.1.29
    str r1, [r0]
_led_enable:
    ldr r0, =GPIO1     @Register bank for GPIO1
    ldr r1, =GPIO_OE   @Register that controls output enable.
    add r0, r1
    mov r1, #0
    str r1, [r0]
_main:
    ldr r0, =GPIO1     
    ldr r1, =GPIO_DATAOUT  @Register than controls the output of GPIO1
    add r0, r1
    ldr r1, =0xFFFFFFFF
    str r1, [r0]
loop:
    ldr r2, =0x00010000     @The start of a loop that may or may not work.
    sub r2, #1              @I tried to make the USR LEDs blink, but I posted
    cmp r2, #0              @this before I tested it.
    beq _main
    mov r1, #0
    str r1, [r0]
_hang:
    b _main

我的 makefile 看起来和原来的问题一样。

【讨论】:

  • 你有这个保存在 github 或者类似的地方吗?
  • @old_timer 我愿意。我在 C here 中有一个版本。如果你真的想要你在这里看到的东西,你可以看看那个 repo 的第一次提交。此外,我写了一个关于此here 的要点。我必须预先警告;我仍在学习。 repo 和 Gist 主要作为“注释”。在撰写此评论时,它们还不是最干净的。如果您愿意,我会很乐意提供反馈、想法等。
  • 感谢您的启动github.com/dwelch67/pocket_beagle_samples 已隔离 LED,将查看原理图是否一致。 C 示例,闪烁...还有很多工作要做,包括自述文件
猜你喜欢
  • 2016-12-20
  • 2018-06-06
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-21
  • 2016-03-17
相关资源
最近更新 更多