一、U-boot启动流程
boot的启动大致可分为两个阶段:
stage1:使用汇编完成CPU的初始化
stage2:通过C语言分board_init_f 和 board_init_r 两个阶段完成外设的初始化
U-Boot在启动过程中,需要将自身代码、环境变量、内核等数据从外部的RAM加载到速度更快,性能更好的DDR内部中。首先,将U-Boot的二进制代码从Flash存储器中读取出来,加载到DDR的一个预设地址(通常是RAM的低地址区域)。然后,找到链接脚本(u-boot.lds)中制定的入口点,并开始执行u-boot的初始化代码。在执行初始化代码的过程中,会对U-boot代码中的变量、函数、环境变量等进行重定位(重定位就是u-boot将自身拷贝到DDR的另一个地方去继续运行(高地址处)),将它们的地址修正成正确的地址,以便在程序执行时能够正确地访问这些变量及函数,避免与操作系统或其他程序运行时所使用的内存区域发生冲突(重定位的原因)。主要过程如下:
- reset函数将处理器设置为SVC模式,并且关闭 FIQ 和 IRQ(在u-boot启动阶段不需要中断触发什么事件,避免干扰代码,使用CPSR禁用),设置中断向量表可重定位,并设置中断向量偏移,初始化CP15;
- lowlevel_init函数设置 SP 指针(任何C程序运行都要设置堆栈指针用于存储函数参数、局部变量和返回地址)、R9 寄存器(存储全局数据指针),调用 s_init (空函数);
- _main函数主要调用 board_init_f、relocate_code、relocate_vectors 和 board_init_r 这 4 个函数;
- board_init_f 函数初始化一系列外设,比如DDR、串口、定时器,或者打印一些消息等,初始化 gd(gd是全局数据(global_data)结构的一个指针,它包含了整个引导加载器运行过程中所需的各种信息。初始化gd的各个成员变量是U-Boot启动过程的关键部分) 的各