一直没有好好分析一个bios的启动过程,这次我分析一些mini44b0开发板的一个小型的bios的启动过程,应该和其他的bios的启动过程非常类似。
先说以下系统定义:
;存储器空间
;GCS6 64M 16bit(8MB) DRAM/SDRAM(0xc000000-0xc7fffff)
;APP RAM=0xc000000~0xc7effff
;44BMON RAM=0xc7f0000-0xc7fffff
;STACK =0xc7ffa00
1. ads设定robase为:0x0c7c0000
2. 启动地址:
AREA Init,CODE,READONLY
ENTRY
ResetEntry
b ResetHandler ;for debug
/*
关于b指令我一直认为是绝对跳转,想着link会把地址从0xc7c0000开始,那样的话,跳转不是一下跳转到那里了吗?仔细看spec发现对b指令的介绍是:
target_address:为目标跳转地址。是相对于PC的偏移值。但是有个疑问:
编译后为:
[0xea000006] b ResetHandler
[0xe59ff148] ldr pc,0x0c7c0154 ; = #0x0c000004
[0xe59ff148] ldr pc,0x0c7c0158 ; = #0x0c000008
[0xe59ff148] ldr pc,0x0c7c015c ; = #0x0c00000c
[0xe59ff148] ldr pc,0x0c7c0160 ; = #0x0c000010
[0xeafffffe] b 0xc7c0014 ; (ResetEntry + 0x14)
[0xe59ff144] ldr pc,0x0c7c0164 ; = #0x0c000018
[0xe59ff144] ldr pc,0x0c7c0168 ; = #0x0c00001c
ResetHandler :[0xe59f0144] ldr r0,0x0c7c016c ; = #0x01d30000
[0xea000006] 怎么会跳转到 ResetHandler呢。
*/
ldr pc, =0x0c000004 ;handlerUndef 当发生中断的时候,直接跳转到SDRAM的开头位置。
ldr pc, =0x0c000008 ;SWI interrupt handler
ldr pc, =0x0c00000c ;handlerPAbort
ldr pc, =0x0c000010 ;handlerDAbort
b . ;handlerReserved
ldr pc, =0x0c000018
ldr pc, =0x0c00001c
ResetHandler
ldr r0,=WTCON ;禁止看门狗
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK
ldr r1,=0x07ffffff ;禁止所有中断
str r1,[r0]
;以下三段设置时钟控制寄存器
ldr r0,=LOCKTIME
ldr r1,=0xfff
str r1,[r0]
ldr r0,=PLLCON ;锁相环倍频设定
ldr r1,=((M_DIV<<12)+(P_DIV<<4)+S_DIV) ;设定系统主时钟频率
str r1,[r0]
ldr r0,=CLKCON
ldr r1,=0x7ff8 ;所有功能单元块时钟使能
str r1,[r0]
;****************************************************
;change BDMACON reset value for BDMA *
;****************************************************
ldr r0,=BDIDES0
ldr r1,=0x40000000 ;BDIDESn reset value should be 0x40000000
str r1,[r0]
ldr r0,=BDIDES1
ldr r1,=0x40000000 ;BDIDESn reset value should be 0x40000000
str r1,[r0]
;****************************************************
;设定存储器控制寄存器 *
;****************************************************
adr r0, ResetHandler //adr是一个伪指令,产生一个相对于PC的位置。
ldr r1, =ResetHandler //r1被赋值为编译后的地址。
sub r0, r1, r0 //如果编译后的地址和真正执行的地址一样,说明设定的链接地址也是为0,而我们的设定的为0xc7c0000. r0就是偏移地址。
ldr r1, =SMRDATA //把SMRDATA的编译地址赋值给r1
sub r0, r1, r0 //r0=r1-r0 是真正的地址,与编译地址无关。
ldmia r0, {r1-r13} //下面的程序是把SMRDATA的内容赋值给0x1c80000开始的寄存器。SMRDATA里面主要存的是mem设定的东西。
ldr r0, =0x01c80000 ;BWSCON Address
stmia r0, {r1-r13}
;****************************************************
;修正内存大小 *
;****************************************************
mov r0, #0
ldr r1, =0x0c000000
ldr r2, =0x0c000200
str r0, [r1]
mov r0, #-1
str r0, [r2]
ldr r0, [r1]
cmp r0, #0
ldrne r0, =0x01c8001c
ldrne r1, =((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN8))
strne r1, [r0]
strne r1, [r0, #4]
;****************************************************
;初始化堆栈 *
;****************************************************
ldr sp, =SVCStack ;复位后位SVC模式
bl InitStacks
;****************************************************
;拷贝并粘贴 RW data/zero initialized data *
;****************************************************
adr r0, ResetEntry
//测试执行地址是否和编译地址相同,如果相同,就直接初始化ram,开始进入main
//如果不是的话,就要把程序先从flash copy到sdram
ldr r1, BaseOfROM
cmp r0, r1
ldreq r0, TopOfROM
beq InitRamData
;****************************************************
;计算拷贝程序在flash中的实际位置 *
;****************************************************
;先把copyProc copy到sdram
;r1代表编译的地址头
ldr r2, =CopyProcBeg ;
sub r1, r2, r1 ;r1
add r0, r0, r1
ldr r3, =CopyProcEnd
;****************************************************
;将拷贝程序复制到ram中 *
;****************************************************
0
ldmia r0!, {r4-r7}
stmia r2!, {r4-r7}
cmp r2, r3
bcc %B0
;********************************************************
;开始用ram中的拷贝程序复本将所有剩下的代码复制到ram中 *
;********************************************************
ldr r3, TopOfROM
ldr pc, =CopyProcBeg
;********************************************************
;本段将代码由实际烧入的地址拷贝到ro-base所指定的位置 *
;只拷贝CopyProcEnd以后的代码 *
;********************************************************
CopyProcBeg ;这段代码的作用是把R0地址的块copy到R2开始地址的块,copy的数量为R3-R2
0
ldmia r0!, {r4-r11} ;R4=[R0],R5=[R0+1],R6=...
stmia r2!, {r4-r11} ;[R2]=R4 [R2+1] = R5,...
cmp r2, r3
bcc %B0
CopyProcEnd
sub r1, r2, r3 ;R1 = R2-R3
sub r0, r0, r1 ;R0 = R0-R1
InitRamData
ldr r2, BaseOfBSS
ldr r3, BaseOfZero
0
cmp r2, r3
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0
mov r0, #0
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
[ :LNOT:THUMBCODE
BL Main ;从汇编进入C语言代码空间,不要使用main()
B .
]
[ THUMBCODE ;for start-up code for Thumb mode
orr lr,pc,#1
bx lr
CODE16
bl Main ;从汇编进入C语言代码空间,不要使用main()
b .
CODE32
]
LTORG
;***********************************************
IMPORT |Image$$RO$$Base| ; ROM code start
IMPORT |Image$$RO$$Limit| ; RAM data starts after ROM program
IMPORT |Image$$RW$$Base| ; Pre-initialised variables
IMPORT |Image$$ZI$$Base| ; uninitialised variables
IMPORT |Image$$ZI$$Limit| ; End of variable RAM space
BaseOfROM DCD |Image$$RO$$Base| ;RO区域的起始地址
TopOfROM DCD |Image$$RO$$Limit|
BaseOfBSS DCD |Image$$RW$$Base|
BaseOfZero DCD |Image$$ZI$$Base|
EndOfBSS DCD |Image$$ZI$$Limit|
EXPORT GetBaseOfROM
EXPORT GetEndOfROM
EXPORT GetBaseOfBSS
EXPORT GetBaseOfZero
EXPORT GetEndOfBSS
GetBaseOfROM
ldr r0, BaseOfROM
mov pc, lr
GetEndOfROM
ldr r0, TopOfROM
mov pc, lr
GetBaseOfBSS
ldr r0, BaseOfBSS
mov pc, lr
GetBaseOfZero
ldr r0, BaseOfZero
mov pc, lr
GetEndOfBSS
ldr r0, EndOfBSS
mov pc, lr
;****************************************************
;* The function for initializing stack *
;****************************************************
InitStacks
;Do not 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.
LTORG
SMRDATA DATA
;*****************************************************************
; Memory configuration has to be optimized for best performance *
; The following parameter is not optimized. *
;*****************************************************************
;*** memory access cycle parameter strategy ***
; 1) Even FP-DRAM, EDO setting has more late fetch point by half-clock
; 2) The memory settings,here, are made the safe parameters even at 66Mhz.
; 3) FP-DRAM Parameters:tRCD=3 for tRAC, tcas=2 for pad delay, tcp=2 for bus load.
; 4) DRAM refresh rate is for 40Mhz.
;bank0 16bit BOOT ROM SST39VF160/SST39VF320
;bank1 8bit Nand Flash K9F2808U0A/K9F5608U0A
;bank2 16bit USB1.1 PDIUSBD12
;bank3 RTL8019
;bank4 No Uesed
;bank5 No Uesed
;bank6 16bit SDRAM
;bank7 16bit SDRAM
[ BUSWIDTH=16
; DCD 0x11111111 ;Bank0=OM[1:0], Bank0~Bank7=16bit
DCD 0x11111001 ;Bank0=OM[1:0] 16bit BootRomSST39VF160/SST39VF320) :0x0
; |||||||- Bank1=8bit Nand Flash
; |||||--- Bank2=8bit PDIUSBD12
; ||||---- Bank3=16bit RTL8019
; |||----- Bank4~5=16bit No Uesd
; -------- Bank6~7=16bit SDRAM
| ;BUSWIDTH=32
DCD 0x22222220 ;Bank0=OM[1:0], Bank1~Bank7=32bit
]
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
[ BDRAMTYPE="DRAM"
DCD ((B6_MT<<15)+(B6_Trcd<<4)+(B6_Tcas<<3)+(B6_Tcp<<2)+(B6_CAN)) ;GCS6 check the MT value in parameter.a
DCD ((B7_MT<<15)+(B7_Trcd<<4)+(B7_Tcas<<3)+(B7_Tcp<<2)+(B7_CAN)) ;GCS7
| ;"SDRAM"
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 0x10 ;SCLK power down mode, BANKSIZE 32M/32M
DCD 0x20 ;MRSR6 CL=2clk
DCD 0x20 ;MRSR7
ALIGN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;RW BEGIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
AREA RamData, DATA, READWRITE
^ (0x0c7ffb00)
UserStack # 256 ;c7ffb00
SVCStack # 256 ;c7ffc00
UndefStack # 256 ;c7ffd00
AbortStack # 256 ;c7ffe00
IRQStack # 256 ;c7fff00
FIQStack # 0 ;c800000
END
阅读(2210) | 评论(1) | 转发(0) |