S3C6410 纯粹的裸机启动,自己写的SD BOOT启动
扫描二维码
随时随地手机看文章
这几天晚上一直折腾S3C6410的裸机SD卡启动,不大想使用UBOOT,我是搞硬件的,对底层非常感兴趣,不喜欢已经写好的,因此自己一直在尝试,其实很早之前就试过SD卡启动,也就是ARM11上电后会把SD卡倒数第9KB开始的8KB(倒数0x2400B偏移量)复制到内部SRAM中执行,这个比较简单,但是代码量只有8K,不能像STM32一样玩,因此查阅相关资料,得知启动方式为L0加载L1,L1加载L2,简单来说,就是上电启动后,固化在S3C6410内部的L0代码启动,将NAND,SD卡等外部存储器映射或者复制到内部SRAM,这个从SD卡或者flash复制过去的代码称之为L1,也就是用户的启动代码,在电脑上相当于硬盘主分区的启动代码和BIOS,用来初始化外时钟以及外设,并启动系统,,这部分代码只有8KB因此完成的工作有限,因此可以使用这段代码完成初始化并复制操作系统或者更大的代码到内存,这部分代码就是L2了,只有L1将内存初始化后才能使用内存,再此之前内存只有8KB,就是内部SRAM,从SD卡启动的时候映射到0x0c000000,从NAND可以是0,也可以是0x0c000000.
目前只实现了L1,无需uboot,只需要烧写到SD卡的指定位置即可,需要将开发板选择为SD卡启动.
启动代码,完成了关闭看门狗,初始化时钟,SDRAM内存,堆栈,VIC,中断等操作(启动代码来自互联网)
INCLUDES3C6410.inc
PRESERVE8
AREAInit,CODE,READONLY
STACK_BASEADDRESSEQU0x0c000400;0x52000000
SVCStackEQU(STACK_BASEADDRESS);管理模式
UndefStackEQU(STACK_BASEADDRESS-0x300);指令终止模式
AbortStackEQU(STACK_BASEADDRESS-0x300);数据访问终止模式
IRQStackEQU(STACK_BASEADDRESS-0x200);中断模式
FIQStackEQU(STACK_BASEADDRESS-0x100);快速中断模式
;---------------------------
;CPSRModeBitDefinition
;---------------------------
Mode_USREQU(0x10)
Mode_FIQEQU(0x11)
Mode_IRQEQU(0x12)
Mode_SVCEQU(0x13)
Mode_ABTEQU(0x17)
Mode_UNDEQU(0x1B)
Mode_SYSEQU(0x1F)
Mode_MASKEQU(0x1F)
NOINTEQU(0xC0)
I_BitEQU(0x80)
F_BitEQU(0x40)
;异常处理函数
;---------------------------------------------------------------------------------------------------
IMPORTmain
EXPORTResetHandler
ResetHandler
ldrr0,=0x70000013;BaseAddres:0x70000000,Size:256MB(0x13)
mcrp15,0,r0,c15,c2,4;告诉CPU外设寄存器的基地址和地址空间重要
;设置为SVC模式
MRSR0,CPSR
BICR0,R0,#0x1F
ORRR0,R0,#0xD3
MSRCPSR_cxsf,R0
;未知模式堆栈
mrsr0,cpsr
bicr0,r0,#Mode_MASK
orrr1,r0,#Mode_UND|NOINT
msrcpsr_cxsf,r1;UndefMode
ldrsp,=UndefStack
;异常模式堆栈
orrr1,r0,#Mode_ABT|NOINT
msrcpsr_cxsf,r1;AbortMode
ldrsp,=AbortStack
;中断模式堆栈
orrr1,r0,#Mode_IRQ|NOINT
msrcpsr_cxsf,r1;IRQMode
ldrsp,=IRQStack
;管理模式堆栈
bicr0,r0,#Mode_MASK|NOINT
orrr1,r0,#Mode_SVC
msrcpsr_cxsf,r1;SVCMode
ldrsp,=SVCStack
;禁止看门狗
LDRR0,=rWTCON
LDRR1,=0x0
STRR1,[R0]
;禁止cache和mmu
LDRR0,=0x0
MRCp15,0,R0,c1,c0,0
LDRR1,=0xFFFF
BICR0,R0,R1
MCRp15,0,R0,c1,c0,0
;禁止所有中断
LDRR0,=rVIC0INTENCLEAR
LDRR1,=0xFFFFFFFF
STRR1,[R0]
LDRR0,=rVIC1INTENCLEAR
LDRR1,=0xFFFFFFFF
STRR1,[R0]
;---------------------------------------------------------------------------------------------------
;设置时钟源
LDRR0,=rOTHERS
LDRR1,[R0]
ORRR1,R1,#(1<<6)
LDRR0,=rCLK_SRC
LDRR1,=(1<<13)|7
STRR1,[R0]
LDRR0,=rCLK_SRC2
LDRR1,=0x0
STRR1,[R0]
;设置时钟分频
LDRR0,=rCLK_DIV0
LDRR1,=0x01043310
STRR1,[R0]
LDRR0,=rCLK_DIV1
LDRR1,=0x0
STRR1,[R0]
LDRR0,=rCLK_DIV2
LDRR1,=3<<16
STRR1,[R0]
;使能时钟
LDRR0,=rHCLK_GATE
LDR R1,=0xFFFFFFFF