正点原子UBOOT启动流程——学习笔记

一、UBOOT入口

uboot的入口在u-boot.lds文件里面决定了,ENTRY(_start),所以uboot的入口就是__start,后面紧接着就是中断向量表的地址。

到__image_copy_start 为 0X87800000,而.text 的起始地址也是 0X87800000,vectors 段的起始 地址也是 0X87800000,说明整个 uboot 的起始地址就是 0X87800000。

__start执行时跳转到reset,reset函数跳转到了 save_boot_params 函数,save_boot_params 函数跳转到 save_boot_params_ret 函数,设置系统为SVC32保护模式、关闭中断、快中断。再跳转到cpu_init_crit,cpu_init_crit跳转到lowlevel_init,完成内部RAM的初始化(只有128k),设置好的RAM图如下:

 再返回save_boot_params_ret,执行_main函数,在_main 函数里面调用了 board_init_f_alloc_reserve、board_init_f_alloc_reserve、board_init_f、relocate_code、 relocate_vectors 和 board_init_r 这几个函数

跳转到board_init_f_alloc_reserve函数,设置上面的内存,留出malloc区域和gt_t内存区域。再执行board_init_f_init_reserve,初始化gd_t结构体的指针,清零处理,gt_t中还有一个bd_t结构体,保存开发板的参数,uboot启动内核时通过这两个结构体传给内核参数。分配完的结果如下:

 

进入board-init_f函数,初始化一系列外设,比如串口、定时器,或者打印一些消息等,初始化 gd 的各个成员变量,uboot 会将自己重定位到 DRAM 最后面的地址区域,也就 是将自己拷贝到 DRAM 最后面的内存区域中,防止 Linux kernel 覆盖掉 uboot。在转移之前会设置一系列函数(init_sequence_f里面的所有函数来分配512MB的DDR内存,比如 gd 应该存放到哪个位置,malloc 内存池应该存放到哪个位置等等,形成以下的内存图。下面的所有值都是通过init_sequence_f里面的函数计算出来的。

 进入代码重定位函数relocate_code,代码原本存在0X87800000中,转移到=0X9FF47000,相减计算出偏移量,之后进行拷贝,每次复制两个字节。重定位其实就是 uboot 将自身拷贝到 DRAM 的另一个地放去继续运行。但是直接转移一个可执行的 bin 文件,其链接地址和运行地址就不相等,如何解决,这里用了一个位置无关码,他解决了重定位后链接地址和运行地址不一致的问题

未完待续:relocate_vectors与board_init_f还有bootz启动在后面学习了再记笔记。

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西邮小菜机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值