正点原子UBOOT启动流程——学习笔记
Posted 西邮菜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正点原子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启动在后面学习了再记笔记。
以上是关于正点原子UBOOT启动流程——学习笔记的主要内容,如果未能解决你的问题,请参考以下文章
Linux编程入门--正点原子Linux驱动开发指南学习2021W26
正点原子Linux MINI板系统固化(烧录ubootlinux kernel.dtb(设备树)和 rootfs)