作为一个嵌入式工程师,假如不能写bootloader程序,那就不能成为一个真实的嵌入式工程师.曾经做linux driver,常对bootloader程序是一知半解,其实要写好bootloader程序还得好好去研读一下处理器 architecture.
ARM 处理器是一种很抢手的嵌入式处理器,现在绝大部分的嵌入式产品都用到了ARM处理器,其低价的价格和丰厚的功用都受到的顾客的喜爱.下面针对ARM处理器来具体谈一下ARM bootloader程序.
首要简略的了解一下ARM architecture.ARM首要由ARM内核单元,vector interface ,coprocessor,两种cache(instruction and data),两种TCM(instruction and data), MMU, power management等. cache是为了平衡数据之间的速度而运用的,而TCM是为了存储一些频频运用的数据,如中断向量等,MMU首要处理虚拟地址到物理地址的转化,起到了对数据的维护效果,用在操作体系的体系中,很显然,bootloader程序便是要为后来的程序供给一个杰出的运转环境,这儿对ARM architecture的几个组成单元进行必要的装备.
综上所述,ARM bootloader程序首要完结下面几个功用:
1)初始化栈.
2)中断向量表的仿制.
3)TCM 和cache的装备,假如有操作体系的话,就应该设置MMU.
4)树立一个程序履行文境.(具体一点,便是依据image文件的特点来处理image段的数据).
5)对内存如mddr,sram进行简略的测验.
6)需求设置一些外围设备,一般来说需求装备一下串口.
一、初始化栈:
应该对irq,firq,svc的栈进行指定,别离操作这几中形式的寄存器。如对irq形式.
mov r0 , #0x12; irq mode
msrCPSR , r0; set irq mode
ldr sp, =0x800; irq steak address
二、中断向量表的仿制:
Boot_Def
ldrPC,Arm_Addr_Ini;0x00
ldrPC,Arm_Addr_Und;0x04
ldrPC,Arm_Addr_Swi;0x08
ldrPC,Arm_Addr_Pre;0x0C
ldrPC,Arm_Addr_Abt;0x10
nop;0x14
ldrPC,Arm_Addr_Irq;0x18
ldrPC,Arm_Addr_Fiq;0x1C
Arm_Addr_IniDCDbootstrap_entry + 0x00;0x20
Arm_Addr_UndDCDundefined_exception_handler;0x24
Arm_Addr_SwiDCDsoftware_interrupt_handler;0x28
Arm_Addr_PreDCDprefetch_exception_handler;0x2C
Arm_Addr_AbtDCDabort_exception_handler;0x30
Arm_Addr_IrqDCDirq_interrupt_handler;0x34
Arm_Addr_FiqDCDfiq_interrupt_handler;0x38
DCD0x12345678; 0x3c
…
ldrr0,=Boot_Def
ldrr1, =0x0;address 0x0
mov r2,#0x3C
add r2, r2, r1
0
cmpr1, r2
bge%b1
ldrcc r3,[r0],#4
strcc r3,[r1],#4
b%B0
1
三、TCM的装备
TCM和cache是有差异的,尽管都是为了加速速度,可是TCM有必要给它指定地址,TCM和cache的用处也不样,TCM保存常用到的数据如中断向量表和realtime数据,而cache仅仅为了加速处理器和外设之间的数据处理。
ldr r0,=0x0;
mrc p15, 0, r1, c9, c1, 1;读coprocessor instruction tcmregion register.
orr r0, r0, r1;
movr1, #1
orr r1, r1, r0;instruction tcm bit_o 置1,enableinsturction tcm.
mcrp15,0,r1,c9,c1,1;写入
其它的cache装备也相似,首要读懂ARM document.
四、树立一个程序运转文境:
image(bin文件)包含俩部分:RO and RW,RO部分一般咱们在加载前后的方位都不必改变,可是RW有必要在加载后把他放到RAM中履行,所以RW部分咱们把它映射到RAM地址中。
IMPORT|Image$$RO$$Base| ;imageRO开端地址
IMPORT|Image$$RO$$Limit|
IMPORT|Image$$RO$$Length|
IMPORT|Image$$RW$$Base|
IMPORT|Image$$RW$$Limit|
IMPORT|Image$$RW$$Length|
IMPORT|Image$$ZI$$Base|
IMPORT|Image$$ZI$$Limit|
IMPORT|Image$$ZI$$Length|
ldrr0,=|Image$$RO$$Limit|
ldrr1,=|Image$$RW$$Base|
ldrr2,=|Image$$RW$$Limit|
3
cmpr1,r2
bge%B3
ldrcc r3,[r0],#4;从RO段的完毕地址+1load rw段数据
strccr3,[r1],#4;从头写入到rw段
b%B4
4
ldrr0,=|Image$$ZI$$Base|;处理ZI段数据
ldrr1,=|Image$$ZI$$Length|
add r1, r1, r0
ldr r1, =0X2000
ldrr2,=0
5
cmpr0, r1
bge%B6
strccr2,[r0],#4;初始化ZI段数据为0
b%B5
6
五、对内存进行测验:
因为体系中有各式各样的内存,能够对内存进行简略测验。
六、UART的装备:
UART在嵌入式体系中很重要,尽管它很简略,可是在前期开发中,UART是有必要的设备之一。UART作为下一篇中将进一步具体评论。