You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何UBoot的boot.scr脚本中setenv与tftp命令无法正常工作?

U-Boot脚本boot.scr执行失败,ipaddr未生效问题排查

手动输入可正常执行的U-Boot命令

setenv ipaddr 192.168.0.199
setenv serverip 192.168.0.198
tftp 0x10000000 rpi3bp/image.bin
go 0x10000000

编译为boot.scr的脚本内容

echo ===== Saving RPi's IP Address =====
setenv ipaddr 192.168.0.199

echo ===== Saving Home TFTP server's IP Address =====
setenv serverip 192.168.0.198

echo ===== Loading file from Home TFTP server =====
tftp 0x10000000 rpi3bp/image.bin
echo ===== Running image =====
go 0x10000000

执行boot.scr时的错误输出

...
Found U-Boot script /boot.scr
359 bytes read in 2 ms (174.8 KiB/s)
## Executing script at 02400000
===== Saving RPis IP Address =====
setenv ipaddr 192.168.0.199

echo ===== Saving Home TFTP servers IP Address =====
===== Loading file from Home TFTP server =====
lan78xx_eth Waiting for PHY auto negotiation to complete........ done
*** ERROR: `ipaddr' not set
===== Running image =====
## Starting application at 0x10000000 ...
"Synchronous Abort" handler, esr 0x02000000
elr: ffffffffd4d27000 lr : 0000000000088cc0 (reloc)
elr: 0000000010000000 lr : 000000003b361cc0
x0 : 0000000000000001 x1 : 000000003af6a028
x2 : 000000003af6a028 x3 : 000000000000003f
x4 : 000000003af60df0 x5 : 0000000000000000
x6 : 0000000000000000 x7 : 0000000000c0c0c0
x8 : 0000000000000010 x9 : 0000000000000008
x10: 00000000ffffffd0 x11: 0000000000000010
x12: 0000000000000000 x13: 0000000000000200
x14: 000000003b3cc640 x15: 0000000000000001
x16: 0000000010000000 x17: 0fac920a292163a0
x18: 000000003af54db0 x19: 000000003af6a028
x20: 0000000010000000 x21: 0000000000000002
x22: 000000003af6a020 x23: 0000000000000002
x24: 000000003b3e567c x25: 0000000000000000
x26: 0000000000000000 x27: 0000000000000000
x28: 000000003af6a080 x29: 000000003af52ed0

Code: aaaaaaaa aaaaaaaa aaaaaaaa a2aaaaaa (55555555)

补充说明

已通过十六进制转储确认boot.scr使用Unix换行符(基于macOS环境):

❯ hexdump -C boot.scr
00000000  27 05 19 56 fc 01 13 df  63 d4 67 63 00 00 01 27  |'..V�..�c�gc...'|
00000010  00 00 00 00 00 00 00 00  a6 de 91 ea 05 02 06 01  |........��.�....|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000040  00 00 01 1f 00 00 00 00  0a 65 63 68 6f 20 3d 3d  |.........echo ==|
00000050  3d 3d 3d 20 53 61 76 69  6e 67 20 52 50 69 27 73  |=== Saving RPi's|
00000060  20 49 50 20 41 64 64 72  65 73 73 20 3d 3d 3d 3d  | IP Address ====|
00000070  3d 0a 73 65 74 65 6e 76  20 69 70 61 64 64 72 20  |=.setenv ipaddr |
00000080  31 39 32 2e 31 36 38 2e  30 2e 31 39 39 0a 0a 65  |192.168.0.199..e|
00000090  63 68 6f 20 3d 3d 3d 3d  3d 20 53 61 76 69 6e 67  |cho ===== Saving|
000000a0  20 48 6f 6d 65 20 54 46  54 50 20 73 65 72 76 65  | Home TFTP serve|
000000b0  72 27 73 20 49 50 20 41  64 64 72 65 73 73 20 3d  |r's IP Address =|
000000c0  3d 3d 3d 3d 0a 73 65 74  65 6e 76 20 73 65 72 76  |====.setenv serv|
000000d0  65 72 69 70 20 31 39 32  2e 31 36 38 2e 30 2e 31  |erip 192.168.0.1|
000000e0  39 38 0a 0a 65 63 68 6f  20 3d 3d 3d 3d 3d 20 4c  |98..echo ===== L|
000000f0  6f 61 64 69 6e 67 20 66  69 6c 65 20 66 72 6f 6d  |oading file from|
00000100  20 48 6f 6d 65 20 54 46  54 50 20 73 65 72 76 65  | Home TFTP serve|
00000110  72 20 3d 3d 3d 3d 3d 0a  74 66 74 70 20 30 78 31  |r =====.tftp 0x1|
00000120  30 30 30 30 30 30 30 20  72 70 69 33 62 70 2f 69  |0000000 rpi3bp/i|
00000130  6d 61 67 65 2e 62 69 6e  0a 0a 65 63 68 6f 20 3d  |mage.bin..echo =|
00000140  3d 3d 3d 3d 20 52 75 6e  6e 69 6e 67 20 69 6d 61  |==== Running ima|
00000150  67 65 20 3d 3d 3d 3d 3d  0a 67 6f 20 30 78 31 30  |ge =====.go 0x10|
00000160  30 30 30 30 30 30 0a                              |000000.|
00000167

问题原因

从错误输出可见,setenv ipaddr 192.168.0.199被直接打印而非执行,说明这条命令未被U-Boot解析为有效命令。

问题根源是echo命令参数中的未转义单引号:脚本中echo ===== Saving RPi's IP Address =====和echo ===== Saving Home TFTP server's IP Address =====两行里的RPi's、server's包含单引号',U-Boot脚本解析器会将单引号视为字符串分界符,导致echo命令参数被错误截断,后续的setenv命令被当成echo的输出内容,完全没有执行。

手动输入命令时,U-Boot命令行的解析逻辑与脚本模式不同,换行符会明确分割命令,因此不会触发该问题。

修复方法

修改脚本中包含单引号的echo命令,有两种可行方式:

  1. 用双引号包裹整个echo内容,避免单引号被解析为分界符:
echo "===== Saving RPi's IP Address ====="
setenv ipaddr 192.168.0.199

echo "===== Saving Home TFTP server's IP Address ====="
setenv serverip 192.168.0.198
  1. 转义单引号,在单引号前添加反斜杠\:
echo ===== Saving RPi\'s IP Address =====
setenv ipaddr 192.168.0.199

echo ===== Saving Home TFTP server\'s IP Address =====
setenv serverip 192.168.0.198

修改后重新用mkimage编译脚本为boot.scr即可正常执行。

关于boot.scr与手动命令的效果一致性

正常情况下,boot.scr的执行效果应当和手动输入命令完全一致,前提是脚本语法正确、无解析错误。出现差异的原因几乎都是脚本存在语法问题,或是U-Boot命令行解析与脚本解析的细微差异(如特殊字符处理),修正脚本语法后就能达到和手动输入相同的效果。


内容的提问来源于stack exchange,提问作者ptk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:15:40