"本章主要分析了ARM架构下Uboot启动的第一阶段代码,特别是涉及了启动流程、链接脚本分析、start.S文件解析以及板级初始化和进入Linux内核的细节。"
在ARM架构中,当系统上电后,处理器的第一个指令通常是由硬件预设的,这取决于具体的CPU型号。例如,S3C2440这样的CPU在上电时,程序计数器(PC)可能被设置在Nor Flash或Nand Flash中的特定地址,从而执行第一条指令。Nor Flash和Nand Flash的区别在于访问方式和数据存储结构,Nor Flash通常可以直接执行其中的代码,而Nand Flash则需要先读取到内存中才能执行。
Uboot的启动流程始于链接脚本`uboot.lds`的解析,这个脚本定义了Uboot在内存中的布局,包括代码段、数据段、初始化零段(bss段)等。分析链接脚本有助于理解Uboot如何在内存中分布和如何被加载。
在`start.S`文件中, `_start`是程序的入口点,它负责初始化处理器状态,如关闭中断,初始化寄存器,并调用`reset`函数进行CPU复位。接着,`cpu_init_cp15`初始化CP15协处理器,用于管理内存映射和高速缓存等。`cpu_init_crit`确保关键区的初始化,`lowlevel_init`进行低级硬件初始化,比如设置时钟和其他外设。
`board_init_f`是板级初始化的一部分,它调用`call_board_init_f`执行特定于板子的初始化任务,如设置GPIO、初始化时钟、内存检测等。`relocate_code`将Uboot从ROM复制到RAM中,`clear_bss`清零bss段,`jump_2_ram`则跳转到RAM中继续执行,此时Uboot进入了第二阶段。
在`board_init_r`函数中,Uboot进一步完成板级初始化,并准备跳入Linux内核。`board_init_r`会设置参数,如全局数据结构`gd_t`,然后调用`jump_to_linux`或类似的函数,将控制权交给Linux内核。
Uboot还包含了异常处理机制,通过异常向量表和对应的处理函数来处理各种异常情况,如数据或预取指异常,保证系统的稳定运行。
这个章节深入剖析了Uboot在ARM平台上的启动过程,涵盖了从上电到Linux内核接管的各个关键步骤,这对于理解和调试嵌入式系统的启动流程至关重要。通过这样的分析,开发者可以更好地理解和定制Uboot以适应特定的硬件需求。