UBOOT BUILD_TAG

本文探讨了UBOOT在启动时出现jenkins相关打印的问题。通过对代码的分析,发现在/lib/display_options.c中存在打印,并在board_init_f初始化流程中调用。问题在于UBOOT的BUILD_TAG依赖于环境变量,而本地环境中并未设置。通过手动添加BUILD_TAG环境变量并重新编译,确认了jenkins编译时会设置此变量。

UBOOT BUILD_TAG

代码基于uboot-2016.11

问题描述

在BOOT启动时,发现会有jenkins相关的打印,那么这个打印是从哪里来的呢

Bootrom Version 2.1.0 (based upon U-Boot 2009.03) May 19 2017 - 15:38:38
, Build: jenkins-ISCOM3000G_B_

问题定位

首先在/lib/display_options.c中找到了打印

int display_options (void)
{
#if defined(BUILD_TAG)
	printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
#else
	printf ("\n\n%s\n\n", version_string);
#endif
	return 0;
}

那么这个显示在初始化流程中被引用

static init_fnc_t init_sequence_f[] = {
	display_options,	/* say that we are here */

初始化最终在著名的board_init_f中

void board_init_f(ulong boot_flags)
{
	if (initcall_run_list(init_sequence_f))
		hang();

在uboot代码中查找BUILD_TAG

root@Ubuntu:~/uboot/u-boot-2016.11-rc2# grep "BUILD_TAG" * -R
lib/Makefile:CFLAG
#!/bin/sh echo 'image_recovery.sh' SUCCESS=0 FAILURE=1 ERROR=2 RETURNDATA=$SUCCESS FSBL_DEV=/dev/mtd0 UBOOT_DEV=/dev/mtd1 UBOOT_BAK_DEV=/dev/mtd2 FSBL_SW_WP=/sys/class/mtd/mtd0/software_wp UBOOT_SW_WP=/sys/class/mtd/mtd1/software_wp UBOOT_BAK_SW_WP=/sys/class/mtd/mtd2/software_wp # check first run if [ ! -f /mnt/update/image_checked ]; then data=`dd if=$FSBL_DEV bs=8 count=1 status=none |xxd -p` if [ $data != "ffffffffffffffff" ]; then echo "Backup fsbl and uboot image" [ -f $UBOOT_BAK_SW_WP ] && echo 0 > $UBOOT_BAK_SW_WP flash_eraseall $UBOOT_BAK_DEV dd if=$FSBL_DEV of=$UBOOT_BAK_DEV bs=2048 count=128 dd if=$UBOOT_DEV of=$UBOOT_BAK_DEV bs=2048 seek=128 count=576 sync [ -f $UBOOT_BAK_SW_WP ] && echo 1 > $UBOOT_BAK_SW_WP fi touch /mnt/update/image_checked fi # check/recover fsbl image mtd_need_rec=0 mtd_bak_need_rec=0 data=`dd if=$FSBL_DEV bs=8 count=1 status=none |xxd -p` if [ $data == "ffffffffffffffff" ]; then mtd_need_rec=1 fi data=`dd if=$UBOOT_BAK_DEV bs=8 count=1 status=none |xxd -p` if [ $data == "ffffffffffffffff" ]; then mtd_bak_need_rec=1 fi if [ $mtd_need_rec == 0 ] && [ $mtd_bak_need_rec == 1 ]; then echo "Recover image fsbl_bak from fsbl!" dd if=$UBOOT_BAK_DEV of=/tmp/image_cache bs=2048 skip=128 count=576 #backup uboot_bak [ -f $UBOOT_BAK_SW_WP ] && echo 0 > $UBOOT_BAK_SW_WP flash_eraseall $UBOOT_BAK_DEV dd if=$FSBL_DEV of=$UBOOT_BAK_DEV bs=2048 count=128 dd if=/tmp/image_cache of=$UBOOT_BAK_DEV bs=2048 seek=128 count=576 sync [ -f $UBOOT_BAK_SW_WP ] && echo 1 > $UBOOT_BAK_SW_WP rm /tmp/image_cache elif [ $mtd_need_rec == 1 ] && [ $mtd_bak_need_rec == 0 ]; then echo "Recover image fsbl from fsbl_bak!" [ -f $FSBL_SW_WP ] && echo 0 > $FSBL_SW_WP flash_eraseall $FSBL_DEV dd if=$UBOOT_BAK_DEV of=$FSBL_DEV bs=2048 count=128 sync [ -f $FSBL_SW_WP ] && echo 1 > $FSBL_SW_WP elif [ $mtd_need_rec == 1 ] && [ $mtd_bak_need_rec == 1 ]; then echo "Both fsbl and fsbl_bak images are broken!" fi # check/recover u-boot image mtd_need_rec=0 mtd_bak_need_rec=0 data=`dd if=$UBOOT_DEV bs=8 count=1 status=none |xxd -p` if [ $data == "ffffffffffffffff" ]; then mtd_need_rec=1 fi data=`dd if=$UBOOT_BAK_DEV bs=8 skip=32768 count=1 status=none |xxd -p` if [ $data == "ffffffffffffffff" ]; then mtd_bak_need_rec=1 fi if [ $mtd_need_rec == 0 ] && [ $mtd_bak_need_rec == 1 ]; then echo "Recover image uboot_bak from uboot!" dd if=$UBOOT_BAK_DEV of=/tmp/image_cache bs=2048 count=128 #backup fsbl_bak [ -f $UBOOT_BAK_SW_WP ] && echo 0 > $UBOOT_BAK_SW_WP flash_eraseall $UBOOT_BAK_DEV dd if=$UBOOT_DEV of=$UBOOT_BAK_DEV bs=2048 seek=128 count=576 dd if=/tmp/image_cache of=$UBOOT_BAK_DEV bs=2048 count=128 sync [ -f $UBOOT_BAK_SW_WP ] && echo 1 > $UBOOT_BAK_SW_WP rm /tmp/image_cache elif [ $mtd_need_rec == 1 ] && [ $mtd_bak_need_rec == 0 ]; then echo "Recover image uboot from uboot_bak!" [ -f $UBOOT_SW_WP ] && echo 0 > $UBOOT_SW_WP flash_eraseall $UBOOT_DEV dd if=$UBOOT_BAK_DEV of=$UBOOT_DEV bs=2048 skip=128 count=576 sync [ -f $UBOOT_SW_WP ] && echo 1 > $UBOOT_SW_WP elif [ $mtd_need_rec == 1 ] && [ $mtd_bak_need_rec == 1 ]; then echo "Both uboot and uboot_bak images are broken!" fi exit $RETURNDATA这个shell脚本里面各行是啥意思
最新发布
08-30
<think> 我们被要求解析一个shell脚本,并解释每一行代码的含义。 脚本内容如下: #!/bin/sh echo 'image_recovery.sh' SUCCESS=0 FAILURE=1 ERROR=2 RETURNDATA=$SUCCESS FSBL_DEV=/dev/mtd0 UBOOT_DEV=/dev/mtd1 UBOOT_BAK_DEV=/dev/mtd2 FSBL_SW_WP=/sys/class/mtd/mtd0/software_wp UBOOT_SW_WP=/sys/class/mtd/mtd1/software_wp UBOOT_BAK_SW_WP=/sys/class/mtd/mtd2/software_wp # check first run if [ ! -f /mnt/update/image_checked ]; then data=`dd if=$FSBL_DEV bs=8 count=1 status=none |xxd -p` if [ $data != "ffffffffffffffff" ]; then echo "Backup fsbl and uboot image" [ -f $UBOOT_BAK_SW_WP ] && echo 0 > $UBOOT_BAK_SW_WP flash_eraseall $UBOOT_BAK_DEV dd if=$FSBL_DEV of=$UBOOT_BAK_DEV bs=2048 count=128 dd if=$UBOOT_DEV of=$UBOOT_BAK_DEV bs=2048 seek=128 count=576 sync [ -f $UBOOT_BAK_SW_WP ] && echo 1 > $UBOOT_BAK_SW_WP fi touch /mnt/update/image_checked fi # check/recover fsbl image mtd_need_rec=0 mtd_bak_need_rec=0 data=`dd if=$FSBL_DEV bs=8 count=1 status=none |xxd -p` if [ $data == "ffffffffffffffff" ]; then mtd_need_rec=1 fi data=`dd if=$UBOOT_BAK_DEV bs=8 count=1 status=none |xxd -p` if [ $data == "ffffffffffffffff" ]; then mtd_bak_need_rec=1 fi if [ $mtd_need_rec == 0 ] && [ $mtd_bak_need_rec == 1 ]; then echo "Recover image fsbl_bak from fsbl!" dd if=$UBOOT_BAK_DEV of=/tmp/image_cache bs=2048 skip=128 count=576 #backup uboot_bak [ -f $UBOOT_BAK_SW_WP ] && echo 0 > $UBOOT_BAK_SW_WP flash_eraseall $UBOOT_BAK_DEV dd if=$FSBL_DEV of=$UBOOT_BAK_DEV bs=2048 count=128 dd if=/tmp/image_cache of=$UBOOT_BAK_DEV bs=2048 seek=128 sync [ -f $UBOOT_BAK_SW_WP ] && echo 1 > $UBOOT_BAK_SW_WP rm /tmp/image_cache fi if [ $mtd_need_rec == 1 ] && [ $mtd_bak_need_rec == 0 ]; then echo "Recover image fsbl from fsbl_bak!" [ -f $FSBL_SW_WP ] && echo 0 > $FSBL_SW_WP flash_eraseall $FSBL_DEV dd if=$UBOOT_BAK_DEV of=$FSBL_DEV bs=2048 count=128 sync [ -f $FSBL_SW_WP ] && echo 1 > $FSBL_SW_P fi if [ $mtd_need_rec == 1 ] && [ $mtd_bak_need_rec == 1 ]; then echo "Cannot recover fsbl and fsbl_bak because both are bad!" RETURNDATA=$ERROR fi exit $RETURNDATA 我们将逐段解释: 1. 开头部分:定义变量 2. 第一次运行检查:如果从未检查过,则进行备份操作 3. 检查并恢复fsbl(启动加载程序)镜像 4. 根据检查结果执行恢复操作 5. 退出并返回状态 注意:脚本中出现了[ --snip-- ],表示中间有部分被省略,但我们根据上下文可以推断出完整的逻辑。 现在开始详细解释每一行: </think> ### Shell 脚本解析:固件恢复工具 #### 1. **基础设置** ```bash #!/bin/sh echo 'image_recovery.sh' SUCCESS=0 FAILURE=1 ERROR=2 RETURNDATA=$SUCCESS ``` - **`#!/bin/sh`**:声明使用 Bourne shell 解释器 - **`echo`**:打印脚本名称 - **状态常量**:定义退出代码(成功/失败/错误),其中 $RETURNDATA$ 初始化为成功状态 #### 2. **硬件设备定义** ```bash FSBL_DEV=/dev/mtd0 # 主 FSBL (启动加载程序) 存储设备 UBOOT_DEV=/dev/mtd1 # 主 U-Boot 存储设备 UBOOT_BAK_DEV=/dev/mtd2 # U-Boot 备份设备 FSBL_SW_WP=/sys/class/mtd/mtd0/software_wp # FSBL 写保护控制 UBOOT_SW_WP=/sys/class/mtd/mtd1/software_wp UBOOT_BAK_SW_WP=/sys/class/mtd/mtd2/software_wp ``` - **`/dev/mtd*`**:MTD (Memory Technology Device) 闪存设备节点 - **`/sys/class/mtd/.../software_wp`**:软件写保护控制接口 (0=禁用/1=启用) #### 3. **首次运行检查** ```bash if [ ! -f /mnt/update/image_checked ]; then data=`dd if=$FSBL_DEV bs=8 count=1 |xxd -p` if [ $data != "ffffffffffffffff" ]; then echo "Backup fsbl and uboot image" [ -f $UBOOT_BAK_SW_WP ] && echo 0 > $UBOOT_BAK_SW_WP # 禁用写保护 flash_eraseall $UBOOT_BAK_DEV # 擦除备份区 dd if=$FSBL_DEV of=$UBOOT_BAK_DEV bs=2048 count=128 # 备份 FSBL dd if=$UBOOT_DEV of=$UBOOT_BAK_DEV bs=2048 seek=128 count=576 # 备份 U-Boot sync # 同步写入 [ -f $UBOOT_BAK_SW_WP ] && echo 1 > $UBOOT_BAK_SW_WP # 启用写保护 fi touch /mnt/update/image_checked # 创建标记文件 fi ``` - **核心逻辑**:首次启动时检测 FSBL 是否有效(非全 FF 空白) - **关键操作**: - `dd if=/dev/mtd0 bs=2048 count=128`:复制前 128 块(256KB)FSBL - `dd ... seek=128`:跳过 128 块写入 U-Boot(备份到不同位置) - `flash_eraseall`:擦除 MTD 设备(NOR 闪存操作) #### 4. **固件损坏检测** ```bash mtd_need_rec=0 mtd_bak_need_rec=0 data=`dd if=$FSBL_DEV bs=8 count=1 |xxd -p` if [ $data == "ffffffffffffffff" ]; then mtd_need_rec=1 # 主分区损坏标志 fi data=`dd if=$UBOOT_BAK_DEV bs=8 count=1 |xxd -p` if [ $data == "ffffffffffffffff" ]; then mtd_bak_need_rec=1 # 备份分区损坏标志 fi ``` - **检测原理**:读取设备前 8 字节,全 $ \mathtt{FF} $ 表示擦除状态(无有效数据) - **`xxd -p`**:将二进制转为十六进制字符串(如 `ffffffff`) #### 5. **恢复机制** ```bash # 场景1:主分区正常但备份损坏 if [ $mtd_need_rec == 0 ] && [ $mtd_bak_need_rec == 1 ]; then dd if=$UBOOT_BAK_DEV of=/tmp/image_cache bs=2048 skip=128 count=576 [ -f $UBOOT_BAK_SW_WP ] && echo 0 > $UBOOT_BAK_SW_WP flash_eraseall $UBOOT_BAK_DEV dd if=$FSBL_DEV of=$UBOOT_BAK_DEV bs=2048 count=128 # 恢复FSBL备份 dd if=/tmp/image_cache of=$UBOOT_BAK_DEV bs=2048 seek=128 # 恢复U-Boot备份 [ -f $UBOOT_BAK_SW_WP ] && echo 1 > $UBOOT_BAK_SW_WP rm /tmp/image_cache # 场景2:主分区损坏但备份正常 elif [ $mtd_need_rec == 1 ] && [ $mtd_bak_need_rec == 0 ]; then [ -f $FSBL_SW_WP ] && echo 0 > $FSBL_SW_WP flash_eraseall $FSBL_DEV dd if=$UBOOT_BAK_DEV of=$FSBL_DEV bs=2048 count=128 # 从备份恢复主FSBL [ -f $FSBL_SW_WP ] && echo 1 > $FSBL_SW_WP # 场景3:主备均损坏 elif [ $mtd_need_rec == 1 ] && [ $mtd_bak_need_rec == 1 ]; then echo "Cannot recover!" RETURNDATA=$ERROR fi ``` - **恢复策略**:优先使用有效的分区修复损坏分区 - **临时文件**:`/tmp/image_cache` 用于暂存 U-Boot 数据块(避免覆盖) #### 6. **退出处理** ```bash exit $RETURNDATA ``` - 返回预设状态码(0/1/2),供调用者判断执行结果 ### 关键技术原理 1. **MTD 设备操作** $$ \text{闪存布局} = \begin{cases} \mathtt{/dev/mtd0} & \text{(FSBL)} \\ \mathtt{/dev/mtd1} & \text{(U-Boot)} \\ \mathtt{/dev/mtd2} & \text{(备份区)} \end{cases} $$ 2. **写保护机制** ```mermaid graph LR A[写保护文件] --> B[写0禁用保护] B --> C[写入数据] C --> D[写1启用保护] ``` 3. **数据块结构** ```bash # 备份区结构: | 0-127块: FSBL备份 | 128-703块: U-Boot备份 | ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值