TQ2440 学习笔记—— 30、移植U-Boot【U-Boot 的启动过程第一阶段源码分析】

2019-07-13 02:16发布

(韦东山——嵌入式Linux 应用开发完全手册) 使用u-boot 从NOR Flash 启动,前面说过u-boot 属于两个阶段的Bootloader ,第一阶段的文件为cpu/arm920t/start.S 和 board/EmbedSky/lowlevel_init.S, 前者是平台相关的,后者是开发板相关的。
一、u-boot 第一阶段代码分析 (1)硬件设备初始化 依次完成如下设置:将CPU 的工作模式设为管理模式(svc),关闭WATCHDOG ,设置FCLK、HCLK、PCLK 的比例(即设置CLKDIVN寄存器),关闭MMU、CACHE。部分代码如下:

(2)为加载Bootloader 的第二阶段代码准备RAM 空间 所谓准备RAM 空间,就是初始化内存芯片,使它可用。通过在start.S 中调用lowlevel_init 函数来设置存储控制器,使得外接的SDRAM可用。lowlevel_init 函数在board 文件夹里面。 lowlevel_init 函数并不复杂,只要注意这时的代码、数据都只保存在NOR Flash 上,内存中还没有,所以读取数据时要变换地址。代码如下:

第174~176 行进行地址变换,因为这个时候内存中还没有数据,不能使用链接程序时确定的地址来读取数据。 第174行中SMRDATA 表示这13个寄存器的值存放的开始地址(链接地址),值为0x33D0xxxx ,处于内存中。 第175行获得代码段的起始地址,它就是167行中的“TEXT_BASE”,其值在board/EmbedSky/config.mk 中定义为”TEXT_BASE = 0x33D00000“。 第176行将0x33D0xxxx 与0x33D00000相减,这就是13 个寄存器值在NOR Flash 上存放的开始地址。
(3)复制 Bootloader 的第二阶段代码到RAM空间中 这里将整个u-boot 的代码(包括第一、第二阶段)都复制到SDRAM 中,这在cpu/arm920t/start.S 中实现,如下所示:

(4)设置好栈 栈的设置灵活性很大,只要让sp寄存器指向一段没有使用的内存即可。

(5)跳转到第二阶段代码的C入口点 在跳转之前,还要清楚BSS段(初始值为0、无初始值的全局变量、静态变量放在BBS段),代码如下:

现在C函数的运行环境已经完全准备好,通过如下命令直接跳转(这之后,程序才在内存中执行),它将调用lib_arm/board.c 中的start_armboot 函数,这是第二阶段的入口点。