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

reset的相关处理

从_start跳转到reset

[cpp] view plaincopy
  1. .globl _start
  2. _start: b   reset
save_boot_params 改函数为weak函数,未定义任何内容。用户如过有任何参数要传递的,那么需要再次定义这个函数。
[cpp] view plaincopy
  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 plaincopy
  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 plaincopy
  1. #ifndef CONFIG_SKIP_LOWLEVEL_INIT
  2. bl  cpu_init_cp15
  3. bl  cpu_init_crit
  4. #endif

跳转到main函数

[cpp] view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  1. void    relocate_code (ulong, gd_t *, ulong) __attribute__ ((noreturn));

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

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

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

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

ARM Uboot经历——Uboot初始化代码解析相关推荐

  1. 嵌入式linux的u-boot系统启动过程,嵌入式linux操作系统u-boot启动顺序以及代码解析...

    嵌入式linux操作系统u-boot启动顺序以及代码解析 (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 Bootloader/u-bo ...

  2. uboot移植Linux-SD驱动代码解析

    一.uboot与linux驱动 1.1.uboot本身是裸机程序 (1)狭义的驱动概念是指:操作系统中用来具体操控硬件的代码叫驱动 广义的驱动概念是指:凡是操控硬件的代码都叫驱动 (2)裸机程序中是直 ...

  3. 【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 :  -- u-boo ...

  4. uboot代码解析3:内存管理、控制台、网络、启动函数

    https://ke.qq.com/course/4032547?flowToken=1042705 目录 https://ke.qq.com/course/4032547?flowToken=104 ...

  5. 【u-boot】uboot代码简要分析 (u-boot 移植)

    uboot代码简要分析 (u-boot 移植) 2012-12-19 22:46:04 [转] 先来看看源码目录结构,再按照代码的执行顺序简单地分析源码 1.U-boot源码整体框架 源码解压以后,我 ...

  6. U-Boot 之三 U-Boot 源码文件解析及移植过程详解

      在之前的博文 Linux 之八 完整嵌入式 Linux 环境介绍及搭建说明 中我们说了要一步步搭建整个嵌入式 Linux 运行环境.我所使用的硬件平台及整个要搭建的嵌入式 Linux 环境见博文 ...

  7. Uboot 板级初始化流程and so on

    -------------------------- 本文以U-boot 2018.09源码 mips mt7621进行举例说明. 此预期的理论初始化流程适用于全U-boot和SPL(Secondar ...

  8. ARM平台的U-Boot移植详细步骤

    0. 背景介绍 我们手里这块RK3399开发板出厂时带的是2017.09版本的U-Boot. U-Boot 2017.09 (Sep 26 2021 - 08:53:15 +0000)Model: F ...

  9. 天嵌TQ2440 ARM开发板Uboot移植

    TQ2440 ARM开发板Uboot移植 移植环境 主    机:VMWare--Fedora 10 Kernel:2.6.34  开发板:TQ2440--256MB Nand 编译器:arm-lin ...

最新文章

  1. JavaScriptjQuery.stopPropogation()
  2. i2c连续读写间隔_迅远科技RFID产品推荐:F5808高性能八通道读写器
  3. 14 篇论文为你呈现「迁移学习」研究全貌 | 论文集精选 #04
  4. VTK:Points之FitImplicitFunction
  5. Elasticsearch之中文分词器插件es-ik(博主推荐)
  6. 列表推导式 生成器表达式
  7. 实现JNI的另一种方法:使用RegisterNatives方法传递和使用Java自定义类 (转)
  8. 虚拟机 安装 linux 分辨率 调整
  9. springboot+微信小程序点餐系统的设计与实现毕业设计源码221541
  10. android gif图片压缩,10种GIF压缩方法
  11. WS以及NW小世界网络的生成(MATLAB)
  12. 清华姚班程序员,网上征婚被骂?
  13. 正则表达式和re模块
  14. 为什么内网地址普遍是192.168.1.1
  15. 复盘港股2021:新股上市热潮不减,市场重现“冰火两重天”
  16. java合并流与文件的分割合并示例
  17. 消防应急灯锂电池供电2.5V-30V升压恒流驱动IC方案
  18. 用 python 脚本,把当前目录及子目录下的 wav 音频文件转换为 flac 格式
  19. 对数函数定义域和值域_对数函数的定义域,值域是怎么求的
  20. Linux mint 16安装后的种种善后

热门文章

  1. 什么计算机网络成瘾,计算机网络与网络成瘾.pdf
  2. close事件 vue_vue中v-on支持的事件总结
  3. 增值电信业务经营许可证怎么办理icp许可证
  4. android之ExoPlayer探索
  5. 20行代码制作字符画版小黄鸭表情包 | 文末送书抽奖结果
  6. 数据科学如此火爆,为什么找个工作还那么难?
  7. 数据库查询时报错com.mysql.jdbc.exceptions.jdbc4.MySQLDataException: ‘1.7725000000E10‘ in column ‘17‘ is outs
  8. Win11终端管理员打不开解决方法
  9. 一墙之隔-看向世界和直面速度与激情
  10. Bzoj4698: [Sdoi2008]Sandy的卡片