这几天晚上一直折腾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,中断等操作(启动代码来自互联网)
- INCLUDE S3C6410.inc
- PRESERVE8
- AREA Init, CODE, READONLY
- STACK_BASEADDRESS EQU 0x0c000400;0x52000000
- SVCStack EQU (STACK_BASEADDRESS) ;管理模式
- UndefStack EQU (STACK_BASEADDRESS - 0x300) ;指令终止模式
- AbortStack EQU (STACK_BASEADDRESS - 0x300) ;数据访问终止模式
- IRQStack EQU (STACK_BASEADDRESS - 0x200) ;中断模式
- FIQStack EQU (STACK_BASEADDRESS - 0x100) ;快速中断模式
- ;---------------------------
- ; CPSR Mode Bit Definition
- ;---------------------------
- Mode_USR EQU (0x10)
- Mode_FIQ EQU (0x11)
- Mode_IRQ EQU (0x12)
- Mode_SVC EQU (0x13)
- Mode_ABT EQU (0x17)
- Mode_UND EQU (0x1B)
- Mode_SYS EQU (0x1F)
- Mode_MASK EQU (0x1F)
- NOINT EQU (0xC0)
- I_Bit EQU (0x80)
- F_Bit EQU (0x40)
- ;异常处理函数
- ;---------------------------------------------------------------------------------------------------
- IMPORT main
- EXPORT ResetHandler
- ResetHandler
- ldr r0, =0x70000013 ; Base Addres : 0x70000000, Size : 256 MB (0x13)
- mcr p15,0,r0,c15,c2,4 ;告诉CPU外设寄存器的基地址和地址空间 重要
- ;设置为SVC模式
- MRS R0,CPSR
- BIC R0,R0,#0x1F
- ORR R0,R0,#0xD3
- MSR CPSR_cxsf,R0
- ;未知模式堆栈
- mrs r0,cpsr
- bic r0,r0,#Mode_MASK
- orr r1,r0,#Mode_UND|NOINT
- msr cpsr_cxsf,r1 ;UndefMode
- ldr sp,=UndefStack
- ;异常模式堆栈
- orr r1,r0,#Mode_ABT|NOINT
- msr cpsr_cxsf,r1 ;AbortMode
- ldr sp,=AbortStack
- ;中断模式堆栈
- orr r1,r0,#Mode_IRQ|NOINT
- msr cpsr_cxsf,r1 ;IRQMode
- ldr sp,=IRQStack
- ;管理模式堆栈
- bic r0,r0,#Mode_MASK|NOINT
- orr r1,r0,#Mode_SVC
- msr cpsr_cxsf,r1 ;SVCMode
- ldr sp,=SVCStack
- ;禁止看门狗
- LDR R0,=rWTCON
- LDR R1,=0x0
- STR R1,[R0]
- ;禁止cache和mmu
- LDR R0,=0x0
- MRC p15,0,R0,c1,c0,0
- LDR R1,=0xFFFF
- BIC R0,R0,R1
- MCR p15,0,R0,c1,c0,0
- ;禁止所有中断
- LDR R0,=rVIC0INTENCLEAR
- LDR R1,=0xFFFFFFFF
- STR R1,[R0]
- LDR R0,=rVIC1INTENCLEAR
- LDR R1,=0xFFFFFFFF
- STR R1,[R0]
- ;---------------------------------------------------------------------------------------------------
- ;设置时钟源
- LDR R0,=rOTHERS
- LDR R1,[R0]
- ORR R1,R1,#(1<<6)
- LDR R0,=rCLK_SRC
- LDR R1,=(1<<13)|7
- STR R1,[R0]
- LDR R0,=rCLK_SRC2
- LDR R1,=0x0
- STR R1,[R0]
- ;设置时钟分频
- LDR R0,=rCLK_DIV0
- LDR R1,=0x01043310
- STR R1,[R0]
- LDR R0,=rCLK_DIV1
- LDR R1,=0x0
- STR R1,[R0]
- LDR R0,=rCLK_DIV2
- LDR R1,=3<<16
- STR R1,[R0]
- ;使能时钟
- LDR R0,=rHCLK_GATE
- LDR R1,=0xFFFFFFFF
|