请教boot block到底是什么?
1.对于zlg的开发板,boot block的内容是否就是开发模板里的那些文件编译成ELF再传到Flash中?
2.还有用户程序是放在Flash的哪个地方?Flash开始64字节和结尾8k字节之间?
ZLGARM:
boot block 是芯片设计厂家在LPC2000系列微控制器内部固化的一段代码,用户无法对其修改和删除。这段代码在芯片复位后首先被运行,其功能主要是判断运行那个存储器上的程序、检查用户代码是否有效、判断芯片是否被加密、芯片的在应用以及在系统编程功能。
--------------------------------------------------------------------
ARM上的Bootloader的具体实现
BootLoader简介:
当完成用户程序的编译并下载到目标板上运行时,总是要首先进行存储器的映射,然后通过 ADS(或 SDT)调试环境下载,显然,这个过程对普通用户来说显得特别烦琐,然而,要在裸板(没有任何程序的系统板)上调试运行程序,也只能采用这种方法。
如果能在用户设计的系统板上烧写一段 BootLoader程序,就可以将该过程屏蔽起来,让用户通过一些简单的操作,就可完成程序的下载、调试等工作。在嵌入式系统中,BootLoader的作用与 PC 机上的 BIOS 类似,通过 BootlLoader可以完成对系统板上的主要部件如 CPU、SDRAM、Flash、串行口等进行初始化,也可以下载文件到系统板、对 Flash 进行擦除与编程。事实上,一个功能完善的 BootLoader 已经相当于一个微型的操作系统了。
BootLoader 作为系统复位或上电后首先运行的代码,一般应写入 Flash 存储器中并从起始物理地址 0x0 开始。BootLoader 根据实现的功能不同而不相同。一个简单的 BootLoader程序可以仅仅完成串行口的初始化,并进行通信,而功能完善的 BootLoader可以支持比较复杂的命令集,对系统的软硬件资源进行合理的配置与管理。因此,用户可根据自身的需求实现相应的功能。
涉及具体汇编代码前,有些术语要必须弄懂的
对于一个ARM bootloader系统来说,本质上,bootloader作为引导与加载内核镜像的工具,必须提供以下几个功能:
~1~初始化RAM(必需):bootloader应该能初始化RAM,因为将来系统要通过它来保存一些Volatile数据,但具体地实现要求依赖与具体的CPU以及硬件系统。
~2~初始化串口(可选),bootloader应该要初始化及使能一个串口,通过它与控制台联系进行一些debug的工作;甚至与PC通信。
~3~创建内核参数列表(针对linux操作系统,推荐)。
~4~启动内核镜像(必需):根据内核镜像保存的存储介质不同,可以有两种启动方式:FALSH启动以及RAM启动;但是无论是哪种启动方式,下面的系统状态必须得到满足:
Bootloader 阶段1的代码实现:
1,定义ARM个模式的栈大小
2,申明各模式的栈
3,将各模式的栈与栈大小结合起来,既为各栈分配栈大小
4,申明一些标号量
5,以某标号标识,一开始处设置异常中断向量表,当冷启动时,直接跳转至对应处启动
为什么在中断向量表中不直接LDR PC,"异常地址".而是使用一个标号,然有再在后面使用DCD 定义这个标号
A:因为LDR 指令只能跳到当前PC 4kB 范围内,而B 指令能跳转到32MB 范围,而现在这样在LDR PC,"xxxx"这条指令不远处用"xxxx"DCD 定义一个字,而这个字里面存放最终异常服务程序的地址,这样可以实现4GB 全范围跳转.
如:LPC2220的复位与存储器映射芯片复位后,MAP=00,启动boot装载程序,boot装载程序检测P0.14口的状态和用户的异常向量表,判断是进入ISP还是启动用户程序,若启动用户程序,则自动设置MAP=1或3。若用户程序需要更改异常向量表,可以将异常向量表复制到片内0x40000000,然后设置MAP=2进行重新映射,0x40000000地址上的向量表就可以更改了。
LPC2220在复位运行的第一段程序并不是用户程序,而是boot block(引导模块),是设计厂家在ARM内部固化的一段代码,用户无法修改或删除,其主要功能为:
boot block(包括bootload 和64字节异常向量表)。
对于LPC2220,复位后(也即是运行完Boot Block后),用户所能见到的存储空间,及其各存储空间上的内容:
0xF0000000----0xFFFFFFFF:AHB外设;
0xE0000000----0xEFFFFFFF:VPB外设;
0x80000000----0xDFFFFFFF;保留给外部存储器;
0x7FFFDFFF---0x7FFFE000;BOOT BLOCK;
0x40004000----0x4000FFFF;64KB片内RAM;
0x00000000—0x0000003f,ARM异常向量位置;
存储器映射控制:
MAP=00:由任何硬件复位激活,boot block中断向量映射到存储器的底部以允许处理异常。
MAP=01:中断向量表没有被重新映射,它位于存储器的底部。
MAP=10:由用户程序激活,中断向量表重新映射到静态RAM的底部。
MAP=11:用户外部模式,由BOOT[1:0]来控制存储器的引导方式,中断向量表重新映射到外部存储器的底部。
例如:每当产生一个软件中断,ARM内核就从0x00000008处取出32位数据,当MAP=0x11时,这就意味着从0x00000008处取值既是对0x80000008处取值。存储器重新映射控制用于改变从地址0x00000000开始的中断向量表的映射,使就使得运行在不同存储器空间中的代码对中断的控制。
拿LPC说
上电后bootblock 检测是否有ISP的相关引脚被设定,如果设定进入ISP模式,如果没有设定运行用户程序(一般来说时用户的BootLoader),然后启动内核或者其他的。关于异常向量表,配置好你自己的就可以了,不用管 bootblock上的!
1 设置异常中断向量表
ARM处理器的中断向量表从地址0x0处开始存放,连续有8×4字节的空间。在ARM存储空间里每个字32位,占4个字节。可以通过图1来描述中断向量表的地址分配。
每当有中断或者异常发生时,ARM处理器便强制把PC指针指向向量表中对应中断类型的地址值。为了加快中断响应,我们在Flash的0x0地址存放能跳转到0x0c000008地址处中断向量的跳转指令,即在RAM中建立一个二级中断向量表,起始地址为0x0c000008,除复位外,其它异常入口地址由Flash跳转得到,如表1所示:
---------------------------------------------------
关于ARM的一些概念
3. VIC 使用注意事项
答:如果在片内RAM当中运行代码并且应用程序需要调用中断,那么必须将中断向量重新映射到Flash地址0x0。这样做是因为所有的异常向量都位于地址0x0及以上。通过将寄存器MEMMAP(位于系统控制模块当中)配置为用户RAM模式来实现这一点。用户代码被连接以便使中断向量表装载到0x4000 0000。
4. ARM启动代码设计
答:ARM启动代码直接面对处理器内核和硬件控制器进行编程,一般使用汇编语言。启动代码一般包括:
中断向量表
初始化存储器系统
初始化堆栈初始化有特殊要求的端口、设备
初始化用户程序执行环境
改变处理器模式
呼叫主应用程序
5. IRQ 和 FIQ 之间的区别
答:IRQ和FIQ是ARM处理器的两种编程模式。IRQ是指中断模式,FIR是指快速中断模式。对于 FIQ 你必须尽快处理你的事情并离开这个模式。IRQ 可以被 FIQ 所中断,但 IRQ 不能中断 FIQ。为了使 FIQ 更快,所以这种模式有更多的影子寄存器。FIQ 不能调用 SWI(软件中断)。FIQ 还必须禁用中断。如果一个 FIQ 例程必须重新启用中断,则它太慢了,并应该是 IRQ 而不是 FIQ。
6. ARM处理器对异常中断的响应过程
答:ARM处理器对异常中断的响应过程如下所述:
保存处理器当前状态、中断屏蔽位以及各条件标志位;
设置当前程序状态寄存器CPSR中的相应位;
将寄存器lr_mode设置成返回地址;
将程序计数器值PC,设置成该异常中断的中断向量地址,跳转到相应异常中断处执行。
14. 存储器重新映射的原因:
使Flash存储器中的FIQ处理程序,不必考虑因为重新映射所导致的存储器边界问题;
用来处理代码空间中段边界仲裁的SRAM和Boot Block向量的使用大大减少;
为超过单字转移指令范围的跳转提供空间来保存常量。
ARM中的重映射是指:在程序执行过程中,通过写某个功能寄存器位操作,达到重新分配其存储器地址空间的映射。一个典型的应用就是应用程序存储在Flash/ROM中,初始这些存储器地址是从0开始的,但这些存储器的读时间比SRAM/DRAM长,造成其内部执行频率不高,故一般在前面一段程序将代码搬移到SRAM/DRAM中去,然后重新映射存储器空间,将相应SRAM/DRAM映射到地址0,重新执行程序可达到高速运行的目的。
18. VIC的基本操作如下:
答:设置IRQ/FIQ中断,若是IRQ中断则可以设置为向量中断并分配中断优先级,否则为非向量IRQ。然后可以设置中断允许,以及向量中断对应地址或非向量中断默认地址。
当有中断后,若是IRQ中断,则可以读取向量地址寄存器,然后跳转到相应的代码。当要退出中断时,对向量地址寄存器写0,通知VIC中断结束。当发生中断时,处理器将会切换处理器模式,同时相关的寄存器也将会映射。
19. 使用外部中断注意
把某个引脚设置为外部中断功能后,该引脚为输入模式,由于没有内部上拉电阻,所以必须外接一个上拉电阻,确保引脚不被悬空;
除了引脚连接模块的设置,还需要设置VIC模块,才能产生外部中断,否则外部中断只能反映在EXTINT寄存器中;
要使器件进入掉电模式并通过外部中断唤醒,软件应该正确设置引脚的外部中断功能,再进入掉电模式。
---------------------------------------------------
ARM LPC2104的Boot与Remap详解
随着半导体工艺技术与处理器设计技术的不断提高,嵌入式处理器的速度愈来愈快;而非易失性存储器的读取速度却远远跟不上CPU的发展。传统的单片机运行模式中,机器代码存储在非易失性存储器(如ROM,FLASH),在运行时由CPU直接从其中取出指令执行,逐渐显得力不从心。如果继续沿用传统的程序运行模式,那么在绝大多数时间内高速CPU将处于空闲等待状态,这既浪费了CPU的计算能力,也无法实现高密度数据流的实时处理与传输。而在短期之内,半导体工业界尚无法实现低成本的非易失性高速存储器技术。为了解决上述处理器和非易失性存储器之间速度不匹配的矛盾,工程师们在嵌入式系统领域内引用了Boot技术和Remap技术。而要正确理解Boot技术和Remap技术,必须先建立Memory Map(存储器映射)的概念。
技术概念描述
Memory Map
在嵌入式处理器内,集成了多种类型的Memory,通常,我们称同一类型的Memory为一个Memory Block。一般情况下,处理器设计者会为每一个Memory Block分配一个数值连续、数目与其存储单元数相等、以16进制表示的自然数集合作为该Memory Block的地址编码。这种自然数集合与Memory Block的对应关系,就是Memory Map(存储器映射),有时也叫Address Map(地址映射)。实际上,Address Map在字面意义上更加贴切。
需要强调的是,Memory Map是一个逻辑概念,是计算机系统在(上电)复位后才建立起来的。 Memory Map相当于这样一个数学函数:函数的输入量是地址编码,输出量被寻址单元中的数据。当计算机系统掉电后或复位时,这个数学函数不复存在,只剩下计算机系统中实现这个数学函数的物理基础:电路连接。也可以这样认为:Memory Map是计算机系统(上电)复位时的预备动作,是一个将CPU所拥有的地址编码资源向系统内各个物理存储器块分配的自动过程。
Boot/Bootload
Boot在计算机专业英文中的意思是“引导”,它是计算机系统(上电)复位后CPU的第一个机器动作。那么,Boot引导的是什么呢?简要地说,Boot就是引导CPU如何装入机器指令。最简单的Boot动作就是8位单片机系统复位后从复位向量中取出跳转指令,转移到用户程序代码段执行的这个过程。
通常,在计算机系统中,(上电)复位后除了执行Boot动作,还跟随着一个Load过程。一般情况下,该Load从低速非易失性存储器中“搬运”一些数据到高速易失性存储器中。Boot和Load连续执行,一气呵成,我们称之为Bootload。最典型的例子之一就是DSP实时信号处理系统,系统上电后,将存储在EEPROM中的实时信号处理程序复制到系统的RAM中,然后CPU直接从RAM中读取机器指令运行。
Remap
Remap与计算机的异常处理机制是紧密相关的。
完整的计算机系统必须具备异常处理能力。当异常产生时,CPU在硬件驱动机制下跳转到预先设定的存储器单元中,取出相应的异常处理程序的入口地址, 并根据该入口地址进入异常处理程序。这个保存有异常处理程序入口地址的存储器单元就是通常所说的“异常入口”,单片机系统中也叫“中断入口”。实际的计算机系统有多种类型的异常,CPU设计人员为了简化芯片设计,一般将所有的异常入口集中起来置于非易失性存储器中,并在系统上电时映射到一个固定的连续地址空间上。位于这个地址空间上的异常入口集合就是“异常向量表”。
系统上电后的异常向量表是从低速非易失性存储器映射得到的。随着处理器速度的不断提高,很自然地,人们希望计算机系统在异常处理时也充分发挥出CPU的处理能力,而非易失性存储器的读取速度使得CPU只能以多个空闲等待同期来获取异常向量,这样就限制了CPU计算能力的充分发挥。尤其是非易失性存储器位宽小于CPU位宽时,这种负面的影响更加明显。于是,Remap技术被引入,以提高系统对异常的实时响应能力。
从Remap这个英文单词的构成不难看出,它是对此前已确立的存储器映射的再次修改。从本质上讲,Map和Remap是一样的,都是将地址编码资源分配给存储器块,只不过二者产生的时间不同:前者在系统上电的时刻发生,是任何计算机系统都必需的;而后者在系统上电后稳定运行的时刻发生,对计算机系统设计人员来说是可选的。典型的8位单片机系统中,就没有使用Remap技术。
完整的Remap过程实际上通常始于系统的Bootload过程。具体执行动作为:Bootload将非易失性存储器中的异常向量复制到高速易失性存储器块的一端,然后执行Remap命令,将位于高速易失性存储器中的异常向量块映射到异常向量表地址空间上。此后,系统若产生异常,CPU将从已映射到异常微量表地址空间的高速非易失性存储器中读取异常向量。具体到典型的ARM7嵌入式系统中,就是由Bootload程序将片内或片外的Flash/ROM中的异常向量复制到片内的SRAM中指定的存在器单元中,然后再执行Remap命令。由于片内的SRAM数据位宽通常与CPU数据位宽相等,因而CPU可以无等待地全速跳入异常处理程序,获得最佳的实时异常响应。
----------------------------------------------------
BOOT Block重映射的意义
BOOT Block是芯片设计厂家在LPC2000系列ARM内部固化的一段代码,它在芯片复位后被首先运行,其功能主要是判断运行哪个存储器上的程序、检查用户代码是否有效、判断芯片是否被加密、芯片的在应用编程(IAP)以及在系统编程功能(ISP)。这其中有些程序是可以被用户调用的,比如擦写片内FLASH的IAP代码。
为了增加用户代码的可移植性,所以最好能把BOOT Block的代码固定在某个地址上。但是因为各个芯片的片内FLASH大小不尽相同,如果把BOOT Block的地址安排在片内FLASH结束的位置上,那么就无法实现BOOT Block地址的固定。所以芯片生产商把BOOT Block的地址重映射到片内存储器空间的最高处,即接近2G(0x80000000)的地方,这样无论片内存储器大小如何,都不会影响BOOT Block的地址。可以让包含有IAP操作的用户代码,不用修改IAP操作地址,就可以在不同的LPC2000系列ARM上运行。
-----------------------------------------------------------
ARM的存储器映射与存储器重映射【】
存储器映射:是指把芯片中或芯片外的FLASH,RAM,外设,BOOTBLOCK等进行统一编址。即用地址来表示对象。这个地址绝大多数是由厂家规定好的,用户只能用而不能改。用户只能在挂外部RAM或FLASH的情况下可进行自定义。
ARM7TDMI的存储器映射可以有0X00000000~0XFFFFFFFF的空间,即4G的映射空间,但所有器件加起来肯定是填不满的。一般来说, 0X00000000依次开始存放FLASH——0X00000000;SRAM——0X40000000;BOOTBLOCK,外部存储器 0X80000000;VPB(低速外设地址,如GPIO,UART)——0XE0000000;AHB(高速外设:向量中断控制器,外部存储器控制器) ——从0XFFFFFFFF回头。他们都是从固定位置开始编址的,而占用空间又不大,如AHB只占2MB,所以从中间有很大部分是空白区域,用户若使用这些空白区域,或者定义野指针,就可能出现取指令中止或者取数据中止。
由于系统在上电复位时要从0X00000000 开始运行,而第一要运行的就是厂家固化在片子里的BOOTBLOCK,这是判断运行哪个存储器上的程序,检查用户代码是否有效,判断芯片是否加密,芯片是否IAP(在应用编程),芯片是否ISP(在系统编程),所以这个BOOTBLOCK要首先执行。而芯片中的BOOTBLOCK不能放在FLASH的头部,因为那要存放用户的异常向量表的,以便在运行、中断时跳到这来找入口,所以BOOTBLOCK只能放在FLSAH尾部才能好找到。而ARM7的各芯片的FLASH大小又不一致,厂家为了BOOTBLOCK在芯片中的位置固定,就在编址的2G靠前编址的位置虚拟划分一个区域作为BOOTBLOCK 区域,这就是重映射,这样访问<2G即<0X80000000的位置时,就可以访问到在FLASH尾部的BOOTBLOCK区了。
BOOTBLOCK运行完,就要运行用户自己写的启动代码了,而启动代码中最重要的就是异常向量表,这个表是放在FLASH的头部首先执行的,而异常向量表中要处理多方面的事情,包括复位、未定义指令、软中断、预取指中止、数据中止、IRQ(中断) ,FIQ (快速中断),而这个异常向量表是总表,还包括许多分散的异常向量表,比如在外部存储器,BOOTBLOCK,SRAM中固化的,不可能都由用户直接定义,所以还是需要重映射把那些异常向量表的地址映到总表中。
为存储器分配地址的过程称为存储器映射,那么什么叫存储器重映射呢?为了增加系统的灵活性,系统中有部分地址可以同时出现在不同的地址上,这就叫做存储器重映射。重映射主要包括引导块“Boot Block”重映射和异常向量表的重映射。
1.引导块“Boot Block”及其重映射
Boot Block是芯片设计厂商在LPC2000系列ARM内部固化的一段代码,用户无法对其进行修改或者删除。这段代码在复位时被首先运行,主要用来判断运行哪个存储器上面的程序,检查用户代码是否有效,判断芯片是否被加密,系统的在应用编程(IAP)以及在系统编程功能(ISP)等。
Boot Block存在于内部Flash,LPC2200系列大小为8kb,它占用了用户的Flash空间,但也有其他的LPC系列不占用FLash空间的,而部分没有内部Flash空间的ARM处理器仍然存在Boot Block。
重映射的原因:
Boot Block中有些程序可被用户调用,如擦写片内Flash的IAP代码。为了增加用户代码的可移植性,所以最好把Boot Block的代码固定的某个地址上。但由于各芯片的片内Flash大小不尽相同,如果把Boot Block的地址安排在内部Flash结束的位置上,那就无法固定Boot Block的地址。
为了解决上面的问题,于是芯片厂家将Boot Block的地址重映射到片内存储器空间的最高端,即接近2Gb的地方,这样无论片内存储器的大小如何,都不会影响Boot Block的地址。因此当Boot Block中包含可被用户调用的IAP操作的代码时,不用修改IAP的操作地址就可以在不同的LPC系列的ARM上运行了。
2.异常向量表及其重映射
ARM内核在发生异常后,会使程序跳转到位于0x0000~0x001C的异常向量表处,再经过向量跳转到异常服务程序。但ARM单条指令的寻址范围有限,无法用一条指令实现4G范围的跳转,所以应在其后面的“0x0020~0x003F”地址上放置跳转目标,这样就可以实现4G范围内的任意跳转,因此“一个异常向量表实际上占用了16个字的存储单元”。以下为一张中断向量表:
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, FIQ_Addr
ResetAddr DCD ResetInit
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
重映射的原因:
由于ARM处理器的存储器结构比较复杂,可能同时存在片内存储器和片外存储器等,他们在存储器映射上的起始地址都不一样,因此ARM内核要访问的中断向量表可能不在0x0000~0x003F地址上,因此采用了存储器重映射来实现将存在与不同地方的中断向量表都映射到0x0000~0x003F地址上。
注意:Boot Block 也存在中断向量表,而且复位后这段代码首先映射到 0x0000~0x003F地址上,也就是说复位后首先运行的是Boot Block程序。各个存储区域的中断向量表也不尽相同。