加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

启动流程分析(2)-uboot .

发布时间:2020-12-15 07:09:56 所属栏目:百科 来源:网络整理
导读:1 ?????? Uboot 存放地址 Uboot 是是运行完固化的 Boot Code 后, Boot Code 会跳转到选定设备的指定地址去运行,以 EMMC 为例,见下图 起始的前 0x200 即 512B 为 MBR ,接着的是预留的 Second Image Table , Boot Image( uboot) 应该放在 0x400(1024) 的

1?????? Uboot存放地址

Uboot是是运行完固化的Boot Code后,Boot Code会跳转到选定设备的指定地址去运行,以EMMC为例,见下图

起始的前0x200512BMBR,接着的是预留的Second Image TableBoot Image( uboot)应该放在0x400(1024)的地址,即烧写uboot的时候,就应该烧写在emmc主分区的1024位置,这也和烧录uboot的脚本“sudo dd if=./u-boot.bin of=./u-boot-no-padding.bin bs=1024 skip=1;?sync”相对应。

?

2?????? Uboot启动

Uboot启动一般认为是由两个阶段来运行,一是汇编start.s运行阶段,二是由其他C语言完成的第二阶段,一下做简要分析。

?

2.1 第一阶段分析

第一阶段主要是start.s的运行,主要完成定义入口地址、设置异常向量、设置CPU的频率、初始化内存控制器、加载Uboot第二阶段代码代码到RAM、初始化堆栈、跳转到RAM运行第二阶段程序。按照规定的0x400存放这段代码,BOOT CODE会加载这段代码到内部RAM运行,根据不同的boot device,具体加载的偏移地址和加载程序范围如下图:

可见到,对于emmc来说,加载的偏移地址为0x400,大小为2Kbyte

通过make mx53_smd_android_config配置自己的板子,查看uboot-imx下的Makefile可知

mx53_smd_android_config??????????? :unconfig

?????? $(MKCONFIG) $(@:_config=) arm arm_cortexa8 mx53_smd freescale mx53

2.1.1 链接文件u-boot.lds

在看链接文件之前,我们先看一下,生成的map文件如下(仅截取memory map一部分)

Memory Configuration

Name???????????? Origin????????? ???Length???????????? Attributes

*default*??????? 0x00000000???????? 0xffffffff

?

Linker script and memory map

??????????????? 0x00000000??????????????? . = 0x0

??????????????? 0x00000000??????????????? . = ALIGN (0x4)

?

.text?????????? 0x77800000??? 0x258a8

?board/freescale/mx53_mpvceo/flash_header.o(.text.flasheader)

?.text.flasheader

??????????????? 0x77800000????? 0x5cc board/freescale/mx53_mpvceo/flash_header.o

?cpu/arm_cortexa8/start.o()

?*fill*???????? 0x778005cc?????? 0x14 00

?.text????????? 0x778005e0????? 0x440 cpu/arm_cortexa8/start.o

??????????????? 0x77800620??????????????? _end_vect

??????????????? 0x77800628??????????????? _bss_start

??????????????? 0x7780062c??????????????? _bss_end

??????????????? 0x77800624??????????????? _armboot_start

???? ???????????0x778005e0??????????????? _start

??????????????? 0x77800960??????????????? v7_flush_dcache_all

?.data????????? 0x77800a20??????? 0x0 cpu/arm_cortexa8/start.o

?.bss?????????? 0x77800a20??????? 0x0 cpu/arm_cortexa8/start.o

?.ARM.attributes

?????? ?????????0x77800a20?????? 0x17 cpu/arm_cortexa8/start.o

?.debug_line??? 0x77800a37?????? 0xbb cpu/arm_cortexa8/start.o

?.debug_info??? 0x77800af2?????? 0x95 cpu/arm_cortexa8/start.o

?.debug_abbrev? 0x77800b87?????? 0x14 cpu/arm_cortexa8/start.o

?*fill*??? ?????0x77800b9b??????? 0x5 00

?.debug_aranges

??????????????? 0x77800ba0?????? 0x20 cpu/arm_cortexa8/start.o

?.glue_7??????? 0x77800bc0??????? 0x0 cpu/arm_cortexa8/start.o

?.glue_7t?????? 0x77800bc0??????? 0x0 cpu/arm_cortexa8/start.o

?.vfp11_veneer? 0x77800bc0??????? 0x0 cpu/arm_cortexa8/start.o

?.v4_bx???????? 0x77800bc0??????? 0x0 cpu/arm_cortexa8/start.o

?board/freescale/mx53_mpvceo/libmx53_mpvceo.a(.text)

?.text????????? 0x77800bc0???? 0x1a88 board/freescale/mx53_mpvceo/libmx53_mpvceo.a(mx53_mpvceo.o)

??????????????? 0x77800c74??????????????? dram_init

??????????????? 0x77800c40??????????????? get_board_id_from_fuse

??????????????? 0x77800c1c??????????????? __iounmap

??????????????? 0x77800c20??????????????? get_boot_device

??????????????? 0x778018d4?? ?????????????i2c_failed_handle

??????????????? 0x77802078??????????????? board_mmc_init

?????????????????????????????????? ……(省略部分内容)

.text????????? 0x77802648??????? 0x0 board/freescale/mx53_mpvceo/libmx53_mpvceo.a(lowlevel_init.o)

?

下面再来看链接文件:

OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")设置输出文件是elf格式,32ARM指令,小端;

OUTPUT_ARCH(arm) 设置输出执行平台Arm

ENTRY(_start) 设置入口地址,在map中可知,其地址为0x778005e0

SECTIONS

{

?????? . = 0x00000000;目标代码段的起始地址;

?????? . = ALIGN(4);对齐为4字节;

?????? .text?????? ?? :代码段,会看到在map中,其值为0x77800000,是由于其被config.mkTEXT_BASE重定向了,即其运行地址在0x77800000

?????? {

?????? ? /* WARNING - the following is hand-optimized to fit within????? */

?????? ? /* the sector layout of our flash chips!??? XXX FIXME XXX??? */

?????? ? board/freescale/mx53_mpvceo/flash_header.o??? (.text.flasheader)这个文件就是启动流程1里面,boot code会完成Device Configuration DataDCD);

?????? ? cpu/arm_cortexa8/start.o 运行地址在程序段0x778005e0,虽然其和flash_header.o运行地址在SDRAM中,但是其存放地址是在boot devices的起始地址,所以其均会被boot Code加载,并在start.s把代码拷贝到RAM中的0x77800000中,之后跳转到RAM运行,具体看start.s分析;

?????? ? board/freescale/mx53_mpvceo/libmx53_mpvceo.a??? (.text)

?????? ? lib_arm/libarm.a????????? (.text)

?????? ? net/libnet.a?????????????????? (.text)

?????? ? drivers/mtd/libmtd.a?????????? (.text)

?????? ? drivers/mmc/libmmc.a????????????? (.text)

?

?????? ? . = DEFINED(env_offset) ? env_offset : .;

?????? ? common/env_embedded.o(.text)

?

?????? ? *(.text)

?????? }

?

?????? . = ALIGN(4);

?????? .rodata : { *(.rodata) } 只读data –常量;

?

?????? . = ALIGN(4);

?????? .data : { *(.data) } 变量初始化过的;

?

?????? . = ALIGN(4);

?????? .got : { *(.got) }

?

?????? . = .;

?????? __u_boot_cmd_start = .; Uboot cmd的存放位置;

?????? .u_boot_cmd : { *(.u_boot_cmd) }

?????? __u_boot_cmd_end = .;

?

?????? . = ALIGN(4);

?????? _end_of_copy = .; /* end_of ROM copy code here */

?????? __bss_start = .; 未初始化的变量,不用拷贝,未初始化本身就为0

?????? .bss : { *(.bss) }

?????? _end = .;

}

2.1.2 Start.s分析

.globl _start 定义全局变量_start

_start: b reset初始运行地址

?????? /*异常处理*/

?????? ldr?? pc,_undefined_instruction

?????? ldr?? pc,_software_interrupt

?????? ldr?? pc,_prefetch_abort

?????? ldr?? pc,_data_abort

?????? ldr?? pc,_not_used

?????? ldr?? pc,_irq

?????? ldr?? pc,_fiq

……

reset:

?????? /*

?????? ?* set the cpu to SVC32 mode

?????? ?*/

?????? mrs r0,cpsr

?????? bic? r0,r0,#0x1f

?????? orr? r0,#0xd3

?????? msr cpsr,r0

?????? ……

_TEXT_BASE:

?????? .word???? TEXT_BASE

?

.globl _armboot_start

_armboot_start:

?????? .word _start 地址为0x778005e0

?

/*

?* These are defined in the board-specific linker script.

?*/

.globl _bss_start

_bss_start:

?????? .word __bss_start 地址为0x778301b4

?

.globl _bss_end

_bss_end:

?????? .word _end

……

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

relocate:??????????????????????????? @ relocate U-Boot to RAM

?????? adr? r0,_start???????????? @ r0 <- current position of code 相对位置

?????? ldr?? r1,_TEXT_BASE???????? @ test if we run from flash or RAM 绝对地址

?????? cmp?????? r0,r1?????????????????? @ don't reloc during debug

?????? beq stack_setup

?

?????? ldr?? r2,_armboot_start绝对地址地址为0x77800624

?????? ldr?? r3,_bss_start绝对地址地址为0x778301b4,即拷贝程序大小为_armboot_start0x778301b4这段空间

?????? sub? r2,r3,r2????????????? @ r2 <- size of armboot

?????? add r2,r2????????????? @ r2 <- source end address

?

copy_loop:???????????????????????? @ copy 32 bytes at a time

?????? ldmia???? r0!,{r3 - r10}????????????? @ copy from source address [r0]

?????? stmia???? r1!,{r3 - r10}????????????? @ copy to?? target address [r1]

?????? cmp?????? r0,r2?????????????????? @ until source end addreee [r2]

?????? ble? copy_loop

#endif??? /* CONFIG_SKIP_RELOCATE_UBOOT */

?

?????? /* Set up the stack */

stack_setup:

?????? ldr?? r0,_TEXT_BASE???????? @ upper 128 KiB: relocated uboot

?????? sub? r0,#CONFIG_SYS_MALLOC_LEN @ malloc area

?????? sub? r0,#CONFIG_SYS_GBL_DATA_SIZE @ bdinfo

#ifdef CONFIG_USE_IRQ

?????? sub? r0,#(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)

#endif

?????? sub? sp,#12?????????? @ leave 3 words for abort-stack

?????? and sp,sp,#~7?????????? @ 8 byte alinged for (ldr/str)d

?

?????? /* Clear BSS (if any). Is below tx (watch load addr - need space) */

clear_bss:

?????? ldr?? r0,_bss_start???????????? @ find start of bss segment

?????? ldr?? r1,_bss_end??????? @ stop here

?????? mov?????? r2,#0x00000000??????? @ clear value

clbss_l:

?????? str?? r2,[r0]????????? @ clear BSS location

?????? cmp?????? r0,r1?????????????????? @ are we at the end yet

?????? add r0,#4???????????? @ increment clear index pointer

?????? bne clbss_l???????????????? @ keep clearing till at end

?

#ifdef CONFIG_ARCH_MMU

?????? bl board_mmu_init

#endif

?????? ldr?? pc,_start_armboot??? @ jump to C code

?

_start_armboot: .word start_armboot 跳转到C start_armboot启动。

2.2 第二阶段分析

lib_arm/board.c中的start_armboot是第二阶段开始的代码,其主要完成系统内核、中断、时钟、接口、设备包括FLASHDISPLAY、网络等的初始化,并进入命令循环,接收用户命令后完成相应的工作。

????? /* Pointer is writable since we allocated a register for it */

????? 初始化Global data的数据地址

????? gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));

????? /* compiler optimization barrier needed for GCC >= 3.4 */

????? __asm__ __volatile__("": : :"memory");

?

????? memset ((void*)gd,sizeof (gd_t));

????? gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));

????? memset (gd->bd,sizeof (bd_t));

?

????? gd->flags |= GD_FLG_RELOC;

????????????? 初始化序列

????????????? for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {

????????????? if ((*init_fnc_ptr)() != 0) {

???????????????????? hang ();

????????????? ?????? }

?????? ?????? }

??????

????????????? ……

?

????????????? ?????? /* main_loop() can return to retry autoboot,if so just run it again. */

?????? ?????? for (;;) {

????????????? ?????? main_loop ();

?????? ?????? }

?????? main_loop中,会不断扫描输入,并根据输入做相应的设置,如果超出delay时间(3S),会自动运行bootcmdevn参数。那么对于从emmc启动的板子,bootcmd的参数为:

"loadaddr=0x70800000"

"rd_loadaddr=0x70D00000"?????????????

????????????? "bootargs=console=ttymxc0 init=/init "

"androidboot.console=ttymxc0 di1_primary calibration video=mxcdi0fb:720P60"

????????????? "bootcmd_SD=mmc read 1 ${loadaddr} 0x800 0x2000;"

???????????????????? "mmc read 1 ${rd_loadaddr} 0x3000 0x300"

????????????? "bootcmd=run bootcmd_SD; bootm ${loadaddr} ${rd_loadaddr}"

?

mmc read <device num> addr blk cnt 意思是将blk开始的cntblock的内容读取到内存地址的addr处。Bootm addr 启动内存addr出的image文件。由此可以判定,uboot启动之后,将读取设备节点10x800block开始的0x2000block大小的内容到0x70800000地址。在uboot初始化fsl_esdhc_initialize时,ESDHC的初始化时按下面的数组顺序来进行的

struct fsl_esdhc_cfg esdhc_cfg[2] = {

?????? {MMC_SDHC1_BASE_ADDR,1,1},

?????? {MMC_SDHC3_BASE_ADDR,

}

SDHC3的位置放置的板载EMMCSD卡的位置在SDHC1的位置,所以节点1正好是板载EMMD的节点。而一个block的大小是512,那么0x800正好是1M的大小,也就是烧录kernel的位置。0x3000的位置正好是6M,即是uRamdisk的烧录位置。

$ dd if=$FILE of=/dev/mmcblk0 bs=512 seek=2048

$ dd if=$FILE of=/dev/mmcblk0 bs=6M seek=1

?因此,系统将会在加载完kernel运行后,加载uramdisk并运行

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读