【问题标题】:iMX6 get U-Boot to temporarily boot another U-BootiMX6 让 U-Boot 临时启动另一个 U-Boot
【发布时间】:2019-04-03 02:56:58
【问题描述】:

先介绍一下背景:

我们在基于 iMX6 的嵌入式系统中有以下设置。有两个 U-Boot 分区和两个系统 (Linux) 分区。目前我们只使用第一个 U-Boot 分区,它使用标准方法来选择、运行和(如果需要)回滚系统分区。

我们现在正在研究一种用于升级 U-Boot 本身的类似方案(这种情况很少发生,但我们确实希望能够做到这一点而不必将设备返回基地)。

但是,这更加危险,因为一旦您告诉 iMX6 设备从备用 U-Boot 分区启动,就是这样 - 如果启动失败,没有 U-Boot/看门狗组合会恢复到前一个分区,因此错误的更新会导致设备变砖的严重风险,直到我们可以将其送回基地进行维修(这是一个昂贵的选择,这就是我们试图尽可能减轻它的原因)。

选择的方法是一个两步 U-Boot 安装过程,包括“写入”和“激活”。它依赖于我们能够成功确定设备重新启动时将运行哪个 U-Boot 分区(选定的分区)以及当前正在运行的分区(已启动的分区)。我们已经解决了这个问题。

但我们缺少的是 UBoot 在某些情况下将控制权转移到 other UBoot 分区的能力。我们让它仅根据 UBoot 环境执行不同的操作,如下所示:

首先,mmcboot 添加了一个前缀,以便它检查控制传输,特别是设置为 run ub_xfer_chk ; <original content of mmcboot>

其次,我们有一个变量ub_xfer_flag,通常设置为0

第三,我们有检查函数ub_xfer_chk,定义为:

if test ${ub_xfer_flag} -eq 1 ; then
    echo Soft-booting other UBoot...
    setenv ub_xfer_flag 0
    saveenv
    weave_magic
fi

weave_magic 代码是我们遇到问题的地方 :-) 这个想法是这会将另一个 UBoot 分区加载到内存中(在我们的 CONFIS_SYS_TEXT_BASE0x1780000)并像实际设备一样执行它搞定了。

我们已经通过使用reset 代替weave_magic 测试了这个解决方案的实质,它成功地重新启动了一次设备,所以我们确信我们可以让它安全。


然后我的具体问题是:如何我可以说服 U-Boot 从另一个分区加载第二个副本并运行它?

两个 UBoot 分区位于可从系统分区访问的 /dev/mmcblk3boot0/dev/mmcblk3boot1 设备中,并且是 2M 文件,包括 1K 导入标头和末尾的一些填充。


更新:

我们实际上取得了一些成功,并设法使用以下命令从引导分区加载了 IMX 映像:

ext4load mmc ${mmcdev}:${mmcpart} 0x17800000 ${bootdir}/u-boot.imx

但是,当尝试执行它时:

go 0x17800000

我们收到一条非法指令并立即重新启动:

pc : [<17800070>]          lr : [<4ff83c64>]
sp : 4f579ac0  ip : 00000030     fp : 4f57be58
r10: 00000002  r9 : 4f579efc     r8 : 4ffbe2b0
r7 : 4f57be68  r6 : 17800000     r5 : fffff200  r4 : 000002cc
r3 : 17800000  r2 : 4f57be6c     r1 : 4f57be6c  r0 : 00000000
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

所以我猜那不是该文件开头的可执行代码。关于从这里去哪里的任何想法?

【问题讨论】:

  • 关于你的最后一个问题,你想找到图像的大小以便将其加载到内存中吗?如果您想了解启动 ROM 的详细信息,请查看参考手册的 System Boot -> Program image 部分。基本上,它定位 IVT 并从那里开始。如果您想要图像大小,请在 Boot Data 部分中找到它。
  • IMO 您需要重新评估您的系统和设计/开发实践。为什么 U-Boot 经常被“升级”?您是否正在用额外的功能重载 U-Boot?您是否了解过 U-Boot 加载和运行脚本和“独立程序”的能力?
  • Sawdust,这是四年来的第一次升级,更多地与设备设置本身有关。但是,例如,如果在 uboot 中发现需要修复的错误或安全问题,我们无论如何都希望能够做到这一点。这些系统的要求寿命为 30 年,对于 RTB 来说非常昂贵。

标签: embedded u-boot imx6


【解决方案1】:

IMX 文件中的实际代码 不在开头。您可以通过使用 excellent on-line disassemblerarmv5 big-endian no-thumb 架构来发现这一事实,以找出开头的字节经常给您无效和/或不太明智的代码:

ldtdmi  a1, [a1], -a2             ; <UNPREDICTABLE>
strne   a1, [a1, a1]
andeq   a1, a1, a1
ldrbne  pc, [pc, -ip, lsr #8]!    ; <UNPREDICTABLE>

在任何情况下,IMX 文件开头的数据都已知是头信息(开头的d1 是一个“神奇”标记,指示 IVT 头,之后还应该有一个 DCD 块. 然而,即使超出了 IVT 和 DCD 块(基于它们在标头字段中声称的长度),代码也是不合理的。

但是,在一大块 0x00 字节之后,偏移量 0xc00 处有可行的信息:

00000be0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000bf0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000c00: 0f00 00ea 14f0 9fe5 14f0 9fe5 14f0 9fe5  ................
00000c10: 14f0 9fe5 14f0 9fe5 14f0 9fe5 14f0 9fe5  ................

将偏移量 0xc00 处的十六进制字节放入反汇编程序,并针对被分支跳过的区域进行调整,显示有效的健全的 ARM 代码。

事实上,使用以下命令剥离 IMX 文件:

dd if=u-boot.imx bs=1 skip=3072 of=ub-at-c00.imx

应该给你一个可以用来启动的文件:

ext4load mmc ${mmcdev}:${mmcpart} 0x17800000 ${bootdir}/ub-at-c00.imx
go 0x17800000

当我们这样做时,它会输出:

U-Boot 2014.04 (Nov 07 2018 - 19:05:32)
CPU:   Freescale i.MX6Q rev1.5 at 792 MHz
CPU:   Temperature 32 C, calibration data: 0x5764e169
Reset cause: unknown reset
Board: DTI BRD0208 (Spitfire I) 05/01/2017
I2C:   ready
DRAM:  1 GiB

我们知道这是较新的 UBoot,因为我们使用的普通 UBoot 输出的是 10 月的日期而不是 11 月的日期。

不幸的是,它在那一点上挂起,看门狗计时器最终启动并重新启动回原来的 UBoot 但我怀疑这与 UBoot 不喜欢设备的当前状态有关(即,它不喜欢初始化两次)。

所以我们必须弄清楚如何说服它这样做,但至少我们已经让它启动了另一个自身的副本,这就是问题所在。

【讨论】:

    猜你喜欢
    • 2016-09-10
    • 1970-01-01
    • 2011-06-28
    • 2010-10-23
    • 2015-08-09
    • 1970-01-01
    • 2020-04-22
    • 2021-07-04
    • 2020-08-24
    相关资源
    最近更新 更多