uboot distro_bootcmd 理解

uboot distro_bootcmd 理解

从 run distro_bootcmd 开始

distro_bootcmd=
	for target in ${boot_targets};
	do
		run bootcmd_${target};
	done

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5

我的 sun8-h3 板子中 boot_targets 为:

boot_targets=fel mmc_auto usb0 pxe dhcp 

   
   
   
   
  • 1

重点分析 mmc_auto dhcp

bootcmd_mmc_auto

以下变量的值,都可以通过 printenv name 查看的到,不过个别变量定义比较长,无法显示完整,这时需要在源代码中查看: \u-boot-2017.11.git\include\config_distro_bootcmd.h

bootcmd_mmc_auto=run bootcmd_mmc0

   
   
   
   
  • 1
bootcmd_mmc0=setenv devnum 0; run mmc_boot

   
   
   
   
  • 1
mmc_boot=
if mmc dev ${devnum};then            # 测试mmc 是否有分区,有则
	setenv devtype mmc;              # devtype = mmc
    run scan_dev_for_boot_part;      
fi

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
scan_dev_for_boot_part=                                         
	part list ${devtype} ${devnum} -bootable devplist;     # 这里正常会设置 devplist = 分区列表
	env exists devplist || setenv devplist 1;              # 如果为空,devplist 设置为 1
	for distro_bootpart in ${devplist}; do 
		if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then  # 检测fstype, 并设置 bootfstype=fstype
			run scan_dev_for_boot;                                          # help fstype 可以查看 fstype 用法说明
		fi; 
	done

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
scan_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;        	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
boot_prefixes=/ /boot/

 
 
 
 
  • 1
scan_dev_for_extlinux=
	if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then 
		echo Found ${prefix}extlinux/extlinux.conf;  # 如果找到 ${prefix}extlinux/extlinux.conf 文件,则 boot_extlinux
		run boot_extlinux; 
		echo SCRIPT FAILED: continuing...; 
	fi	

 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
boot_extlinux=
	sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf	
	                                                 # 读取 extlinux.conf 到 $scriptaddr

 
 
 
 
  • 1
  • 2
  • 3
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};   # 如果找到 boot.scr* 文件,则 boot_a_script
			run boot_a_script;
			echo SCRIPT FAILED: continuing...; 
		fi; 
	done
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
boot_scripts=boot.scr.uimg boot.scr

 
 
 
 
  • 1
boot_a_script=
		load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script};  # 将 script 读到 $scriptaddr
		source ${scriptaddr}                                                            # source 执行 $scriptaddr
  • 1
  • 2
  • 3
  • 4

boot.scr 的原始文件如下

setenv fdt_high ffffffff
setenv loadkernel fatload mmc 0 \$kernel_addr_r uImage
setenv loaddtb fatload mmc 0 \$fdt_addr_r dtb
setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait
setenv uenvcmd run loadkernel \&\& run loaddtb \&\& bootm \$kernel_addr_r - \$fdt_addr_r
run uenvcmd

 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

bootcmd_dhcp

bootcmd_dhcp=
	if dhcp ${scriptaddr} ${boot_script_dhcp}; then   # 从dhcp server 中下载 boot.scr.uimg 并执行
		source ${scriptaddr}; 
	fi;

 
 
 
 
  • 1
  • 2
  • 3
  • 4
boot_script_dhcp=boot.scr.uimg

 
 
 
 
  • 1

小结:不论是从mmc 启动还是 dhcp 启动,最终的步骤都是一样的,获取 boot.scr 到 scriptaddr , 然后 source scriptaddr

source

source 的用法,用途是从内存执行脚本

=> help source
source - run script from memory

Usage:
source [addr]

  • run script starting at addr
    valid image header must be present

boot.scr

boot.scr 如何生成

在 openwrt/package/boot/uboot-sunxi/Makefile 中,使用mkiamge 生成,输入文件为 uEnv-default.txt

        mkimage -C none -A arm -T script -d uEnv-$(UENV).txt \
                $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-boot.scr

 
 
 
 
  • 1
  • 2

uEnv-default.txt

setenv fdt_high ffffffff
setenv loadkernel fatload mmc 0 \$kernel_addr_r uImage
setenv loaddtb fatload mmc 0 \$fdt_addr_r dtb
setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/nfs nfsroot=172.16.10.67:/home/lql/my_rootfs/rootfs,vers=3 ip=dhcp rootwait
setenv uenvcmd run loadkernel \&\& run loaddtb \&\& bootm \$kernel_addr_r - \$fdt_addr_r
run uenvcmd

 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

读取 kernel 和 dtb 到指定内存位置,最后执行 bootm $kernel_addr_r - $fdt_addr_r

bootm

bootm 使用说明:

=> help bootm
bootm - boot application image from memory

Usage:
bootm [addr [arg ...]]
    - boot application image stored in memory
        passing arguments 'arg ...'; when booting a Linux kernel,
        'arg' can be the address of an initrd image
        When booting a Linux kernel which requires a flat device-tree
        a third argument is required which is the address of the
        device-tree blob. To boot that kernel without an initrd image,
        use a '-' for the second argument. If you do not pass a third
        a bd_info struct will be passed instead

Sub-commands to do part of the bootm sequence.  The sub-commands must be
issued in the order below (it's ok to not issue all sub-commands):
        start [addr [arg ...]]
        loados  - load OS image
        ramdisk - relocate initrd, set env initrd_start/initrd_end
        fdt     - relocate flat device tree
        cmdline - OS specific command line processing/setup
        bdt     - OS specific bd_t processing
        prep    - OS specific prep before relocation or go
        go      - start OS

第一个参数为 kernel 地址 ,当 要使用 dtb 时 加上 - 符号, 后接 dtb 地址。

小结:uboot 的使命就是执行 bootm , bootm 正常后,cpu 权限交给kernel ,uboot 宣告退休,直到下一次重启。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
uboot是一种常用的开源引导加载程序,用于嵌入式系统的引导启动。其中,board_init_r和board_init_f是uboot中的两个重要函数。 board_init_r函数是在uboot启动过程中执行的第一个函数。它负责执行一系列的初始化工作,例如初始化系统时钟、设置内存映射等。此函数被用于配置和初始化各个硬件模块,包括中断控制器、串口控制器、定时器等,以确保系统正常运行。该函数还读取并解析配置文件,加载设备树等操作,为后续的引导加载准备好必要的条件。 board_init_f函数是在board_init_r函数之后调用的。它用于进一步初始化系统,并执行一些与硬件相关的操作。例如,该函数可能会初始化网络接口、USB接口、存储设备等,并设置系统的默认环境变量。此外,board_init_f函数还负责将uboot的控制权交给操作系统的引导加载程序,从而完成uboot的使命。 通过调用board_init_r和board_init_f函数,uboot能够在系统启动时完成各种硬件的初始化和配置工作。这两个函数是uboot启动过程中的重要环节,确保系统能够顺利地加载操作系统并运行。同时,它们也为开发者提供了扩展uboot的接口,可以在这两个函数中添加自定义的初始化代码,以满足系统特定的需求。 总结来说,board_init_r和board_init_f是uboot中两个重要的函数,用于初始化和配置嵌入式系统的硬件,并为操作系统的加载做好准备。它们是uboot启动过程中不可或缺的一部分,保证系统的正常启动和运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值