从用户空间获取U-boot版本信息

19

有没有人知道如何从用户空间获取安装的U-boot版本?有一个fw_printenv命令可以访问U-boot的环境变量,但无法获取版本。

8个回答

23

如果U-boot位于mtd0中,您可以按如下方式获取版本信息:

root@SUPERWIFI:/proc# strings /dev/mtd0 | grep U-Boot    
U-Boot 1.1.4-g1c8343c8-dirty (Feb 28 2014 - 13:56:54)
U-Boot
Now running in RAM - U-Boot at: %08lx

我使用了类似的版本,扩展了grep以使其更精确,即“U-Boot [0-9].[0-9].\(Build.)”,以返回更少的结果。如果您大致知道u-boot映像位于闪存设备上的位置,则可以进行优化。如果您确定它在第一个兆字节中,您可以使用dd将前面的一兆字节数据吸出,然后再运行strings,以节省处理时间。 - synthesizerpatel
谢谢。使用dd来节省处理时间。 - SHI Shougang

4

这里是关于最新进展的更新。 在我们版本的U-Boot中,我们更改了 main.c 中 main_loop() 的代码为以下内容:

#ifdef CONFIG_VERSION_VARIABLE
    char *oldver=getenv("ver");
    if(oldver==0 ||strcmp(oldver,version_string))
    {
        setenv("ver", version_string);  /* set version variable */
        saveenv();
    }
#endif /* CONFIG_VERSION_VARIABLE */

因此,setenv/saveenv仅在更新需要时才会被调用。 在我们的固件中,我们添加了:

/sbin/fw_printenv -n ver > /var/config/u-boot.ver

发布u-boot版本供公众使用。


3

一种 替代方案 是直接从 u-boot 二进制文件中读取版本号(可以嵌入到包含其他二进制文件的镜像文件中,如第一阶段引导程序),使用 mmcblk0boot0 作为分区(设备为 mmcblk0)引导程序所在的位置:

sudo grep -a --null-data U-Boot /dev/mmcblk0boot0

注:这项工作不仅适用于Arch Linux,还适用于Ubuntu等操作系统。


2

没有明确定义的方法来做到这一点。一旦Linux启动,u-boot就不再运行,并且它的RAM被回收供Linux使用。Linux甚至不知道u-boot的存在,也不必通过u-boot启动。

如果你真的想这样做,唯一的方法是将u-boot版本添加到内核的命令行中,编写代码扫描闪存中的u-boot映像以获取其版本,或者执行更加复杂的操作。


如果没有明确定义的方法来做这件事,那么从您启动的闪存中提取数据的可靠方法是存在的。一个可靠的实现方式是将您的u-boot版本传递给内核(uboot=blah),然后读取/proc。如果您想确保您确切地知道您启动的版本,而不仅仅是闪存上的版本。 - synthesizerpatel
2
如果u-boot仍然是一个已挂载的分区,那么你可以使用strings从中提取此信息。也许不是标准的方法,但对于大多数人来说是可行的。 - Nimjox

1
在我的设备中,UBoot会自动创建一个名为“ver”的环境变量,其中包含其版本信息:
U-Boot > printenv
baudrate=115200
ethact=FEC ETHERNET
ethaddr=24-db-ad-00-00-08
bootdelay=3
bootcmd=bootm fc080000 - fc060000
bootargs=console=ttyCPM0,115200n8 rdinit=/sbin/init
stdin=serial
stdout=serial
stderr=serial
ver=U-Boot 2009.03-svn9684 (Mar 08 2010 - 17:08:32)

Environment size: 253/131068 bytes
U-Boot >

我不使用fw_printenv,但我会想象这个变量也会被传递。也许你的系统中已经有类似的东西了吗?

更新(2012年5月23日): 我在我的Linux镜像中添加了fw_printenv,并确认我确实看到了"ver"变量:

[root@ST600 /]# fw_printenv
baudrate=115200
ethact=FEC ETHERNET
ethaddr=24-db-ad-00-00-08
stdin=serial
stdout=serial
stderr=serial
ver=U-Boot 2009.03-svn9684 (Mar 11 2010 - 09:43:08)
bootcmd=bootm fc080000 - fc060000
bootdelay=3
bootargs=console=ttyCPM0,115200n8 rdinit=/sbin/init panic=10 mem=32m
[root@ST600 /]#

这个“很好地工作”,直到您更新U-Boot。在那之后,除非您更改某些环境变量并从U-Boot提示中说“保存”,否则您将以这种方式获取旧的U-Boot版本。这是因为fw_printenv提供对存储的环境的访问,而不是当前环境(新的U-Boot将放置其版本的环境)。解决方案是使您的U-Boot检查“ver”的存储和当前值是否不同,并在如此时重新刷新环境,但这也可能带来一些不良影响。 - Alexander Amelkin
您还需要确保使用CONFIG_VERSION_VARIABLE=y构建U-Boot,以便在环境中出现ver - remcycles

1

尝试使用以下方法读取uboot版本:

  1. 找到uboot分区,例如对于MTD设备:

    cat /proc/mtd

  2. 对于/dev/mtd5:

    cat /dev/mtd5 | hexdump -C -n 64


0
如果u-boot驻留在MTD分区中,则可以使用以下方法:
U_BOOT_VER=$(for part in `grep u-boot-[01] /proc/mtd | cut -f 1 -d ':'`; do strings /dev/${part} | grep "^U-Boot.*("; break; done)

0

如果你想知道u-boot版本,就不能依赖fw_printenv。

fw_printenv只是查找printenv分区并转储其数据。因此,对于普通变量来说它没问题,但对于“ver”变量来说不行,因为它是动态的,并且其值在u-boot启动时由u-boot初始化。这个变量的值在u-boot退出后不会保留,除非你手动将其保存到环境中。

例如,在我的板子上,如果我从u-boot提示符打印“ver”变量:

U-Boot >      printenv ver
ver=U-Boot 2009.11-00393-g5ca9497-dirty (Nov 26 2012 - 11:08:44)

这是来自u-boot本身的真正版本。

现在,如果我启动我的板子并使用fw_printenv:

el@board # fw_printenv | grep ver=
ver=U-Boot 2009.11-00323-gbcc6e0e (Sep 21 2012 - 11:07:19)

正如您所看到的,它是不同的。因为我在我的环境中定义了一个“ver”变量,它与真实的u-boot版本不匹配。

当然,我可以回到u-boot,使用“saveenv”来更新环境中的“ver”值。然后这两个值将匹配。但是,之后每次更改u-boot后都应该更新环境。

因此,我的结论是使用fw_printenv获取u-boot版本绝对不是一个好主意。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接