【问题标题】:fw_printenv Not showing env variables from uboot.envfw_printenv 不显示来自 uboot.env 的环境变量
【发布时间】:2021-08-30 15:10:30
【问题描述】:

我正在开发 OrangePi Zero,试图让 fw_printenv 正常工作。到目前为止,我很茫然。提前感谢您提供的任何帮助。

在启动内核之前,我正在运行以下 u-boot 脚本:

fdt addr ${fdt_addr} && fdt get value bootargs /chosen bootargs

test -n "${BOOT_ORDER}" || setenv BOOT_ORDER "A B"
test -n "${BOOT_A_LEFT}" || setenv BOOT_A_LEFT 3
test -n "${BOOT_B_LEFT}" || setenv BOOT_B_LEFT 3
test -n "${BOOT_DEV}" || setenv BOOT_DEV "mmc 0:1"

setenv bootpart
setenv raucslot

for BOOT_SLOT in "${BOOT_ORDER}"; do
  if test "x${bootpart}" != "x"; then
    # skip remaining slots
  elif test "x${BOOT_SLOT}" = "xA"; then
    if test ${BOOT_A_LEFT} -gt 0; then
      setexpr BOOT_A_LEFT ${BOOT_A_LEFT} - 1
      echo "Found valid RAUC slot A"
      setenv bootpart "/dev/mmcblk0p2"
      setenv raucslot "A"
      setenv BOOT_DEV "mmc 0:2"
    fi
  elif test "x${BOOT_SLOT}" = "xB"; then
    if test ${BOOT_B_LEFT} -gt 0; then
      setexpr BOOT_B_LEFT ${BOOT_B_LEFT} - 1
      echo "Found valid RAUC slot B"
      setenv bootpart "/dev/mmcblk0p3"
      setenv raucslot "B"
      setenv BOOT_DEV "mmc 0:3"
    fi
  fi
done

setenv bootcmd_pxe ""

if test -n "${bootpart}"; then
  setenv bootargs console=${console} console=tty1 root=/dev/${rootdev} rootwait panic=10 ${extra}
  setenv bootargs "${bootargs} root=${bootpart} rauc.slot=${raucslot}"
  saveenv
else
  echo "No valid RAUC slot found. Resetting tries to 3"
  setenv BOOT_A_LEFT 3
  setenv BOOT_B_LEFT 3
  saveenv
  reset
fi

fatload mmc 0:1 ${kernel_addr_r} @@KERNEL_IMAGETYPE@@
if test ! -e mmc 0:1 uboot.env; then saveenv; fi;

load mmc 0:1 ${fdt_addr_r} ${fdtfile} || load mmc 0:1 ${fdt_addr_r} boot/${fdtfile}
load mmc 0:1 ${kernel_addr_r} zImage || load mmc 0:1 ${kernel_addr_r} boot/zImage || load mmc 0:1 ${kernel_addr_r} uImage || load mmc 0:1 ${kernel_addr_r} boot/uImage
bootz ${kernel_addr_r} - ${fdt_addr_r} || bootm ${kernel_addr_r} - ${fdt_addr_r}

此脚本运行似乎没有问题,并且它设置的环境变量保存到/boot/uboot.env。 /boot 分区是我设备上的 mmcblk0p1。我的 uboot.env 文件如下所示:

root@orange-pi-zero:~# cat /boot/uboot.env 
�5�`BOOT_A_LEFT=3OOT_B_LEFT=3BOOT_DEV=mmc 0:2BOOT_ORDER=A Barch=armbaudrate=115200board=sunxiboard_name=sunxiboot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}boot_efi_binary=if fdt addr ${fdt_addr_r}; then bootefi bootmgr ${fdt_addr_r};else bootefi bootmgr ${fdtcontroladdr};fi;load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootarm.efi; if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi ${kernel_addr_r} ${fdtcontroladdr};fiboot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}boot_net_usb_start=usb startboot_prefixes=/ /boot/boot_script_dhcp=boot.scr.uimgboot_scripts=boot.scr.uimg boot.scrboot_syslinux_conf=extlinux/extlinux.confboot_targets=fel mmc0 usb0 pxe dhcp bootargs=console=ttyS0,115200 console=tty1 root=/dev/ rootwait panic=10 root=/dev/mmcblk0p2 rauc.slot=Abootcmd=run distro_bootcmdbootcmd_dhcp=run boot_net_usb_start; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; setenv efi_old_vci ${bootp_vci};setenv efi_old_arch ${bootp_arch};setenv bootp_vci PXEClient:Arch:00010:UNDI:003000;setenv bootp_arch 0xa;if dhcp ${kernel_addr_r}; then tftpboot ${fdt_addr_r} dtb/${efi_fdtfile};if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r}; else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi;fi;setenv bootp_vci ${efi_old_vci};setenv bootp_arch ${efi_old_arch};setenv efi_fdtfile;setenv efi_old_arch;setenv efi_old_vci;bootcmd_fel=if test -n ${fel_booted} && test -n ${fel_scriptaddr}; then echo '(FEL boot)'; source ${fel_scriptaddr}; fibootcmd_mmc0=devnum=0; run mmc_bootbootcmd_pxe=bootcmd_usb0=devnum=0; run usb_bootbootdelay=2bootfstype=fatbootm_size=0xa000000bootpart=/dev/mmcblk0p2console=ttyS0,115200cpu=armv7devplist=1dfu_alt_info_ram=kernel ram 0x42000000 0x1000000;fdt ram 0x43000000 0x100000;ramdisk ram 0x43300000 0x4000000distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; doneefi_dtb_prefixes=/ /dtb/ /dtb/current/eth1addr=12:42:0f:ba:44:2eethaddr=02:42:0f:ba:44:2efdt_addr_r=0x43000000fdtcontroladdr=5bf59080fdtfile=sun8i-h2-plus-orangepi-zero.dtbfileaddr=43100000filesize=77ckernel_addr_r=0x42000000load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fimmc_bootdev=0partitions=name=loader1,start=8k,size=32k,uuid=${uuid_gpt_loader1};name=loader2,size=984k,uuid=${uuid_gpt_loader2};name=esp,size=128M,bootable,uuid=${uuid_gpt_esp};name=system,size=-,uuid=${uuid_gpt_system};preboot=usb startpxefile_addr_r=0x43200000ramdisk_addr_r=0x43300000raucslot=Ascan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done; setenv devplistscan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootarm.efi; then echo Found EFI removable media binary efi/boot/bootarm.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfilescan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; run boot_extlinux; echo SCRIPT FAILED: continuing...;��scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; donescriptaddr=0x43100000serial#=02c000420fba442esoc=sunxistderr=serialstdin=serial,usbkbdstdout=serialusb_boot=usb start; if usb dev ${devnum}; then devtype=usb; run scan_dev_for_boot_part; fiuuid_gpt_esp=c12a7328-f81f-11d2-ba4b-00a0c93ec93buuid_gpt_system=69dad710-2ce4-4e3c-b16c-21a1d49abed3

考虑到这一点,当我运行fw_printenv 时返回以下内容:

root@orange-pi-zero:~# fw_printenv
BOOT_A_LEFT=3

奇怪的是,似乎只输出了第一个变量。以下是 strace 的相关部分:

openat(AT_FDCWD, "/etc/fw_env.config", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=30, ...}) = 0
read(3, "/boot/uboot.env 0x0000 0x4000\n", 4096) = 30
lstat64("/boot", {st_mode=S_IFDIR|0755, st_size=16384, ...}) = 0
lstat64("/boot/uboot.env", {st_mode=S_IFREG|0755, st_size=131072, ...}) = 0
stat64("/boot/uboot.env", {st_mode=S_IFREG|0755, st_size=131072, ...}) = 0
openat(AT_FDCWD, "/boot/uboot.env", O_RDONLY) = 4
close(4)                                = 0
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/var/lock/fw_printenv.lock", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
flock(3, LOCK_EX)                       = 0
openat(AT_FDCWD, "/boot/uboot.env", O_RDONLY) = 4
read(4, "\3365\337`BOOT_A_LEFT=3\0\0OOT_B_LEFT=3\0"..., 16384) = 16384
close(4)                                = 0
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(0x4, 0x40), ...}) = 0
ioctl(1, TCGETS, {B115200 opost isig icanon echo ...}) = 0
write(1, "BOOT_A_LEFT=3\n", 14BOOT_A_LEFT=3
)         = 14
flock(3, LOCK_UN)                       = 0
close(3)                                = 0
exit_group(0)                           = ?

因此,基于该堆栈跟踪(并且因为它似乎读取了其中的第一个变量),它似乎可以毫无问题地找到我的 uboot.env 文件。至于为什么它似乎无法阅读其他的,我有点茫然。

【问题讨论】:

    标签: linux embedded-linux yocto u-boot


    【解决方案1】:

    uboot.env 文件似乎在 BOOT_A_LEFT=3 值之后包含双 NUL 终止:

    read(4, "\3365\337`BOOT_A_LEFT=3\0\0OOT_B_LEFT=3\0"..., 16384) = 16384
    

    我怀疑该文件可能已被覆盖一次或多次,并且您看到的是旧内容(奇怪的 OOT_B_LEFT 值及其后面的所有内容)和新内容(单个 BOOT_A_LEFT值)。

    catfw_printenv 的输出不同的原因是cat 将打印整个文件的内容,而fw_printenv 将在遇到双 NUL 终止后停止打印变量,这表明环境块结束。

    【讨论】:

    • 您指出的非常正确,我没有注意到!谢谢!一旦我将 fw_env.config 中的环境长度增加到适当的值,它似乎已经解决了
    【解决方案2】:

    所以,我确定了问题的症结所在。这似乎最终是由于在我的 fw_env.config 文件中使用了不正确的配置造成的。在我之前发布的内容中,它看起来如下:

    /boot/uboot.env 0x0000 0x4000

    但是,第二个值 (0x4000) 指的是环境的大小。就我而言,在 OrangePi Zero 上,我的环境是 0x20000。

    一旦我的 fw_env.config 如下所示,一切正常。

    /boot/uboot.env 0x0000 0x20000

    【讨论】:

      猜你喜欢
      • 2020-02-20
      • 1970-01-01
      • 2018-06-08
      • 2021-09-20
      • 2011-06-02
      • 2021-10-15
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多