嵌入式Linux引导过程之1.5——从BootRom到Xloader
在开始看Xloader_Entry的代码之前,我想先总结一下从芯片上电到开始运行Xloader的代码的过程,这是我目前理解的一个过程,可能有所出入,待以后继续完善。
当 系统上电之后,首先会将PC寄存器设置成BootRom里面的代码对应的一个地址。BootRom是芯片内部集成的一块很小的存储区,里面一般会固化一段 启动代码。至于BootRom所占用的地址空间,每个芯片的定义可能会有所不同,具体的可以参考芯片的用户手册中的Memory Map部分的说明。在spearplus中,BootRom位于从0xFF000000到0xFFFFFFFF的16M大小的地址区间。当 然,BootRom的大小不一定要那么大,这只是说,这些地方给你用了,具体你用了多少随你自己,够用就行。在spearplus里面是32k。
那 么BootRom有那么大的一片地址区域可以用,具体系统上电的时候会跳转到哪一个地址去执行代码呢?这就取决于CPU的定义了。对于spearplus 里面使用的ARM926EJS来说,它是这么定义的:Following reset, the ARM core starts to fetch instructions either from 0x00000000 or 0xFFFF0000 depending on the signal level of VINITHI* input signal to ARM
core. If after reset VINITHI signal level is LOW then ARM core will start fetching code from address 0x00000000 otherwise ARM core will start fetching code from 0xFFFF0000. So there must be some executable code accessible from either of this address. In an
embedded system, this requires some nonvolatile memory usually ROM or Flash to be present.
也就是说,ARM核在reset之后取得的第一条指令的 地址取决于给ARM核输入的一个信号VINITHI,如果在设计的时候给ARM输入的VINITHI信号是低电平,那么ARM核将从0x00000000 这个地址来获取它要执行的第一条指令,反之,如果给ARM输入的VINITHI信号是高电平,那么它将从0xFFFF0000地址处获取它要执行的第一条 指令。
spearplus系统中(由于spearplus系统含有两个ARM核,而在系统初始启动的时候系统的控制权完全在ARM1上,此时的 ARM2核是不可用的,因此在后面,我们所说的ARM核都是指ARM1核),在系统reset之后,输送给ARM核的VINITHI信号是一个高电平,因 此,在我们的系统中,系统在上电之后将会去地址0xFFFF0000处获取它所要执行的第一条指令。
我们发现,0xFFFF0000正好位于上面 所说的BootRom的地址区间之内,因此,我们BootRom中的第一条代码肯定是位于0xFFFF0000处的。这样在系统启动之后,就将从 0xFFFF0000处取得所需要执行的第一条指令。之后就将按照BootRom预先定义好的过程往下走了。由于BootRom处的代码(我们称之为 firmware,也就是在芯片出厂的时候就固化在芯片中的)我们是看不到的,因此我们只能根据文档中的描述来进行说明。
在spearplus的BootRom中,主要提供了三个功能(其他的板子或者芯片中的bootrom提供的功能应该也是类似的):
1、从NOR serial Flash引导系统
2、从NAND Flash引导系统
3、从USB引导或者更新系统
在这三个功能中,其中第3个功能我们暂且不说,因为这个是最主要使用来在最初的时候(除了BootRom之外既没有Xloader也没有U-Boot的情况时),用来将Xloader image或者uboot image烧写到相应的Flash中的。
我 们这里关心的主要是第1个和第2个功能。而从本质上来说,从NAND Flash引导和从NOR serial Flash引导应该是没有差别的,最主要的是这两种Flash的读写方式不同(另外,它们之间还有一个很重要的区别那就是NOR可以按字节寻址,也就是可 以直接在NOR上面运行程序,而不必拷贝到RAM中,但是NAND是按块寻址的,无法直接在其上运行程序。但是对于spearplus来说,不管是NOR 还是NAND,它的做法都是先将相应的代码拷贝到RAM中),因此在将Flash中的内容加载到内存中的相应的地址中执行的时候的加载过程可能会有所区
别。而对于我们的系统来说,使用的是NOR Flash,因此,这里重点分析从NOR serial Flash引导系统的情况。具体的NOR Flash和NAND Flash的差别可以参考文末的参考文章。
BootRom在开始执行程序的时候,如果被设置成从NOR引导(可以通过向 spearplus芯片提供几个信号,这几个信号的组合能够指定BootRom的功能,具体参考芯片手册),那么BootRom会首先在flash的首个 sector也就是第0号sector处检查是否有uboot存在,如果存在就直接跳转到uboot的代码处执行(因为在NOR上是可以直接运行程序 的)。由此可见,我们甚至可以不需要Xloader,而直接就从BootRom跳转到uboot执行代码(方法是直接将uboot image烧写到flash的第0号sector)。但是我们没有这么做,我们在uboot之前又放置了一层Xloader,这么做能够提高系统的灵活
性。
话说到这里,那么BootRom是怎么来判断到底在flash的第0号sector中有没有uboot image的呢?其实方法很简单,整个uboot image有两部分组成,一个部分就是由uboot源代码编译产生的目标文件(elf文件),另一部分就是一个64字节的image header,在这个image header中,有这个image的name属性、magic number属性、load address属性等等,具体的我们将在后续的文章中详细分析。这部分image header就是通过一个叫做mkimage的工具程序与之前编译链接产生的目标elf文件组合,最终生成uboot
image的。而image header就位于这个uboot image的开头64个字节处,紧接着的就是elf目标文件。而BootRom就是通过这个64个字节大小的image header中的某个或者某几个字段来判断在某一个位置是否存在某一个image的。对于判断在flash的第0号sector,BootRom会首先读 取头64个字节的内容,然后判断其中的name属性是不是约定的值("UBOO"或者"UBOOT"取决于实现时的约定),如果经判断确实是约定的值,那 么说明在sector 0上存在uboot image,否则则认为不存在。
显然,在我们的实现方案中,是不存在uboot的,因为我们在其上还放置了一层Xloader。
因 此,当BootRom发现在flash的sector 0中不存在uboot的时候,它会用同样的方法来判断其中是否存在Xloader image(同样,Xloader image也会有一个image header,事实上,Xloader image的image header的结构和uboot image的image header的结构是完全相同的),如果它判断存在Xloader image的时候,它就会将Xloader image加载到指定的SRAM的地址中(因为此时外部内存SDRAM还没有进行初始化,因此不可用,还记得我们之前分析的在Xloader中的
ddr_init吗?对,SDRAM就是在那里初始化的,因此Xloader都还没有起来呢,SDRAM就更不可能被初始化了。由于每个人使用的 SDRAM可能是不相同的,所以对SDRAM的初始化是不能够放在BootRom里面执行的。因此,此时只有芯片内部集成的8k的SRAM可用,因此 Xloader代码必须非常短小),然后跳转到该地址执行,将控制权交给了Xloader。从这里开始,就开始执行Xloader的代码了,也就是我们最 初分析的_start标号处的代码了。那么BootRom是如何知道Xloader image该加载到SRAM的哪个地址上的呢?又是如何在加载完之后跳转到这个地址的呢?问题的答案还是在那个image
header身上,刚才我们说过,在header的属性里面,有一个叫做load address的属性,这个属性就是BootRom和Xloader约定的那个地址。BootRom在读取到Xloader header中的load address这个属性之后,就会将xloader elf部分加载到该地址,然后跳转到load address指定的地址上执行代码。而这个load address则是由Xloader指定的,具体体现在Xloader的Makefile中的TEXT_BASE这个参数,这个参数在Xloader使用
ld进行链接的时候作为ld的参数将覆盖xloader.ldr文件中指定的代码运行起始地址,用以说明xloader指令的执行开始地址(通过ld的参 数-T xloader.lds -Ttext $(TEXT_BASE)来指定),另外,这个TEXT_BASE同时还会传递给mkimage这个工具程序,使得在最作Xloader image的时候,能够正确的设置image header中的load address这个属性。这样,整个过程也就完美了。
当然,如果BootRom在flash的sector 0处没有找到xloader image,那么它就会试图从NAND flash引导(前提是在设置BootRom的功能模式的时候同时还设置了允许从NAND引导)。如果再找不到,那么系统就会进入一个死循环。
在将程序的控制权成功交给Xloader之后,就是我们现在正在分析的代码部分了。
后续部分我们将接着一步一步来分析。
嵌入式Linux引导过程之1.5——从BootRom到Xloader的更多相关文章
- 嵌入式Linux引导过程之1.6——Xloader的Xloader_Entry
我们已经看完了XLOADER_ENTRY里调用的前两个标号的代码,分别是sys_init和ddr_init.对于一个嵌入式系统来说,这两 个部分的代码是在一开始就执行的,至少是在从bootrom里面的 ...
- 嵌入式Linux引导过程之1.4——Xloader的ddr_init
这里我们来看XLOADER_ENTRY中调用的第二个标号ddr_init处的代码,这部分代码的作用是对外部内存SDRAM进行初始化,在我 spearplus开发板中,使用的是DDR SDRAM.在调用 ...
- 嵌入式Linux引导过程之1.2——Xloader的XLOADER_ENTRY
根据上文中获得的线索,本文分析init.S中的XLOADER_ENTRY. 在init.S中,定义了好多与平台相关的寄存器地址宏以及好多其他函数,我们在用到的时候再回过头来分析,这里,我们只看其中的一 ...
- 嵌入式Linux引导过程之1.3——Xloader的sys_init
上一篇文章对XLOADER_ENTRY进行了分析,看到其中调用的第一个标号就是sys_init,本文就对这个标号对应的代码段进行粗略的分析,这里我也还有好多没有搞明白的,就先留着,日后慢慢明白,先把自 ...
- 嵌入式Linux引导过程之1.1——Xloader的xloader.lds
本文中的所有代码版本都是基于ST的SpearPlus开发板的. xloader是在系统上电之后,执行完ROM中的frimware后最先开始执行的用户程序,它的体积很小,执行的功能也很简单,主要是对系统 ...
- 嵌入式linux加载引导内核和根文件系统的方法
总体来说,嵌入式Linux内核和根文件的引导与PC机差不多.嵌入式linux内核和根文件系统可以存放在各种可能的存储设备中,一般情况下我 们将内核和根文件系统直接烧入到Flash中(包括NOR和NAN ...
- linux引导流程
本章重点: 1.linux引导流程 2.linux运行级别 3.linux启动服务管理 4.GRUB配置与应用 5.启动故障分析解决 linux启动流程 1.固件(fireware):固话在硬件上的程 ...
- 嵌入式Linux内核制作【转】
本文转载自:http://blog.csdn.net/coding__madman/article/details/51291316 1. Linux体系结构 从整体上来分,linux可以分为User ...
- 《嵌入式Linux基础教程学习笔记一》
常用书目下载地址:http://www.cnblogs.com/pengdonglin137/p/3688029.html 第二章 1.进程上下文和中断上下文(Page20) 当应用程序执行系统调用, ...
随机推荐
- Hyperledger Fabric Endorsement policies——背书策略
背书策略 背书策略用于指导peer如何确定交易是否得到了的认可.当一个peer接收到一个事务时,它会调用与事务的Chaincode相关联的VSCC(验证系统链代码),作为事务验证流程的一部分,以确定交 ...
- vhost-user 简介
什么是 vhost-user 在 vhost 的方案中,由于 vhost 实现在内核中,guest 与 vhost 的通信,相较于原生的 virtio 方式性能上有了一定程度的提升,从 guest 到 ...
- JAVA设计模式---迭代器模式
1.定义: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 2.实例:1)需求: 菜单(煎饼屋菜单.餐厅菜单和咖啡菜单)采用不同的集合存取(ArrayList,String[] ...
- 一道python面试题引发的血案
这里说的是一道阿里校招的面试题:一行代码实现对列表a中的偶数位置的元素进行加3后求和? 今天去面试同样遇到了这个题目,这道题考察的是对python高阶函数map/filter的灵活运用(具体的使用方法 ...
- POJ 3128 Leonardo's Notebook [置换群]
传送门 题意:26个大写字母的置换$B$,是否存在置换$A$满足$A^2=B$ $A^2$,就是在循环中一下子走两步 容易发现,长度$n$为奇数的循环走两步还是$n$次回到原点 $n$为偶数的话是$\ ...
- 关于js 全选 反选
prop 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法. attr 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法. $("#selectAll ...
- 常见HTTP状态码出现原因
302:重定向.访问当前地址,后端重新指定一个URL,浏览器跳转到新的地址. 303:对于POST请求,它表示请求已被处理,客户端可以接着使用GET方法请求Location里的URL. 304:客户端 ...
- 金融&业务常识积累
前言 在项目中遇到很多名词,不太明白其含义.这些名词都是和金融领域紧密相关并且与项目的业务有着直接的联系.因此,决定通过搜集资料和归纳总结,对经后的工作产生一定的帮助. 常见的金融知识 PDL: Pa ...
- PhpStorm使用之 —— Xdebug断点调试
PhpStorm使用之 -- Xdebug断点调试 在<XAMPP的配置与使用>中已经阐述了Xdebug插件的配置,Xdebug配置完成后,只需要在IDE工具中进行相关设置,便可启动Xde ...
- C++11 标准库也有坑(time-chrono)
恰巧今天调试程序遇到时间戳问题, 于是又搜了搜关于取时间戳,以及时间戳转字符串的问题, 因为 time() 只能取到秒(win和linux) 想试试看能不能找到 至少可以取到毫秒的, 于是, 就找 ...