U-Boot启动流程分析 IMX6ULL


前言

在linux开发中,一个完整的Linux系统包含Bootloader,Linux kernel和Rootfile,而它的启动顺序也是Bootloader->Linux kernel->Rootfile,后者需要前者提供完整的功能支持。作为启动的第一步,Bootloader是嵌入式系统在加电后执行的第一段代码,在它完成CPU和相关硬件的初始化之后,再将操作系统映像或固化的嵌入式应用程序装载到内存中然后跳转到操作系统所在的空间,启动操作系统运行。而它的存在类似于PC上电时执行BIOS程序。
常见的Bootloader有:Redboot ARMboot U-boot Blob Bios-lt vivi Bootldr


一、uboot是什么?

uboot是SourceForge上的开源项目,它是由一个德国人最早发起的项目,然后由整个网络上所有感兴趣的人共同维护发展而来的一个bootloader。
uboot本质上是一个裸机程序(不是操作系统),它的入口就是开机自动启动,uboot的唯一出口就是启动内核。uboot还可以执行很多别的任务(譬如烧录系统),但是其他任务执行完后都可以回到uboot的命令行继续执行uboot命令,而启动内核命令一旦执行就回不来了。简单来说,uboot的生命周期在开机启动,到内核启动。

总结:一切都是为了启动内核。

二、uboot的启动流程

在IMX6ULL中,uboot的启动过程分为两个阶段。

  • 第一阶段:通常是开发板的配置等设备初始化代码,需要依赖依赖于SoC体系结构,通常用汇编语言来实现;
  • 第二阶段:准备启动内核,执行uboot命令。

1. 第一阶段

在uboot的第一阶段主要有:
  1. 获取uboot程序入口,通过连接脚本u-boot.lds找到程序入口arch/arm/lib/vectors.S文件中的_start
  2. 设置异常向量,设置中断模式为SVC模式,关闭FIQ和IRQ (reset 函数中)
  3. 关闭cache,MMU(cpu_init_cp15函数中)
  4. 对CPU初始化 开发板供电锁存(lowlevel_init.S)
  5. 设置运行环境,初始化DRAM,DDR,定时器,外设等
  6. 将uboot拷贝到DRAM最后面的内存区域中,为Linux腾出空间(加载uboot第二阶段代码到ROM中)
  7. 通过对DRAM整体使用规划,在DRAM中合适的地方设置栈。(设置好栈)
  8. 清除BSS段,远跳转到第二阶段执行入口board_init_r,第一阶段执行完(BSS段是用来存储静态变量,全局变量的)

2. 第二阶段

在第一阶段中,为第二阶段的函数调用提供了基础,比如gb结构,堆栈等,程序运行在main_loop中,根据获取到的bootcmd准备进入linux内核.
在第二阶段不管是bootz还是bootm命令,启动Linux的时候都会用到一个全局的变量:images,主要存放系统镜像相关数据.
而程序最终进入Linux内核的是do_bootm_linux()…

总结

uboot的启动流程还是比较复杂的,不仅涉及汇编代码部分,还有涉及到ARM处理器架构的内容,就IMX6ULL而言,uboot的启动流程还是需要花大量时间去理解的.

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐