一. uboot第二阶段初识

  1.1. uboot第二阶段应该做什么

    a. 概括来讲uboot第一阶段主要就是初始化了SoC内部的一些部件(譬如看门狗、时钟),然后初始化DDR并且完成重定位。

    b. 由宏观分析来讲,uboot的第二阶段就是要初始化剩下的还没被初始化的硬件。主要是SoC外部硬件(譬如iNand、网卡芯片····)、uboot本身的一些东西(uboot的命令、环境变量等····)。然后最终初始化完必要的东西后进入uboot的命令行准备接受命令。

  1.2. uboot第二阶段结束于何处

    a. uboot启动后自动运行打印出很多信息(这些信息就是uboot在第一和第二阶段不断进行初始化时,打印出来的信息)。然后uboot进入了倒数bootdelay秒然后执行bootcmd对应的启动命令。

    b. 如果用户没有干涉则会执行bootcmd进入自动启动内核流程(uboot就死掉了);此时用户可以按下回车键打断uboot的自动启动进入uboot的命令行下。然后uboot就一直工作在命令行下。
    c. uboot的命令行就是一个死循环,循环体内不断重复:接收命令、解析命令、执行命令。这就是uboot最终的归宿。

二. start_armboot解析1

  2.1. init_fnc_t类型

    2.1.1. typedef int (init_fnc_t) (void); 这是一个函数类型;并不是函数指针类型

    2.1.2. init_fnc_t **init_fnc_ptr;

      a. init_fnc_ptr是一个二重函数指针,回顾高级C语言中讲过:二重指针的作用有2个(其中一个是用来指向一重指针地址),一个是用来指向指针数组。因此这里的init_fuc_ptr可以用来指向一个函数指针数组。

  2.2. DECLARE_GLOBAL_DATA_PTR宏分析

#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")

    a. 定义了一个全局变量名字叫gd,这个全局变量是一个指针类型,占4字节

    b. 用volatile修饰表示可变的

    c. 用register修饰表示这个变量要尽量放到寄存器中,后面的asm("r8")是gcc支持的一种语法,意思就是要把gd放到寄存器r8中。

  2.3. gd和bd内存分配

    2.3.1. 内存当前没有被人管理(因为没有操作系统统一管理内存),大片的DDR内存散放着可以随意使用(只要使用内存地址直接去访问内存即可)。但是因为uboot中后续很多操作还需要大片的连着内存块,因此这里使用内存要本着够用就好,紧凑排布的原则。所以我们在uboot中需要有一个整体规划。

    2.3.2.内存排布

      a. uboot区 CFG_UBOOT_BASE-xx(长度为uboot的实际长度)
      b. 堆区 长度为CFG_MALLOC_LEN,实际为912KB
      c. 栈区 长度为CFG_STACK_SIZE,实际为512KB
      d. gd 长度为sizeof(gd_t),实际36字节
      e. bd 长度为sizeof(bd_t),实际为44字节左右
      f. 内存间隔 为了防止高版本的gcc的优化造成错误。

    2.3.3. 使用内存地址强制转化为gd和bd内存分配空间

gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);
#ifdef CONFIG_USE_IRQ
gd_base -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
#endif
gd = (gd_t*)gd_base;
#else
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
#endif /* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory"); memset ((void*)gd, , sizeof (gd_t));
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, , sizeof (bd_t));

最新文章

  1. ReportViewer内存泄漏问题解决方案[上]
  2. C语言再学习之内存对齐
  3. AES加密解密
  4. struct 类型重定义
  5. CodeForces - 404B(模拟题)
  6. 利用HTML5开发Android(6)---构建HTML5离线应用
  7. .Net Core 项目中的包引用探索(使用VSCode)
  8. C语言变参函数/Variadic fucntion
  9. 用Quartus II 建立一个工程模板,以后新建工程时无需再配置参数
  10. oracle 11g RAC Grid Infrastructure
  11. 记一次服务器Tomcat优化经历
  12. 1000以内完全数(完美数)获取实现---基于python
  13. 向ASP.NET Core迁移
  14. cocos2dx-3.0(14)------SpriteBatchNode与SpriteFrameCache加快渲染
  15. Service Worker和HTTP缓存
  16. ES6(正则扩展)
  17. Php如何返回json数据,前后端分离的基本解决方案
  18. 介绍Dynamics 365 Performance Center
  19. 关于Android的fragment的使用
  20. 两年前详细分析了ijkplayer的代码

热门文章

  1. kafka伪分布式安装(2.12版)
  2. PHP入门(四)
  3. 虚拟机安装 Output error file to the following location
  4. DOM事件处理函数
  5. #333 Div2 Problem B Approximating a Constant Range (尺取 && RMQ || 尺取 && multiset)
  6. #418 Div2 Problem B An express train to reveries (构造 || 全排列序列特性)
  7. rabbitmq 和 kafka 简单的性能测试
  8. [CF118D]Caesar's Legions 题解
  9. C++学习一二
  10. 搜索引擎算法研究专题五:TF-IDF详解