当前位置:   article > 正文

嵌入式Linux(十九)U-Boot启动流程详解_嵌入式boot启动代码

嵌入式boot启动代码

1.1 链接脚本 u-boot.lds 详解

  编译过uboot之后会在uboot根目录下生成u-boot.lds文件,这是链接程序的脚本,从这里找程序的入口。重点代码如下:

ENTRY(_start)          //当前代码入口点“_start”(在arch/arm/lib/vectors.S中定义,后面就是中断向量表)
 .text :
 {
  *(.__image_copy_start)
  *(.vectors)                            //vectors段保存中断向量表
  arch/arm/cpu/armv7/start.o (.text*)    //将arch/arm/cpu/armv7/start.s编译出的.o放到中断向量表后面
  *(.text*)                              //其它代码段放在这
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

  打开u-boot.map(该文件为uboot的映射文件,可以看到哪个文件或者函数链接到的地址),vscode中搜索,可以看到__image_copy_start链接到0X87800000也是.text和vectors段的起始地址。一些和地址有关的变量值如下:

__image_copy_start  0x87800000 	uboot 拷贝的首地址
__image_copy_end 	0x8785dd54 	uboot 拷贝的结束地址
__rel_dyn_start 	0x8785dd54 	.rel.dyn 段起始地址
__rel_dyn_end 		0x878668f4 	.rel.dyn 段结束地址
_image_binary_end 	0x878668f4 	镜像结束地址
__bss_start 		0x8785dd54 	.bss 段起始地址
__bss_end 			0x878a8e74 	.bss 段结束地址
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

1.2 链接脚本 u-boot.lds 详解

1.2.1 reset 函数源码详解

  “_start”在arch/arm/lib/vectors.S中,其中“b reset”开始跳转到reset函数(arch/arm/cpu/armv7/start.S),reset函数中“b save_boot_params”跳转到save_boot_params函数。再由“b save_boot_params_ret”跳转,save_boot_params_ret函数进行一些对于CPU的设置,调用了一些函数比如cpu_init_crit,_main等,cpu_init_crit其内部调用了lowlevel_init。

1.2.2 lowlevel_init函数详解

  lowlevel_init在arch/arm/cpu/armv7/lowlevel_init.S定义,重要代码:

//设置SP指针指向CONFIG_SYS_INIT_SP_ADDR(在include/configs/mx6ullevk.h)
//其中定义了一些变量,比如IMX6ULL内部ocram的首地址和大小
ldr sp, =CONFIG_SYS_INIT_SP_ADDR     

//对sp指针做8字节对齐处理
bic	sp, sp, #7 

//sp指针减去GD_SIZE(248)
sub	sp, sp, #GD_SIZE
bic	sp, sp, #7
mov	r9, sp    //将sp地址保存在r9寄存器

//s_init会判断CPU类型,对于IMX6ULL返回空
bl	s_init
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

1.2.3 _main函数详解

  来源于arch/arm/lib/crt0.S,重要代码:

ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)     //设置sp指向0X0091FF00

//调用函数,参数为r0中的值=0X0091FF00
//作用是留出早期的malloc内存区域和gd内存区域
//返回值为新的top值==0X0091FA00
bl	board_init_f_alloc_reserve

//用于初始化 gd,其实就是清零处理。
//设置了early malloc起始地址=0X0091FB00
bl	board_init_f_init_reserve

//初始化DDR,定时器,完成代码拷贝等
//初始化gd的各个成员变量,这些成员变量使得uboot自己重定位到DRAM最后的地址区域给Linux腾出空间,生成一个内存“分配图”
bl	board_init_f

//将uboot拷贝到新的地址
b	relocate_code

//对中断向量表进行重定位
bl	relocate_vectors

//清除BSS段,设置board_init_r等
bl	c_runtime_cpu_setup
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

board_init_f最终内存分配结果:
在这里插入图片描述

1.2.4 uboot函数调用总结

在这里插入图片描述

1.2.5 bootz启动Linux内核过程详解

略,以后再看吧
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/75869
推荐阅读
相关标签
  

闽ICP备14008679号