U-BOOT移植过程详解: UBOOT启动过程

申明

  本着学习交流的原则, 将个人移植u-boot的过程做一个记录. 文章参考了csdn blog里面的很多内容, 有的已经记不得出处了, 只好把当时的摘要直接贴出来. 如果冒犯, 还请见谅. 如有侵权, 请与我邮件联系. 谢谢!


概念

地址无关

  • 地址无关是指代码在编译的时候,不论基于什么地址编译,在运行阶段,拷贝(或者直接在原地址运行,norflash)到任何地址都能正常运行

地址相关

  • 地址相关是指在代码编译的时候,如果基于某个地址编码,那么代码在运行阶段就必须要拷贝到这个地址才能运行.这种代码大多是高级语言编写的,比如在main函数里面调用init函数, init函数的地址是在编译阶段就确定的,这是个绝对地址.如果运行阶段的地址与编译阶段的不一样,跳转就会出问题了

嵌入式系统启动过程

  • RomBoot --> SPL --> u-boot --> Linux kernel --> file system --> start application
    • SPL: SPL是uboot新版本里面引进的一个概念. 它基本上是用地址无关的代码写成的. 主要目的是把uboot中真正做事情的stage2阶段的代码拷贝到外部RAM中去运行.SPL也可以理解为uboot的stage1阶段. 关于SPL的详细信息, 可以参考 http://blog.csdn.net/voice_shen/article/details/17373671
    • u-boot: uboot的stage2阶段.

UBOOT宏观执行流程

Stage1

Stage1部分代码是与地址无关,也就是拷贝到任何地方都能运行.如何做到这一点?需要在编写stage1的代码时候使用汇编语言,所有的命令跳转都是基于相对地址

  • 硬件设备初始化 :主要初始化CPU相关的时钟等
    • 这段代码一般在与CPU体系架构相关的start.S, arch/arch/cpu/armv7/start.S
  • 为加载Bootloader的第二阶段准备RAM空间 :主要是初始化外部RAM,因为一会要把stage2阶段的代码拷贝这个RAM中去
    • 这段代码一般放在板子相关的lowlevel_init.S,放在板级目录下是因为,不同的板子所焊接的RAM型号等时不一样的,初始化阶段配置的参数也会不一样
  • 复制Bootloader的stage2代码到RAM空间中
    • 这段代码一般在start.S,调用完lowlevel_init之后
  • 设置好栈 :因为stage2代码在运行阶段,调用某个函数时,会先把返回地址压栈,调用函数返回时,在从堆栈获取返回地址继续运行.中断的处理也涉及到类似的压栈出栈操作
  • bss段清零
  • 跳转到stage2代码的C入口点

Stage2

  • 初始化本阶段要使用的硬件设备
  • 检测系统内存映射
  • 将内核映像和根文件系映象从Flash搬移到RAM空间中
  • 为内核设置启动参数
  • 启动内核

启动内核

将内核存放在适当的位置后,直接跳到它的入口点即可调用内核,调用内核之前,下列条件要满足

  • CPU寄存器的设置
    • R0=0
    • R1=机器类型ID;对于ARM结构的CPU,其机器类型ID在linux/arch/arm/tools/mach-types
    • R2=启动参数标记列表在RAM中起始基地址
  • CPU工作模式
    • 必须禁止中断(IRQsFIQs)
    • CPU必须为SVC模式
  • Cach和MMU的设置
    • MMU必须关闭
    • 指令Cach可以打开也可以关闭
    • 数据Cach必须关闭

UBOOT详细执行流程

  1. 配置uboot
    • make xxxx_config
    • 这个命令会执行Makefile中的%_config:: unconfig 这个目标, 进而调用mkconfig. 具体分析见下一篇"添加一块新板子支持"
  2. 编译uboot
    • make
      • 首先更新autoconf.mk
      • 将配置阶段生成的include/config.mk包含进来
      • 将U-Boot顶层目录下的include.mk文件包含进来,该文件包含了对编译的一些设置
      • 执行all: $(ALL-y) $(SUBDIR_EXAMPLES)这个目标

你可能感兴趣的:(u-boot)