|
| Samsung原版44B0X的Bootloader分析 | ||||||||
|
1.中断向量表AREA Init,CODE,READONLY
ENTRY ;入口 ;地址 b ResetHandler ;for debug ;0x0000 0000 b HandlerUndef ;handlerUndef ;0x0000 0004 b HandlerSWI ;SWI interrupt handler ;0x0000 0008 b HandlerPabort ;handlerPAbort ;0x0000 000c b HandlerDabort ;handlerDAbort ;0x0000 0010 b . ;handlerReserved ;0x0000 0014 b HandlerIRQ ;0x0000 0018 b HandlerFIQ ;0x0000 001c
;以下参考44B0的手册:中断控制器一章.按地址顺序排列 VECTOR_BRANCH ldr pc,=HandlerEINT0 ;mGA H/W interrupt vector table 0x0000 0020 ldr pc,=HandlerEINT1 ; ldr pc,=HandlerEINT2 ; ldr pc,=HandlerEINT3 ; ldr pc,=HandlerEINT4567 ; ldr pc,=HandlerTICK ;mGA b . b . ldr pc,=HandlerZDMA0 ;mGB ldr pc,=HandlerZDMA1 ; ldr pc,=HandlerBDMA0 ; ldr pc,=HandlerBDMA1 ; ldr pc,=HandlerWDT ; ldr pc,=HandlerUERR01 ;mGB b . b . ldr pc,=HandlerTIMER0 ;mGC ldr pc,=HandlerTIMER1 ; ldr pc,=HandlerTIMER2 ; ldr pc,=HandlerTIMER3 ; ldr pc,=HandlerTIMER4 ; ldr pc,=HandlerTIMER5 ;mGC b . b . ldr pc,=HandlerURXD0 ;mGD ldr pc,=HandlerURXD1 ; ldr pc,=HandlerIIC ; ldr pc,=HandlerSIO ; ldr pc,=HandlerUTXD0 ; ldr pc,=HandlerUTXD1 ;mGD b . b . ldr pc,=HandlerRTC ;mGKA b . ; b . ; b . ; b . ; b . ;mGKA b . b . ldr pc,=HandlerADC ;mGKB b . ; b . ; b . ; b . ; b . ;mGKB b . b . ;0xe0=EnterPWDN ldr pc,=EnterPWDN
2.一级与二级中断处理程序
1)设置缺省中断处理函数 。;**************************************************** ;* Setup IRQ handler * ;**************************************************** ldr r0,=HandleIRQ ;This routine is needed ldr r1,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c str r1,[r0] 2)IRQ中断处理函数
IsrIRQ ;using I_ISPR register. sub sp,sp,#4 ;reserved for PC,为PC留下空位. stmfd sp!,{r8-r9} ;把r8,r9先入栈
ldr r9,=I_ISPR ;读入I_ISPR中的值 ldr r9,[r9] mov r8,#0x0 0 movs r9,r9,lsr #1 ;逻辑右移,得到中断源的编号 bcs %F1 add r8,r8,#4 b %B0
1 ldr r9,=HandleADC add r9,r9,r8 ;得到偏移地址 ldr r9,[r9] ;得到相应的IRQ程序地址 str r9,[sp,#8] ;把IRQ程序的地址当成PC值入栈 ldmfd sp!,{r8-r9,pc} ;对PC赋值,转到新的中断程序处。 3)定义一个加载宏。MACRO $HandlerLabel HANDLER $HandleLabel
$HandlerLabel ;由于ADS仅支持FD(满递减)型堆栈 sub sp,sp,#4 ;decrement sp(to store jump address) stmfd sp!,{r0} ;PUSH the work register to stack(lr does't push because it return to original address) ;将要使用的R0寄存器压栈保护。 ldr r0,=$HandleLabel ;load the address of HandleXXX to r0 ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack ;将对应的中断函数首地址入栈保护 ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR) ;将中断函数的首地址出栈,放入PC中,系统将跳转到对应中断处理函数 MEND 4)宏调用
HandlerFIQ HANDLER HandleFIQ HandlerIRQ HANDLER HandleIRQ HandlerUndef HANDLER HandleUndef HandlerSWI HANDLER HandleSWI HandlerDabort HANDLER HandleDabort HandlerPabort HANDLER HandlePabort
HandlerADC HANDLER HandleADC HandlerRTC HANDLER HandleRTC HandlerUTXD1 HANDLER HandleUTXD1 HandlerUTXD0 HANDLER HandleUTXD0 HandlerSIO HANDLER HandleSIO HandlerIIC HANDLER HandleIIC HandlerURXD1 HANDLER HandleURXD1 HandlerURXD0 HANDLER HandleURXD0 HandlerTIMER5 HANDLER HandleTIMER5 HandlerTIMER4 HANDLER HandleTIMER4 HandlerTIMER3 HANDLER HandleTIMER3 HandlerTIMER2 HANDLER HandleTIMER2 HandlerTIMER1 HANDLER HandleTIMER1 HandlerTIMER0 HANDLER HandleTIMER0 HandlerUERR01 HANDLER HandleUERR01 HandlerWDT HANDLER HandleWDT HandlerBDMA1 HANDLER HandleBDMA1 HandlerBDMA0 HANDLER HandleBDMA0 HandlerZDMA1 HANDLER HandleZDMA1 HandlerZDMA0 HANDLER HandleZDMA0 HandlerTICK HANDLER HandleTICK HandlerEINT4567 HANDLER HandleEINT4567 HandlerEINT3 HANDLER HandleEINT3 HandlerEINT2 HANDLER HandleEINT2 HandlerEINT1 HANDLER HandleEINT1 HandlerEINT0 HANDLER HandleEINT0
3.设置存储相关寄存器的程序
;**************************************************** ;* Set memory control registers * ;**************************************************** ldr r0,=SMRDATA ldmia r0,{r1-r13} ldr r0,=0x01c80000 ;BWSCON Address stmia r0,{r1-r13}
这是上面提到的对存储寄存器初始化的数据映射表(DATA Map)
SMRDATA DATA DCD 0x11110090 ;Bank0= DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0 DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1 DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2 DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3 DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4 DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5 DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6 DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7 DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) ;REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019 DCD 0x16 ;SCLK power mode, BANKSIZE 32M/32M DCD 0x20 ;MRSR6 CL=2clk DCD 0x20 ;MRSR7
ALIGN 4.初始化各模式下的堆栈指针;**************************************************** ;* The function for initializing stack * ;**************************************************** InitStacks ;Don't use DRAM,such as stmfd,ldmfd...... ;SVCstack is initialized before ;Under toolkit ver 2.50, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
mrs r0,cpsr bic r0,r0,#MODEMASK orr r1,r0,#UNDEFMODE|NOINT msr cpsr_cxsf,r1 ;UndefMode ldr sp,=UndefStack
orr r1,r0,#ABORTMODE|NOINT msr cpsr_cxsf,r1 ;AbortMode ldr sp,=AbortStack
orr r1,r0,#IRQMODE|NOINT msr cpsr_cxsf,r1 ;IRQMode ldr sp,=IRQStack
orr r1,r0,#FIQMODE|NOINT msr cpsr_cxsf,r1 ;FIQMode ldr sp,=FIQStack
bic r0,r0,#MODEMASK|NOINT orr r1,r0,#SVCMODE msr cpsr_cxsf,r1 ;SVCMode ldr sp,=SVCStack
;USER mode is not initialized. mov pc,lr ;The LR register may be not valid for the mode changes. 5.对RW与ZI数据进行拷贝和初始化
;******************************************************** ;* Copy and paste RW data/zero initialized data * ;******************************************************** LDR r0, =|Image$$RO$$Limit| ; Get pointer to ROM data, ;获得ROM中的加载/运行时的RW地址 LDR r1, =|Image$$RW$$Base| ; and RAM copy ;获得运行时的RW地址 LDR r3, =|Image$$ZI$$Base| ;获得运行时的ZI地址 ;Zero init base => top of initialised data
CMP r0, r1 ; Check that they are different ;比较指定的加载RW地址是否与运行时的RW地址相同。 BEQ %F1 ;如果相同不需要拷贝RW数据,因为它们的在加载和运行时的地址相同 0 CMP r1, r3 ; Copy init data,因为对RW指定了不同的加载和运行地址,因此需要拷贝 LDRCC r2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4 STRCC r2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4 BCC %B0 1 LDR r1, =|Image$$ZI$$Limit| ;Top of zero init segmen ;初始化ZI数据为0 MOV r2, #0 2 CMP r3, r1 ; Zero init STRCC r2, [r3], #4 BCC %B2 |
|
|