ARM启动代码分析(2440init.c)
[ PLL_ON_START
; Added for confirm clock divide. for 2440.
; Setting value Fclk:Hclk:Pclk
; 这里设置的 Fclk:Hclk:Pclk = 1:3:6,因为 CLKdiv_VAL = 7
ldrr0,=CLKdivN
ldrr1,=CLKdiv_VAL; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.
strr1,[r0] ;数据表示分频数
;UPLL和MPLL的控制参数
;PLLCON Bit Description Initial State
;Mdiv [19:12] Main divider control 0x96 / 0x4d
;Pdiv [9:4] Pre-divider control 0x03 / 0x03
;Sdiv [1:0] Post divider control 0x0 / 0x0
;InputFrequency OutputFrequency Mdiv Pdiv Sdiv
;12.0000MHz 48.00 MHz(Note) 56(0x38) 2 2
;12.0000MHz 96.00 MHz(Note) 56(0x38) 2 1
;12.0000MHz 271.50 MHz 173(0xad) 2 2
;12.0000MHz 304.00 MHz 68(0x44) 1 1
;12.0000MHz 405.00 MHz 127(0x7f) 2 1
;12.0000MHz 532.00 MHz 125(0x7d) 1 1
;Configure UPLL
; 根据手册,要对PLL进行设置的话,就需要先设置UPLLCON,再设置MPLLCON
; 并且中间需要有至少七个指令周期的延时
ldrr0,=UPLLCON
ldrr1,=((U_Mdiv<12)+(U_Pdiv<4)+U_Sdiv)
strr1,[r0]
nop; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.
nop
nop
nop
nop
nop
nop
;Configure MPLL
ldrr0,=MPLLCON
ldrr1,=((M_Mdiv<12)+(M_Pdiv<4)+M_Sdiv)
strr1,[r0]
]
;Check if the boot is caused by the wake-up from SLEEP mode.
ldrr1,=GSTATUS2
ldrr0,[r1]
tstr0,#0x2
;In case of the wake-up from SLEEP mode, go to SLEEP_WAKEUP handler.
bneWAKEUP_SLEEP
;EXPORT伪指令声明一个全局标号
EXPORT StartPointAfterSleepWakeUp
StartPointAfterSleepWakeUp
;3.置存储相关寄存器的程序
;这是设置SDRAM,flash ROM 存储器连接和工作时序的程序,片选定义的程序
;SMRDATA map在下面的程序中定义
;SMRDATA中涉及的值请参考memcfg.s程序
;具体寄存器各位含义请参考s3c44b0 spec
;Set memory control registers
ldrr0,=SMRDATA
ldrr1,=BWSCON;BWSCON Address
addr2, r0, #52;End address of SMRDATA
; beq %F[ ]中,b为跳转指令,eq为相等条件标识,整条语句的意思就是
; 如果相等,则在此条语句后面的代码中搜索[ ]标号并跳转。
; 同样的 bcc %B[ ] 其中cc为无符号数小于,%B在此条语句前面的代码中搜索并跳转
;下面是一个循环
;首先把r0指向的地址单元的一个字(4字节)的内容复制到r3中,
;然后r0+4,这样的话下次取的值将会是SMRDATA中的下一个个字
;
;将r3中的值写入到r1的地址单元(BWSCON)中,并将r1+1,即
;下一次将会写入到BWSCON的下一个控制器
;控制器以此为:BWSCON - BANKCON0 - BANKCON1 - BANKCON2 ……BANKCON7
;BANKSIZE - MRSRB6 - MRSRB7
0
ldrr3, [r0], #4
strr3, [r1], #4
cmpr2, r0
bne%B0;不等于0时跳转,也就是说一直循环直到将上面所说的控制器全部,设置了值之后才继续执行下一步
;r0 是这个数据区的起始地址,r2 是数据区的结束地址,r1 是寄存器的起始地址。这样,
;用一个判断语句就可以把内存中的数据赋给这13 个存储控制寄存器了。
;Initialize stacks
;4.初始化各模式下的栈指针
blInitStacks
; Setup IRQ handler
;5.设置缺省中断处理函数
ldrr0,=HandleIRQ ;This routine is needed
ldrr1,=IsrIRQ ;if there isnt subs pc,lr,#4 at 0x18, 0x1c
strr1,[r0]
;initialize the IRQ 将普通中断判断程序的入口地址给HandleIRQ
;6.将数据段拷贝到ram中 将零初始化数据段清零 跳入C语言的main函数执行 到这步结束bootloader初步引导结束
;由于 ROM 和 Flash 的读取速度相对较慢,这样无疑会降低代码的执行速度和系统的运行效率。
;为此,需要把系统的代码复制到 RAM 中运行。
;If main() is used, the variable initialization will be done in __main().
[:LNOT:USE_MAIN
;Copy and paste RW data/zero initialized data
LDR r0, =|Image
LDR r1, =|Image
LDR r3, =|Image
;Zero init base => top of initialised data
CMP r0, r1 ; Check that they are different
BEQ %F2
1
CMP r1, r3 ; Copy init data
LDRCC r2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4
STRCC r2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4
BCC %B1
2
LDR r1, =|Image
MOV r2, #0
3
CMP r3, r1 ; Zero init
STRCC r2, [r3], #4
BCC %B3
]
;这里不能写main,因为写了main,系统会自动为我们完成一些初始化工作,
;而这些工作在这段程序中是由我们显式地人为完成的。
[ :LNOT:THUMBCODE
blMain ;Dont use main() because ......
b.
]
ARM启动代码244 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)