您的位置:首页 > 新闻 > 资讯 > 微信如何自己创建公众号_网络营销策划是什么意思_福州网站建设_百度客服电话号码

微信如何自己创建公众号_网络营销策划是什么意思_福州网站建设_百度客服电话号码

2025/3/2 0:31:51 来源:https://blog.csdn.net/wenhao_ir/article/details/145902134  浏览:    关键词:微信如何自己创建公众号_网络营销策划是什么意思_福州网站建设_百度客服电话号码
微信如何自己创建公众号_网络营销策划是什么意思_福州网站建设_百度客服电话号码

前言

在 U-Boot 中,环境变量用于配置系统的启动参数和行为。是否能正确理解和设置u-boot中的环境变量是启动Linux系统的关键,所以有必要认真学习了解下各环境变量的意思和作用。

最好的学习材料就是实际的例子,所以本篇博文把我遇到过的各个u-boot的环境变量作个汇总,以便将来工作和学习时能进行参考。

如何查看当前u-boot的环境变量

输入下面的命令可查看当前u-boot的所有环境变量:

printenv

如何修改当前u-boot的某个环境变量的值

可以用setenv命令进行设置,示例如下:

setenv serverip 192.168.5.11

如何对修改后的环境变量进行保存

可以用下面的命令保存下当前的所有环境变量值,下次再运行u-boot时用的就是新的环境变量值。

saveenv

saveenv命令会将当前所有的环境变量值保存到U-Boot的环境存储中。这个命令会将内存中的环境变量(包括bootargs等设置)写入到U-Boot的存储介质(例如SPI Flash、eMMC、SD卡等)中,以便在设备重新启动时能够保留这些配置。

IMX6ULL_PRO开发板原装的u-boot的环境变量

u-boot启动后按任意键停止u-boot的自动启动进程,然后输入下面的命令查看其所有环境变量:

printenv

运行结果如下:

baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi
bootcmd_mfg=run mfgtool_args; if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; fi;
bootdelay=3
bootdir=/boot
bootscript=echo Running bootscript from mmc ...; source
console=ttymxc0
eth1addr=00:01:3f:2d:3e:4d
ethact=ethernet@020b4000
ethaddr=00:01:1f:2d:3e:4d
ethprime=eth1
fdt_addr=0x83000000
fdt_file=100ask_imx6ull-14x14.dtb
fdt_high=0xffffffff
fdtcontroladdr=9ef40478
findfdt=if test $fdt_file = undefined; then if test $board_name = EVK && test $board_rev = 9X9; then setenv fdt_file imx6ull-9x9-evk.dtb; fi; if test $board_name = EVK && test $board_rev = 14X14; then setenv fdt_file imx6ull-14x14-evk.dtb; fi; if test $fdt_file = undefined; then setenv fdt_file imx6ull-14x14-alpha.dtb; fi; fi;
image=zImage
initrd_addr=0x83800000
initrd_high=0xffffffff
ip_dyn=yes
loadaddr=0x80800000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
loadfdt=ext2load mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${bootdir}/${fdt_file}
loadimage=ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${bootdir}/${image}
loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file}
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" clk_ignore_unused 
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${tee} = yes; then run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
mmcdev=1
mmcpart=2
mmcroot=/dev/mmcblk1p2 rootwait rw
netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
netboot=echo Booting from net ...; run netargs; setenv get_cmd tftp; ${get_cmd} ${image}; ${get_cmd} ${fdt_addr} ${fdt_file};  bootz ${loadaddr} - ${fdt_addr};
panel=TFT43AB
script=boot.scr
tee=no
tee_addr=0x84000000
tee_file=uTee-6ullevkEnvironment size: 2661/8188 bytes

解释如下:

在 U-Boot 中,环境变量用于配置系统的启动参数和行为。以下是上面这些环境变量的解释:

  1. baudrate=115200:串口通信的波特率,U-Boot 将通过串口与主机进行通信,115200 是常见的串口波特率。

  2. board_name=EVK:板卡名称,在这个环境中是 EVK(评估板)。

  3. board_rev=14X14:板卡的版本号,指示当前硬件的版本。

  4. boot_fdt=try:是否尝试加载设备树(FDT,Flattened Device Tree)。设置为 try 表示如果设备树存在,尝试加载它。

  5. bootcmd=...:启动命令。它定义了在启动时 U-Boot 执行的一系列操作,包括查找设备树(findfdt)、加载脚本(loadbootscript)和启动操作(如从 MMC 或网络启动)。

  6. bootcmd_mfg=...:制造工具的启动命令,通常用于设备制造时的特殊启动过程。

  7. bootdelay=3:启动延时,表示 U-Boot 启动前的等待时间,单位是秒。

  8. bootdir=/boot:启动目录,指定从哪个目录加载启动文件,通常是 /boot

  9. bootscript=echo Running bootscript from mmc ...; source:定义启动脚本,执行脚本时将输出提示信息并从 MMC 加载脚本。

  10. console=ttymxc0:控制台设备,ttymxc0 表示使用该串口作为控制台。

  11. eth1addr=00:01:3f:2d:3e:4dethaddr=00:01:1f:2d:3e:4d:分别是网卡接口 eth1eth0 的 MAC 地址。

  12. ethact=ethernet@020b4000:激活的网络接口。表示 ethact 对应的硬件地址。

  13. ethprime=eth1:指定首选的网络接口(此处为 eth1)。

  14. fdt_addr=0x83000000:设备树文件的加载地址。

  15. fdt_file=100ask_imx6ull-14x14.dtb:设备树文件的名称。

  16. fdt_high=0xffffffff:设备树的高地址,通常用于 U-Boot 以确保在启动时使用正确的内存区域。

  17. fdtcontroladdr=9ef40478:指向设备树结构的地址。

  18. findfdt=...:查找设备树文件的命令。根据不同的硬件版本,选择合适的设备树文件。

  19. image=zImage:指定内核镜像文件名,这里是 zImage(压缩内核映像)。

  20. initrd_addr=0x83800000initrd_high=0xffffffff:初始化 RAM 磁盘(initrd)映像的加载地址和高地址。

  21. ip_dyn=yes:是否动态获取 IP 地址,yes 表示启用 DHCP。

  22. loadaddr=0x80800000:内核镜像加载的地址。

  23. loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script}:加载启动脚本的命令,fatload 用于从 MMC 卡加载文件。

  24. loadfdt=ext2load mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${bootdir}/${fdt_file}:从 MMC 加载设备树文件的命令。

  25. loadimage=ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${bootdir}/${image}:从 MMC 加载内核镜像的命令。

  26. loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file}:加载可信执行环境(TEE)映像的命令。

  27. mfgtool_args=...:制造工具相关的启动参数,通常与设备的生产相关。

  28. mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}:定义从 MMC 启动时传递给内核的启动参数。

  29. mmcautodetect=yes:是否自动检测 MMC 设备。

  30. mmcboot=...:从 MMC 启动的命令,包含加载内核和设备树、启动内核等操作。

  31. mmcdev=1:指定 MMC 设备编号,1 通常指代第二个 MMC 设备(设备编号从 0 开始)。

  32. mmcpart=2:指定 MMC 的分区号。

  33. mmcroot=/dev/mmcblk1p2 rootwait rw:指定根文件系统的位置,这里是 mmcblk1p2,并传递给内核启动时的参数。

  34. netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp:通过网络启动时的命令,包括 NFS 根文件系统的挂载和 DHCP 配置。

  35. netboot=...:通过网络启动的命令,首先从 DHCP 获取 IP 地址,然后通过 TFTP 下载内核镜像和设备树文件,并启动。

  36. panel=TFT43AB:显示面板的型号,TFT43AB 表示 4.3 英寸的 TFT 显示屏。

  37. script=boot.scr:启动脚本文件的名称。

  38. tee=no:是否启用可信执行环境(TEE)。设置为 no 表示不启用。

  39. tee_addr=0x84000000:TEE 映像的加载地址。

  40. tee_file=uTee-6ullevk:TEE 映像文件的名称。

总结:
这些环境变量主要配置了启动过程中的设备、文件系统、内核映像、设备树等参数。通过修改这些变量,用户可以定制启动行为,例如选择启动设备、设备树文件、内核镜像等。

FSL Yocto Project Community BSP提取出的u-boot的环境变量

具体这个u-boot的源码、修改、编译和运行见我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145662136

u-boot启动后按任意键停止u-boot的自动启动进程,然后输入下面的命令查看其所有环境变量:

printenv

在这里插入图片描述
打印的结果如下:

baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi
bootcmd_mfg=run mfgtool_args;if iminfo ${initrd_addr}; then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; fi; else echo "Run fastboot ..."; fastboot 0; fi;
bootdelay=3
bootscript=echo Running bootscript from mmc ...; source
console=ttymxc0
emmc_ack=1
emmc_dev=1
eth1addr=00:01:3f:2d:3e:4d
ethact=ethernet@20b4000
ethprime=eth1
fastboot_dev=mmc1
fdt_addr=0x83000000
fdt_file=undefined
fdt_high=0xffffffff
fdtcontroladdr=9df6d770
findfdt=if test $fdt_file = undefined; then if test $board_name = ULZ-EVK && test $board_rev = 14X14; then setenv fdt_file imx6ulz-14x14-evk.dtb; fi; if test $board_name = EVK && test $board_rev = 9X9; then setenv fdt_file imx6ull-9x9-evk.dtb; fi; if test $board_name = EVK && test $board_rev = 14X14; then setenv fdt_file imx6ull-14x14-evk.dtb; fi; if test $fdt_file = undefined; then echo WARNING: Could not determine dtb to use; fi; fi;
findtee=if test $tee_file = undefined; then if test $board_name = ULZ-EVK && test $board_rev = 14X14; then setenv tee_file uTee-6ulzevk; fi; if test $board_name = EVK && test $board_rev = 9X9; then setenv tee_file uTee-6ullevk; fi; if test $board_name = EVK && test $board_rev = 14X14; then setenv tee_file uTee-6ullevk; fi; if test $tee_file = undefined; then echo WARNING: Could not determine tee to use; fi; fi;
image=zImage
initrd_addr=0x86800000
initrd_high=0xffffffff
ip_dyn=yes
kboot=bootz 
loadaddr=0x80800000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file}
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc clk_ignore_unused 
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${tee} = yes; then run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
mmcdev=1
mmcpart=1
mmcroot=/dev/mmcblk1p2 rootwait rw
netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
netboot=echo Booting from net ...; ${usb_net_cmd}; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${tee} = yes; then ${get_cmd} ${tee_addr} ${tee_file}; ${get_cmd} ${fdt_addr} ${fdt_file}; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
script=boot.scr
sd_dev=1
serial#=2e1181d769237caa
splashimage=0x8c000000
tee=no
tee_addr=0x84000000
tee_file=undefinedEnvironment size: 3388/8188 bytes

这些打印出的环境变量的大概解释

在U-Boot中,printenv命令列出了环境变量的当前设置。每个环境变量用于配置系统的启动参数、设备设置等。以下是这些环境变量的解释:

  1. baudrate=115200

    • 设置U-Boot的串口通信波特率为115200。
  2. board_name=EVK

    • 设定开发板的名称为EVK(Evaluation Kit)。
  3. board_rev=14X14

    • 设置开发板的硬件版本为14X14。
  4. boot_fdt=try

    • 设置U-Boot启动时是否尝试加载设备树文件。如果为try,表示尝试加载设备树文件,若加载失败则继续启动。
  5. bootcmd=run findfdt; run findtee; mmc dev ${mmcdev}; mmc dev ${mmcdev}; if mmc rescan; then ...

    • bootcmd是启动时执行的命令。此命令定义了启动顺序,包括:
      1. 寻找设备树文件(findfdt)。
      2. 寻找TEE(可信执行环境,findtee)。
      3. 启动SD卡(mmc dev)。
      4. 如果SD卡存在且能被扫描到,加载启动脚本、内核镜像,设备树等。
  6. bootcmd_mfg=run mfgtool_args;if iminfo ${initrd_addr}; then ...

    • 这是制造商工具模式下的启动命令。它在启动时加载初始化内核镜像和设备树文件,或在失败时进入fastboot模式。
  7. bootdelay=3

    • 启动延迟为3秒,在启动时等待的时间。
  8. bootscript=echo Running bootscript from mmc ...; source

    • 启动脚本,它会在启动时执行脚本(通常用于自动化启动流程)。
  9. console=ttymxc0

    • 设置控制台输出的设备为ttymxc0,通常指的是串口0。
  10. emmc_ack=1

  • 启用eMMC设备确认。
  1. emmc_dev=1
  • 设置eMMC设备的编号为1。
  1. eth1addr=00:01:3f:2d:3e:4d
  • 设置以太网接口1的MAC地址。
  1. ethact=ethernet@20b4000
  • 设置当前活动的以太网控制器为ethernet@20b4000
  1. ethprime=eth1
  • 设置以太网设备的首选接口为eth1
  1. fastboot_dev=mmc1
  • 设置fastboot模式下的设备为mmc1,通常是SD卡或eMMC。
  1. fdt_addr=0x83000000
  • 设置设备树文件加载的内存地址为0x83000000
  1. fdt_file=undefined
  • 设备树文件未设置,通常在找不到设备树文件时会用undefined表示。
  1. fdt_high=0xffffffff
  • 设置设备树加载的内存上限地址为0xffffffff,指示内核可以使用的最大内存地址。
  1. fdtcontroladdr=9df6d770
  • 设备树控制地址,通常用于指向设备树的内存地址。
  1. findfdt=if test $fdt_file = undefined; then ...
  • 寻找设备树文件的脚本,根据不同的开发板名称和版本选择合适的设备树文件。
  1. findtee=if test $tee_file = undefined; then ...
  • 寻找TEE文件的脚本,确保选择合适的可信执行环境文件。
  1. image=zImage
  • 设置内核镜像文件名为zImage
  1. initrd_addr=0x86800000
  • 设置初始化内存盘(initrd)的加载地址为0x86800000
  1. initrd_high=0xffffffff
  • 设置内存盘的高地址为0xffffffff,即指示内核加载initrd时使用的内存范围。
  1. ip_dyn=yes
  • 启用动态IP分配(通过DHCP)。
  1. kboot=bootz
  • 设置内核启动命令为bootz,通常用于启动压缩内核(zImage)。
  1. loadaddr=0x80800000
  • 设置内核镜像、设备树、脚本等文件的加载地址为0x80800000
  1. loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script}
  • 加载启动脚本的命令,从MMC卡中加载脚本文件(通常是boot.scr)。
  1. loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
  • 从MMC卡加载设备树文件。
  1. loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
  • 从MMC卡加载内核镜像。
  1. loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file}
  • 从MMC卡加载TEE镜像。
  1. mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc clk_ignore_unused
  • 设置在制造商工具模式下的启动参数。
  1. mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
  • 设置从MMC启动时的内核启动参数,包括控制台设置和根文件系统位置。
  1. mmcautodetect=yes
  • 启用MMC自动检测。
  1. mmcboot=echo Booting from mmc ...; run mmcargs; ...
  • 从MMC卡启动的命令,包括加载内核、设备树和TEE等。
  1. mmcdev=1
  • 设置MMC设备为1(通常指SD卡或eMMC设备)。
  1. mmcpart=1
  • 设置MMC分区为1。
  1. mmcroot=/dev/mmcblk1p2 rootwait rw
  • 设置根文件系统的位置为/dev/mmcblk1p2,并指定rootwait(等待根文件系统)和rw(以读写模式挂载)。
  1. netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
  • 设置网络启动时的启动参数,包括NFS根文件系统和DHCP。
  1. netboot=echo Booting from net ...; ${usb_net_cmd}; run netargs; ...
  • 从网络启动的命令,包括加载内核镜像、设备树等。
  1. script=boot.scr
  • 启动脚本文件的名称,通常是boot.scr
  1. sd_dev=1
  • 设置SD卡设备为1。
  1. serial#=2e1181d769237caa
  • 设置设备的唯一序列号。
  1. splashimage=0x8c000000
  • 设置启动时显示的Splash屏幕图像的地址。
  1. tee=no
  • 禁用TEE(可信执行环境)。
  1. tee_addr=0x84000000
  • 设置TEE镜像的加载地址为0x84000000
  1. tee_file=undefined
  • TEE文件未定义。

这些环境变量控制了U-Boot的各种设置和启动行为,确保系统按照预定的方式启动,加载正确的内核、设备树、文件系统等。如果你需要更改某些启动参数,可以通过修改这些变量来调整启动流程。

环境变量bootcmd的详细介绍

请详细解释参数bootcmd

bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi

bootcmd 是 U-Boot 启动时执行的主要命令,它定义了启动的逻辑流程。你提供的 bootcmd 命令非常复杂,包含了多个步骤。下面是对每个部分的详细解释:

bootcmd 参数解释:

bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi
  1. run findfdt; run findtee;
run findfdt
run findtee
  • findfdtfindtee 是两个自定义的环境变量,它们分别用于寻找设备树文件(FDT,Flattened Device Tree)和 TEE(可信执行环境)文件。
  • findfdt 会根据板子的名称和版本选择对应的设备树文件,并设置 fdt_file 环境变量。
  • findtee 会设置 tee_file 环境变量,选择适当的可信执行环境(TEE)镜像文件。
  • 这些命令帮助 U-Boot 在启动时加载正确的配置文件。
  1. mmc dev ${mmcdev}; mmc dev ${mmcdev};
mmc dev ${mmcdev}
mmc dev ${mmcdev}
  • mmc dev 是 U-Boot 中用于选择当前活动的 MMC 设备的命令。这里的 ${mmcdev} 是一个变量,表示 MMC 设备的编号。
  • 这行命令做了两次 mmc dev ${mmcdev},这通常用于确保所选的 MMC 设备被正确初始化并切换为当前设备。
  • 一般来说,mmcdev 会被设置为一个值(如 1),表示设备号,通常指的是 SD 卡或 eMMC 存储设备。
  1. if mmc rescan; then ... fi;
if mmc rescan; then ...
  • mmc rescan 是一个命令,用于重新扫描 MMC 卡。如果 MMC 卡没有正确初始化或有新的卡插入,可以使用该命令来检测并重新扫描卡。
  • 这个 if 语句检查 MMC 卡是否成功扫描并连接。如果成功(即 mmc rescan 返回 true),则进入 then 分支,继续执行后面的命令。
  1. if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi;
if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi;
  • 这个部分根据条件判断来决定启动的方式,分为以下几步:

    1. run loadbootscript:

      • 尝试加载启动脚本(通常是 boot.scr 文件)。loadbootscript 是一个自定义命令,定义了如何从 MMC 卡加载脚本文件。
      • 如果加载成功,则执行 run bootscript,即运行实际的启动脚本,通常包含一些初始化步骤。
    2. else if run loadimage:

      • 如果加载启动脚本失败,则尝试加载内核镜像文件。loadimage 是自定义命令,用于加载内核镜像(通常是 zImageuImage)。
      • 如果加载成功,则执行 run mmcboot,即使用 MMC 启动内核,启动系统。
    3. else run netboot:

      • 如果无法加载启动脚本或内核镜像,则尝试通过网络启动(netboot)。netboot 是自定义命令,用于通过网络从 TFTP 或其他协议加载镜像并启动。
  1. else run netboot; fi
else run netboot; fi
  • 如果 mmc rescan 失败(即没有检测到 MMC 卡),则直接跳到 run netboot,通过网络启动系统。

总结:
这个 bootcmd 定义了一个灵活的启动流程,确保在不同情况下都能找到合适的启动方式。具体流程如下:

  1. 先尝试查找并设置设备树文件和 TEE 文件。
  2. 然后检查 MMC 设备(SD 卡或 eMMC)是否正确连接并扫描。
  3. 如果扫描成功,首先尝试加载启动脚本,若失败则尝试加载内核镜像并从 MMC 启动。如果这些都失败,则通过网络启动。
  4. 如果 MMC 设备没有正确连接或无法扫描,则通过网络启动。

这个流程确保了系统能够在不同的硬件环境下灵活地找到启动方式,保证启动的可用性。

手动方式实现网络启动的分析

在上面对环境变量bootcmd的分析中,我们知道,当u-boot自动进行Linux系统的启动时,如果u-boot没有能从MMC设备启动内核,那么它会从网络进行启动。

我们在进行内核和设备树开发时,也常常用网络的方式启动内核,因为这样很方便嘛,不用去进行烧写操作,不过此时我们常常用手动的方式实现内核的网络启动。
比如我在下面这篇博文对设备树、内核、根文件系统进行移植时就需要用手动的方式实现内核的网络启动:
https://blog.csdn.net/wenhao_ir/article/details/145822475

在实际研发中,我们通常会按任意键让u-boot的自动启动停下来,如下图所示:
在这里插入图片描述
然后我们可以手动执行下面这条命令让u-boot以网络方式启动内核。

run netboot

接下来,我们就根据这些环境变量来分析一下这条命令执行后的运行过程。

从命令printenv的结果来看,netboot是一个环境变量,其内容如下:

netboot=echo Booting from net ...; ${usb_net_cmd}; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${tee} = yes; then ${get_cmd} ${tee_addr} ${tee_file}; ${get_cmd} ${fdt_addr} ${fdt_file}; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;

其解释如下 :

环境变量netboot的详细分析

netboot 参数定义了如何通过网络启动(即通过 TFTP 或 NFS 等协议)。该命令使用了条件判断、环境变量和一些 U-Boot 提供的命令来实现灵活的网络启动过程。下面是对该命令的详细解析:

netboot 参数解释:

netboot=echo Booting from net ...; ${usb_net_cmd}; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${tee} = yes; then ${get_cmd} ${tee_addr} ${tee_file}; ${get_cmd} ${fdt_addr} ${fdt_file}; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
  1. echo Booting from net ...;
echo Booting from net ...
  • 在启动过程中,这个命令输出一条信息,提示系统正在通过网络启动。echo 是一个简单的命令,用来显示文本。
  1. ${usb_net_cmd};
${usb_net_cmd}
  • 这里执行了一个环境变量 ${usb_net_cmd}。这个变量通常包含与 USB 网络设备(如 USB Ethernet 适配器)相关的命令,确保网络设备正确初始化。如果系统通过 USB 以太网适配器连接网络,它会执行这些命令来配置网络连接。
  1. run netargs;
run netargs
  • 这个命令会运行 netargs 环境变量中的命令,通常是设置网络启动所需的启动参数。例如,netargs 可能包含设置 bootargs(启动参数)的命令,如动态分配 IP 地址(DHCP)等。 bootargs这个参数很重要,详细的分析见下文【搜索关键词“事关重要的环境变量”】。
  1. if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi;
if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi;
  • ip_dyn 是一个环境变量,表示是否启用动态 IP 地址分配(通过 DHCP)。
    • 如果 ip_dynyes,则使用 DHCP 获取 IP 地址。在这种情况下,get_cmd 环境变量被设置为 dhcp,表示 U-Boot 使用 DHCP 协议获取网络配置。
    • 如果 ip_dynno,则使用 TFTP 来加载内核镜像、设备树等文件。此时,get_cmd 被设置为 tftp
  1. ${get_cmd} ${image};
${get_cmd} ${image}
  • 这里使用了 ${get_cmd},它的值要么是 dhcp,要么是 tftp,取决于之前的判断。
  • ${image} 是内核镜像的名称(通常是 zImageuImage)。
  • 如果 get_cmddhcp,系统会首先通过 DHCP 获取 IP 地址。
  • 如果 get_cmdtftp,系统会通过 TFTP 协议从网络服务器下载内核镜像。get_cmd 实际上指示了如何获取内核镜像。
  1. if test ${tee} = yes; then ${get_cmd} ${tee_addr} ${tee_file}; ${get_cmd} ${fdt_addr} ${fdt_file}; bootm ${tee_addr} - ${fdt_addr};
if test ${tee} = yes; then ${get_cmd} ${tee_addr} ${tee_file};${get_cmd} ${fdt_addr} ${fdt_file};bootm ${tee_addr} - ${fdt_addr};
  • tee 是一个环境变量,表示是否启用 TEE(可信执行环境)。如果 teeyes,则:
    • get_cmd ${tee_addr} ${tee_file} 会从网络获取 TEE 文件,tee_addr 是加载地址,tee_file 是 TEE 镜像文件的名称。
    • get_cmd ${fdt_addr} ${fdt_file} 会从网络获取设备树文件(DTB)。fdt_addr 是设备树加载的地址,fdt_file 是设备树文件的名称。
    • bootm ${tee_addr} - ${fdt_addr}:使用 bootm 命令来启动内核,bootm 的参数包括 TEE 镜像的地址(tee_addr)、内核镜像的地址(- 表示不加载内核镜像),以及设备树的地址(fdt_addr)。这样内核、设备树和 TEE 会一并启动。
  1. else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi;
else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; thenbootz ${loadaddr} - ${fdt_addr};else if test ${boot_fdt} = try; then bootz;else echo WARN: Cannot load the DT;fi;
fi;
  • 这个部分处理设备树(FDT)的加载:
    • 如果 boot_fdtyestry,则尝试从网络获取设备树文件(fdt_file)。
    • 如果成功获取设备树文件,使用 bootz 启动内核,其中 loadaddr 是内核镜像的加载地址,fdt_addr 是设备树的加载地址。
    • 如果设备树文件加载失败,且 boot_fdttry,则尝试直接启动内核,不加载设备树(即执行 bootz)。
    • 如果无法加载设备树并且 boot_fdt 不为 try,则输出警告信息 "WARN: Cannot load the DT",即无法加载设备树。
  1. else bootz; fi; fi;
else bootz; fi; fi;
  • 如果 teeno,且没有设备树文件的要求(boot_fdt 也为 no),直接执行 bootz 来启动内核。此时系统仅加载内核镜像,不加载设备树和 TEE 文件。

通过环境变量netboot总结出网络启动方式的流程

通过上面的对 netboot 内容的分析,整个 netboot 命令的流程如下:

  1. 输出提示信息,表明正在通过网络启动。
  2. 配置网络(如果嵌入式板子使用的是 USB 网络设备)。
  3. 设置网络启动的参数(使用 DHCP 还是 TFTP的形式来获取内核的设备树文件和镜像)。
  4. 尝试从网络获取内核镜像。
  5. 如果启用 TEE,则获取 TEE 镜像和设备树文件,并通过 bootm 启动系统。
  6. 如果未启用 TEE,尝试获取设备树文件,如果成功加载设备树,使用 bootz 启动内核。如果设备树无法加载并且 boot_fdttry,则直接启动内核。
  7. 如果所有步骤失败,显示警告或直接启动内核。

该命令定义了灵活的网络启动机制,可以根据系统配置和环境条件选择合适的启动方式。

环境变量netargs的分析(事关重要的环境变量bootargs)

环境变量netargs的定义如下:

netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp

环境变量netargs在上面已经分析的环境变量netboot的具体内容中被用到,相关的内容为:

run netargs

具体的语义环境如下:

netboot=echo Booting from net ...; ${usb_net_cmd}; run netargs;.......

在这里插入图片描述
所以,其实环境变量netboot中的命令run netargs等效于下面的语句:

run setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp

可见,其实就是设置向内核传递参数的环境变量bootargs,关于这个环境变量bootargs的详细介绍见博文 https://blog.csdn.net/wenhao_ir/article/details/145901614

所以,如果我们要改变境变量bootargs的内容,实际上应该是去修改环境变量netargs,而不是直接去修改环境变量bootargs,你如果直接去修改环境变量bootargs,那么在执行命令 run netboot时,会被命令run netargs替换为在环境变量netargs中写好的对环境变量bootargs的设置值。

我在实际移植内核时该如何设置环境变量

在博文 https://blog.csdn.net/wenhao_ir/article/details/145822475 中,进行了对设备树和Linux内核的移植。

在移植时,我们是通过TFTP的形式来获取内核和设备树文件,所以根据上面的分析,要进行下面这样的设置:

01-设置环境变量ip_dyn的值为no,如果ip_dyn的值为yes,则当以netboot的方式启动内核时,u-boot会使用 DHCP 协议获取网络配置,然后从这个利用DHCP 协议配置好的网络中去获取内核镜像和设备树文件。

setenv ip_dyn no

02-设置设备树文件的名字

setenv fdt_file imx6ull-14x14-evk.dtb

03-设置TFTP的服务器地址和NFS的服务器地址:

setenv serverip 192.168.5.11

我在博文 https://blog.csdn.net/wenhao_ir/article/details/145814363 中已经证实了,serverip这个环境变量就是u-boot中TFTP协议使用的服务器地址。详情搜索博文 https://blog.csdn.net/wenhao_ir/article/details/145814363 中的关键词“这个地址必须设置”。

根据上面的分析,环境变量serverip不仅是TFTP的服务器地址,还是环境变量netargs中对NFS设置的服务器地址,当然你也可以把环境变量netargs中的相关环境名更改一下,比如把:

netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp

中的nfsroot=${serverip}改为nfsroot=${serverip_nfs},就可以单独设置 NFS的服务器地址了。

关于这其中涉及到的关键的环境变量bootargs,我在本篇博文的前面已经介绍了,请搜索“事关重要的环境变量”。在是u-boot启动过程中,bootargs是u-boot传递给Linux内核的一个关键参数,它包含了内核启动时所需要的各种配置选项。U-Boot通过设置环境变量bootargs来指定这些启动参数。内核获取到这些参数后就可以按照这些配置去启动和设置内核。

04-设置NFS的目录地址

环境变量netargs中就要用到这个值,设置如下:

setenv nfsroot /home/book/mybuild/nfs_linux_rootfs

05-设置u-boot的IP地址
由于不使用DHCP方式获取网络配置,所以当然要为u-boot指定一个IP地址了,命令如下:

setenv ipaddr 192.168.5.9

06-重新设置环境变量netargs的值
因为我需要挂载是可读可写的,而不是只读的,所以需要在NFS挂载设置时加上rw属性,具体的设置如下:

setenv netargs 'setenv bootargs console=${console},${baudrate} root=/dev/nfs rw ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp'

其实这里本质上修改的是环境变量bootargs的值,环境变量bootargs的内容就是u-boot向内核传递的参数,详情见 https://blog.csdn.net/wenhao_ir/article/details/145901614

关于这个修改的探索过程和来历详见 https://blog.csdn.net/wenhao_ir/article/details/145883835 【搜索关键词“修改NFS挂载方式为可读可写并再次测试”】

以上这些环境变量设置完毕后,就可以用下面的命令从网络启动Linux系统了:

run netboot

后续的启动过程详见下面两篇博文:
https://blog.csdn.net/wenhao_ir/article/details/145883835

https://blog.csdn.net/wenhao_ir/article/details/145822475

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com