8.1 start.S 修改

  发现启动初始化的过程需要屏蔽看门狗和中断。

  如果看门狗不禁用,会导致系统反复重启,因此需要在初始化的时候禁用看门狗;中断屏蔽保证启动过程中不出现异常现象

  时钟不需要初始化,直接由外部晶振提供初始化,在第二阶段 C 部分再进行初始化。

  代码主要在 start.S 中进行修改,主要是时钟代码的删除:

  

  这一块代码删除掉。

8.2 _main --- C环境

  执行完一系列初始化后,开始跳转到 _main 中执行进行C环境初始化和第二阶段的代码  

  crt0.S (arch\arm\lib)

  _main 执行过程如下:

  1. 建立调用 board_init_f() 的环境,此环境只是提供一个用来保存全局变量 GD 结构体的栈和空间,栈和空间都位于 SRAM 中。在调用board_init_f()前,GD 需要被清 0。
  2. 调用 board_init_f(),该函数从系统RAM(DRAM,DDR ...)准备将要执行的硬件。由于系统RAM可能还不可用,因此board_init_f()必须使用当前的GD来存储必须传递到后面阶段的任何数据。 这些数据包括重定位目标,未来堆栈和未来的GD位置。
  3. 设置中间环境,其中堆栈和GD是由系统RAM中的board_init_f()分配的,但BSS和初始化的 non-const 数据仍然不可用。
  4. 对于U-Boot本身(不是SPL),调用relocate_code()。 该函数将U-Boot从其当前位置重定位到由board_init_f()计算的重定位地址。
  5. 设置调用board_init_r()的最终环境。 这个环境具有BSS(初始化为0),初始化的 non-const 数据(初始化为其预期值),和系统RAM中的堆栈(用于SPL将堆栈和GD移入RAM是可选的 - 参见CONFIG_SPL_STACK_R)。 GD保留由board_init_f()设置的值。
  6. 对于U-Boot(不是SPL),有些CPU在内存方面还有一些工作要做,所以调用c_runtime_cpu_setup。
  7. 最后 跳到 board_init_r() 去执行

8.2.1 设置栈并初始化GD 和全局数据

 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
ldr sp, =(CONFIG_SPL_STACK)
#else
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) /** CONFIG_SYS_INIT_SP_ADDR = 0x3000 0f40 */
#endif /** end defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) */
#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */
mov r3, sp
bic r3, r3, #
mov sp, r3
#else
bic sp, sp, # /* 8 字节对齐,将 sp 的低三位清零,还是 0x3000 0f40 */
#endif /** end defined(CONFIG_CPU_V7M) */
mov r0, sp
bl board_init_f_alloc_reserve /** 预留 GD 的空间 */
mov sp, r0
/* set up gd here, outside any C code */
mov r9, r0
bl board_init_f_init_reserve /** 对 GD 做了次初始化,栈指针不动 */ mov r0, #
bl board_init_f /** 进入 relocate 前的初始化 */

8.2.2 board_init_f_alloc_reserve

 ulong board_init_f_alloc_reserve(ulong top)
{
/* Reserve early malloc arena */
#if defined(CONFIG_SYS_MALLOC_F)
/** 从顶部向下分配一块 CONFIG_SYS_MALLOC_F_LEN 大小的空间给 early malloc 使用,
这块内存是用于在relocation前用于给malloc函数提供内存池
0x3000 0f40 - 0x400 = 0x3000 0b40*/
top -= CONFIG_SYS_MALLOC_F_LEN;
#endif
/** 分配 sizeof(struct global_data) 大小的内存给 global_data 使用,向下 16byte 对齐
global_data 的长度会根据我们的配置变化长度,这里没办法计算分配后的地址所在 */
top = rounddown(top-sizeof(struct global_data), ); return top;
}

8.2.4 board_init_f_init_reserve

 void board_init_f_init_reserve(ulong base)
{
struct global_data *gd_ptr;
#ifndef _USE_MEMCPY
int *ptr;
#endif /*
* clear GD entirely and set it up.
* Use gd_ptr, as gd may not be properly set yet.
*/
/** gd_ptr 地址等于当前栈所在的地址 */
gd_ptr = (struct global_data *)base;
/* zero the area */
#ifdef _USE_MEMCPY
/** 初始化 */
memset(gd_ptr, '\0', sizeof(*gd));
#else
for (ptr = (int *)gd_ptr; ptr < (int *)(gd_ptr + ); )
*ptr++ = ;
#endif
/* set GD unless architecture did it already */
#if !defined(CONFIG_ARM)
arch_setup_gd(gd_ptr);
#endif
/* next alloc will be higher by one GD plus 16-byte alignment */
/** 分配空间,并向上 16 字节对齐,这里又指向了 0x3000 0b40 处 */
base += roundup(sizeof(struct global_data), ); /*
* record early malloc arena start.
* Use gd as it is now properly set for all architectures.
*/ #if defined(CONFIG_SYS_MALLOC_F)
/* go down one 'early malloc arena' */
gd->malloc_base = base;
/* next alloc will be higher by one 'early malloc arena' size,
base 重新回到 0x3000 0f40*/
base += CONFIG_SYS_MALLOC_F_LEN;
#endif
}

8.2.5 global_data内存分布

  

七、uboot 代码流程分析---C环境建立的更多相关文章

  1. 六、uboot 代码流程分析---start.S

    6.1 _start 入口函数 6.1.1 vectors.S (arch\arm\lib) 从上一节可以知道,uboot 的入口函数为 _start .此 函数定义在 vectors.S (arch ...

  2. 十、uboot 代码流程分析---run_main_loop

    调用 board_init_r,传入全局 GD 和 SDRAM 中的目的地址 gd->rellocaddr void board_init_r(gd_t *new_gd, ulong dest_ ...

  3. 八、uboot 代码流程分析---board_init_f

    接着上一节,板子开始做前期初始化工作. 8.1 board_init_f Board_f.c (common) /* 板子初次初始化.boot_flags = 0 */ void board_init ...

  4. 九、uboot 代码流程分析---relloc_code

    执行完 board_init_f 后,重新跳转回 _main 中执行. 9.1 relloc_code 前 9.1.1 gd 设置 在调用board_init_f()完成板卡与全局结构体变量 gd 的 ...

  5. u-boot启动流程分析(2)_板级(board)部分

    转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...

  6. imx6 uboot启动流程分析

    参考http://blog.csdn.net/skyflying2012/article/details/25804209 这里以imx6平台为例,分析uboot启动流程对于任何程序,入口函数是在链接 ...

  7. Uboot启动流程分析(三)

    1.前言 在前面的文章Uboot启动流程分析(二)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12002764.html 已经对_main函数的整个大体调用流程 ...

  8. Uboot启动流程分析(二)

    1.前言 在前面的文章Uboot启动流程分析(一)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12000889.html 已经简单地分析了low_level_i ...

  9. [国嵌笔记][030][U-Boot工作流程分析]

    uboot工作流程分析 程序入口 1.打开顶层目录的Makefile,找到目标smdk2440_config的命令中的第三项(smdk2440) 2.进入目录board/samsung/smdk244 ...

随机推荐

  1. javaIO缓冲区

    java中IO类分类. 图来自网络 缓冲区:应用程序在内存中开辟的一个空间.用来放置需要被写入或写出的数据. 使用缓冲区的 优点:使得应用程序操作磁盘(或者说是与磁盘的通信)的次数降低,提高应用程序的 ...

  2. 理解 Delphi 的类(十) - 深入方法[18] - 在接口区声明的方法都相当于提前声明了

    //要点18: 如果函数在接口区定义了, 就无需用 forward 提前声明了 unit Unit1; interface uses   Windows, Messages, SysUtils, Va ...

  3. POJ - 1062(昂贵的聘礼)(有限制的spfa最短路)

    题意:...中文题... 昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 54350   Accepted: 16 ...

  4. Educational Codeforces Round 4 B. HDD is Outdated Technology

    题目链接:http://codeforces.com/problemset/problem/612/B 解题思路: 一开始看错了题意,他要求的是从1-n所耗费的时间,n表示的是数值而不是下标, 实现代 ...

  5. JavaScript 隐式类型转换

    JavaScript 隐式类型转换 原文:https://blog.csdn.net/itcast_cn/article/details/82887895 · 1.1 隐式转换介绍 · 1.2 隐式转 ...

  6. 【刷题】BZOJ 1132 [POI2008]Tro

    Description 平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和 N<=3000 Input 第一行给出数字N,N在[3,3000] 下面N行给出N个点的坐标,其值在[0,10 ...

  7. 19+ JavaScript 常用的简写技巧

    博主说:对于任何基于 JavaScript 的开发人员来说,这绝对是一篇必读的文章,乃提升开发效率之神器也. 正文 js 1. 三元运算符 当你想用一行代码来写if...else语句的时候,使用三元操 ...

  8. 集成Android免费语音合成功能(在线、离线、离在线融合)

    集成Android免费语音合成功能(在线.离线.离在线融合),有这一篇文章就够了(离线)集成Android免费语音合成功能(在线.离线.离在线融合),有这一篇文章就够了(离在线融合) 转眼间,大半年没 ...

  9. BZOJ 3503 [CQOI2014]和谐矩阵

    题目链接 BZOJ 3503 题解 没想到--直接用暴力的\(O((nm)^3)\)算法,居然能过?! 高斯消元解异或方程组. #include <cstdio> #include < ...

  10. 分数拆分(Fractions Again?!, UVa 10976)

    题目链接:https://vjudge.net/problem/UVA-10976 It is easy to see that for every fraction in the form 1k(k ...