最近一段时间一直在做uboot移植相关的工作,需要将uboot-2016-7移植到单位设计的ARMv7的处理器上。正好元旦放假三天闲来无事,有段完整的时间来整理下最近的工作成果。之前在学习uboot时,在网上看了很多文章,很多都是基于老版本的的uboot,并且很多都是直接从代码开始分析,并没有将uboot与ARM处理器体系结构结合起来。毕竟很多时候做一件事情,你知道怎么去做这件事和你知道这件事为什么要这么去做两个不同的概念。即英文中常说的:how do?和 why do?
将2016年7月发布的新版本uboot移植到单位的板子上并进行了调试,在此也将我的学习成果分享给大家。文中有很多地方加入了我自己的理解,可能不太准确,希望大家提出修改意见。
开始深入了解处理器启动流程前,请准备好两个工具:
1.uboot-2016-7源码包
(开源的随便下载 官方下载地址:ftp://ftp.denx.de/pub/u-boot/ 下载u-boot-2016.07.tar.bz2)
2.代码阅读软件source insight
(推荐! 可以想象uboot源码包有10000多个文件,每个文件都有几百行甚至上千行代码。没有专业的代码阅读器如何查找函数原型。 当然不是全都需要看的! 根据自己的需要去查看)
同时下载好这几个技术文档
(笔者在学习uboot时阅读的几个文档 可以根据需求去查找阅读 完全没必要重头读到尾)
1.arm公司官方提供的ARMv7-A体系结构文档
《ARM® Architecture Reference Manual ARM®v7-A and ARM®v7-R 》
( 官方 品质保证! 如果觉得英文看着费劲 可以去看 杜春雷 《ARM体系结构与编程》 )
2.《Uboot中start.S源码的指令级的详尽解析_v1.6.pdf》(好吧 中文滴)
(对理解gnu arm汇编极其有帮助)
3.《ARM指令集快速查询手册.pdf》(中文滴)
(工具手册,快速查找各种arm指令用法)
4.《ARM指令详解[ARM标准].pdf》(还是中文滴)
(arm汇编的一些规范和常用形式,很多例子非常有用:子程序调用、散转、数据块复制等。对写裸机程序很有帮助,同样对理解uboot和内核启动代码有很大帮助)
5.《程序员的自我修养—链接、装载与库.pdf》(全是中文滴)
(里面会介绍ELF文件 程序链接的过程 最重要的部分就是帮助理解uboot的核心重定位!这个真的很重要!!)
好了,现在进入正题。
什么是uboot?
在嵌入式操作系统中,Boot Loader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由Boot Loader来完成。 uboot就是bootloader的一种,全称Universal Boot Loader。
目标:用uboot来启动单位设计的ARMv7的处理器。
问题:如何启动? 启动流程是什么?
首先,我先来描述一下需要移植uboot的这块板子上使用到的存储器(处理器架构可以暂时先不考虑,后面我会根据arm公司官方提供的ARMv7-A体系结构文档去分析uboot初始化处理器的汇编代码。无论是arm9 arm11 armv7 armv8都是相同的套路,首先需要根据存储器资源,去定制自己的启动流程)。在我手上的这块板子上使用存储器资源:Norflash(16MB) SRAM(512KB) SDRAM(512MB)。
看到这里应该想到两个问题:
1. Norflash SRAM SDRAM 作为存储器它们之间有何异同?
2. 如何通过它们去启动arm处理器?(重要的事情说三遍:先一定要理解启动流程 然后再去看uboot源码 要不然看了也无法理解 嵌入式的代码都是与硬件息息相关 了解硬件结构再去读代码 事半功倍)
下面我将对以上问题依次做出解析:
一. Norflash SRAM SDRAM 异同