TQ2440 学习笔记—— 30、移植U-Boot【U-Boot 的启动过程第一阶段源码分析】
2015-09-07 09:30
991 查看
(韦东山——嵌入式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 函数,这是第二阶段的入口点。
使用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 函数,这是第二阶段的入口点。
相关文章推荐
- Xutils和Volley请求服务器的使用
- Java IO流学习总结
- 折半查找法
- LINUX中编译程序时,-I,-L,-l 的区别
- android权限管理, API劫持, xposed, xprivacy
- centos6.5编译安装LNMP架构web环境
- 设计模式-状态模式
- Spring MVC+Mybatis入门学习小项目实例
- 用Eclipse运行selenium脚本时弹出浏览器导入向导设置的解决方法
- malloc/free与new/delete的区别
- Fixing security sandbox violation in Flash AS3
- 自适应reset.js布局 用于手机端页面编写
- awk统计文本里某一列重复出现的次数
- 通过XMLHttpRequest和jQuery实现ajax的几种方式
- 将一个十进制转换为二进制,八进制,十六进制
- android studio gradle project sync failed,和android studio Error:Unable to start the daemon process问题
- Mysql 删除重复的记录
- SortedList
- jQuery介绍 DOM对象和jQuery对象的转换与区别
- You Can’t Future-Proof Solutions