ARM Uboot经历——Uboot初始化代码解析

本文详细解析U-Boot启动过程中的关键步骤,包括重定位之前的初始化处理、系统模式设置、底层设备初始化绕过机制及SPL加载流程等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Uboot初始化代码主要是在Uboot重定位之前的一系列处理,起源于start.s文件,涉及crt0.s和board.c等文件,会完成最系统环境最初始的设置和结构体赋值。


reset的相关处理

从_start跳转到reset

[cpp]  view plain copy
  1. .globl _start  
  2. _start: b   reset  

save_boot_params 改函数为weak函数,未定义任何内容。用户如过有任何参数要传递的,那么需要再次定义这个函数。
[cpp]  view plain copy
  1. reset:  
  2. bl  save_boot_params  
  3. #if defined(SIM_BREAKPOINT_WA)  
  4.     /* workaround to disable secure state */  
  5.     mrc     p15, #0, r0, c1, c1, #0  
  6.     orr r0, r0, #1  
  7.     mcr     p15, #0, r0, c1, c1, #0  
  8.     isb  
  9. #endif  

将ARM的模式修改为supervisor模式
[cpp]  view plain copy
  1. mrs r0, cpsr  
  2. bic r0, r0, #0x1f  
  3. orr r0, r0, #0xd3  
  4. msr cpsr,r0  

该宏已定义,表示会跳过底层设备的初始化
        cpu_init_cp15 用来设置cp15的一些功能,主要包括禁止cache,关闭MMU和TBL等功能
        cpu_init_crit 里面包含了lowlevel_init函数,用户可以自定义一些功能
[cpp]  view plain copy
  1. #ifndef CONFIG_SKIP_LOWLEVEL_INIT  
  2.     bl  cpu_init_cp15  
  3.     bl  cpu_init_crit  
  4. #endif  

跳转到main函数
[cpp]  view plain copy
  1. bl  _main  

main函数的处理

SPL表示secondary program loader,是android等手机刷机的常用术语。二级boot的主要意思就是连续两次boot,第一次是一个很简单的boot,这boot完成的目的就是在初始化PLL和flash等东西,然后将真实的Image从flash中拷入实际内存,继而重新再启动一遍。第二遍就是真实的uboot流程。
这个SPL的主要目的就是当PLL等东西初始化完成后,第二级的boot时间会大幅度缩短;而由于第一级的boot内容很少,因此boot的过程也很短。因此采用SPL方式会缩短boot时间。这里最终SPL就是用来读写flash rom的。除此之外,SPL还会检查要刷的数据文件是否正确。
这并没有定义各种宏,因此最终的sp的地址为 CONFIG_SYS_INIT_SP_ADDR  = 0x0c001000 - 128 = 0xC000F80
[cpp]  view plain copy
  1. _main:  
  2. #if defined(CONFIG_NAND_SPL)  
  3.     /* deprecated, use instead CONFIG_SPL_BUILD */  
  4.     ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)  
  5. #elif defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)  
  6.     ldr sp, =(CONFIG_SPL_STACK)  
  7. #else  
  8.     ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)  
  9. #endif  

GD的定义如下:
#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")
表示GD永远使用r8寄存器来存储地址
调用 board_init_f函数
[cpp]  view plain copy
  1. bic sp, sp, #7  /* 8-byte alignment for ABI compliance */  
  2. sub sp, #GD_SIZE    /* allocate one GD above SP */  
  3. bic sp, sp, #7  /* 8-byte alignment for ABI compliance */  
  4. mov r8, sp      /* GD is above SP */  
  5. mov r0, #0  
  6. bl  board_init_f  


board_init_f函数

board_init_f函数是uboot主要完成初始化的函数,在arch/arm/lib/board.c中,这个函数的主要功能如下:
1)调用一个函数指针数组,这个函数指针数组保存了需要初始化的多个函数指针;
2)配置并初始化gd结构体和bd结构体;
3)传递相应参数给uboot重定位模块;

对于第一个功能,代码如下:
[cpp]  view plain copy
  1. for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {  
  2.     if ((*init_fnc_ptr)() != 0) {  
  3.         hang ();  
  4.     }  
  5. }  
其中init_sequence是一个全局的函数指针数组,这个数组最后以NULL结尾,因此for循环会自动遍历这个数组来完成用户定义的所有初始化函数。这些初始化函数主要包括,DDR初始化,Timer初始化,I2C等串口初始化,Serial初始化等,当然用户可以自己根据自己是否需要来选择。

对于第二个功能,gd和bd模块,gd主要管理了内存划分,bd主要记录了可用SDRAM的起始位置和大小。
gd和bd两个结构体是uboot里面最重要的两个结构体,我想以后会另起一章。

对于第三个功能,传递的参数如下:
[cpp]  view plain copy
  1. void    relocate_code (ulong, gd_t *, ulong) __attribute__ ((noreturn));  

第一个堆栈指针,这个指针的位置是进过计算得出的;

第二个参数为gd的指针,这个gd指针是重定位后的地址;

第三个地址为重定位后的uboot的Image的起始位置;

注意这个函数是没有返回值的,调用这里完毕之后就直接进入uboot代码重定位过程了,至此,uboot的第一部分就结束了。

所有资料来源网上,与朋友分享 u-boot-1.1.6之cpu/arm920t/start.s分析 2 u-boot中.lds连接脚本文件的分析 12 分享一篇我总结的uboot学习笔记(转) 15 U-BOOT内存布局及启动过程浅析 22 u-boot中的命令实现 25 U-BOOT环境变量实现 28 1.相关文件 28 2.数据结构 28 3.ENV 的初始化 30 3.1env_init 30 3.2 env_relocate 30 3.3*env_relocate_spec 31 4. ENV 的保存 31 U-Boot环境变量 32 u-boot代码链接的问题 35 ldr和adr在使用标号表达式作为操作数的区别 40 start_armboot浅析 42 1.全局数据结构的初始化 42 2.调用通用初始化函数 43 3.初始化具体设备 44 4.初始化环境变量 44 5.进入主循环 44 u-boot编译过程 44 mkconfig文件的分析 47 从NAND闪存中启动U-BOOT的设计 50 引言 50 NAND闪存工作原理 51 从NAND闪存启动U-BOOT的设计思路 51 具体设计 51 支持NAND闪存的启动程序设计 51 支持U-BOOT命令设计 52 结语 53 参考文献 53 U-boot给kernel传参数和kernel读取参数—struct tag (以及补充) 53 1 、u-boot 给kernel 传RAM 参数 54 2 、Kernel 读取U-boot 传递的相关参数 56 3 、关于U-boot 中的bd 和gd 59 U-BOOT源码分析及移植 60 一、u-boot工程的总体结构: 61 1、源代码组织 61 2.makefile简要分析 61 3、u-boot的通用目录是怎么做到与平台无关的? 63 4、smkd2410其余重要的文件 : 63 二、u-boot的流程、主要的数据结构、内存分配 64 1、u-boot的启动流程: 64 2、u-boot主要的数据结构 66 3、u-boot重定位后的内存分布: 68 三、u-boot的重要细节 。 68 关于U-boot中命令相关的编程 : 73 四、U-boot在ST2410的移植,基于NOR FLASH和NAND FLASH启动。 76 1、从smdk2410到ST2410: 76 2、移植过程: 76 3、移植要考虑的问题: 77 4、SST39VF1601: 77 5、我实现的flash.c主要部分: 78 6、增加从Nand 启动的代码 : 82 7、添加网络命令。 87
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值