uboot引导os

本文接《uboot重定位后初始化》,假定未中断auto boot,即使用默认引导参数去boot os(linux kernel).

假设,我们没有干预,使用auto boot, abortboot_normal()返回0.

我们回到process_boot_delay().

abortboot()返回0后,程序使用环境变量中定义的”bootcmd”来运行boot命令(449行).

我的环境上:

bootcmd=bootfmh

bootargs= root=/dev/nfs rw nfsroot=10.108.219.172:/root/workspace/NDCS18OCP_3_45_ 00_workspace/Build/output/ImageTree,proto=tcp,nfsvers=4,nolock ip=dhcp console=t tyS4,115200

调用bootcmd的函数调用过程如下:

run_command_list() -> builtin_run_command_list() -> builtin_run_command() -> cmd_process() -> cmd_call()

uboot/common/command.c

bootcmd的定义是通过宏 U_BOOT_CMD()来申明的,定义在uboot/include/command.h

我们来看一下bootcmd=bootfmh的定义:

uboot/oem/ami/fmh/cmd_fmh.c

我们接着看do_bootfmh.

uboot/oem/ami/fmh/cmd_fmh.c

125行ReadJumperConfig为__ReadJumperConfig, 该函数返回-1,故PathID会修正为0(129行)。

最后调用BootFMH(1<<0)处理。

849行:波特率115200。

897行:获取bootImage在flash哪块(60M一块,共2块,我的环境上是在第2块,即IMAGE2)。

906行:将image boot信息打印出来:

CONFIG_SPX_FEATURE_GLOBAL_USED_FLASH_SIZE= 0x3c00000(60M).

uboot/include/configs/ast.cfg

对于image2,startaddress为0x20000000(512M) + 60M.

937行,打印.

941行开始,循环扫描spi flash中从startaddress开始的每个sector,看是否有FMH头,FMH头用于描述module的信息,比如:

boot FMH:

location描述这个module(程序块)在flash中的偏移地址。

LoadAddr描述这个module需要被加载到哪个地址去run。

root FMH(根设备):

osimage FMH:

找到FMH头后,往下执行:

从FMH头中取出module_type,如果是MODULE_INITRD_SQUASHFS(当前我的系统上的值), 则设置为rootisinitrd,并打印1072行信息。

这行打印表示linux os使用flash地址为0x23c60000地址处的存储空间用作它的根设备,即linux的根文件系统rootfs需要烧写在flash地址0x23c60000处。

之后在1087行,打印0x23c60000处烧写的文件系统类型。

1101行打印root @ /dev/mtdblock1 Address 0X23C60000,注意,这里的”/dev/mtdblock1”是给linux kernel使用的,kernel根据这个字符串去匹配对应的mtdblock1驱动,找到后才能将该设备/dev/mtdblock1挂载mount成rootfs,并切到这个rootfs。

1119-1130行,从flash中根据startaddress + FMH location将module读出来,放到FMH loadAddress描述的地址上。

同时将这些信息打印出来:

对于”ROOT”这个module,还有如下(1150行)打印:

串口打印log:

对于osimage, 从FMH从取出LoadAddress:

我的系统中总共有boot, root, osimage, www, dre这些modules,故后面还有这些打印:

最后再打印下校验结果:

1256行构建bootargs参数:

uboot/oem/ami/fmh/bootargs.c

Get_bootargs()之后,则增加其他boot参数,比如console=ttyS4, rootfstype=cramfs等。

uboot/oem/ami/fmh/cmd_fmh.c

构建完bootargs后:

又构建了argv[] = {“FMHEXECUTE”, “$execute_addr”, “$initrd_addr”, NULL}.

1371行将bootargs参数打印出来:

最后,将bootargs参数的值设置为环境变量bootargs的值,之后,1382行进入do_bootm(NULL, 0, 2, argv)。

do_bootm()定义在uboot/common/cmd_bootm.c

do_bootm去掉了argv[0],即去掉了默认的命令” FMHEXECUTE”, 然后调用do_bootm_stats,注意此时argv[]只有2个参数,argv[0]为executeAddr, 即kenel image的flash存储地址,argv[1]为initrd地址,即ramdisk的地址。

uboot/common/cmd_bootm.c

631行,记录lower memory:

uboot/common/cmd_bootm.c

这里再放置一下relocate uboot之后的memory map图。

635行根据argv[0]提供的kernel image烧写地址,加载image HDR信息。

uboot/common/cmd_bootm.c

uboot/common/cmd_bootm.c

927-943行拿到os image烧写地址后,去处image header信息。并打印” ## Booting kernel from Legacy Image at <image flash addr> …”.

238-243行从os头中拿到os的type, 压缩方式,os二进制存储地址,以及加载地址。

638行根据argv[1]查找ramdisk的hdr信息。

uboot/common/cmd_bootm.c

uboot/common/cmd_bootm.c

uboot/common/image.c

980行会打印ramdisk在flash上的地址” ## Loading init Ramdisk from Legacy

"Image at <ramdisk flash addr> …”

找到这些信息后,我们就需要加载kernel和ramdisk了。

uboot/common/cmd_bootm.c

bootm_load_os根据image header中的信息将image搬运到load addr,同时打印“           Loading <os_name> … OK”(kernel image是自压缩解压的,这里无需解压处理)。

663行,由于没有设置BOOTM_STATE_RAMDISK,所以我们没有去load ramdisk到内存中,这部分工作kernel会自己做。

处理完image & ramdisk 加载后,获取boot_fn, 这里为do_bootm_linux,并调用该函数。

do_bootm_linux的主要工作就是跳转到kernel的入口函数(符号)处执行。

uboot/arch/arm/lib/bootm.c

uboot/arch/arm/lib/bootm.c

这里的参数r2,即gd->bd->bi_boot_params必须和Linux保持一致。

uboot/board/ast2500evb/ast2500evb.c

至此, uboot工作结束了。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值