S5PV210 构建最小linux系统(1)—->搬运代码到ram中运行
1.时钟初始化
- 通过时钟树对相应的寄存器进行配置,得到期望时钟。
//set clock
ldr r0, =CLK_BASE
ldr r1, =0x0
str r1, [r0, #CLK_SRC0]
//set SCLKapll=1000M
ldr r1, =(1<<31)|(125<<16)|(3<<8)|1
str r1, [r0, #APLL_CON0]
//set SCLKmpll=667M
ldr r1, =(1<<31)|(667<<16)|(12<<8)|1
str r1, [r0, #MPLL_CON]
ldr r1, =(1<<28)|(4<<24)|(1<<20)|(3<<16)|(1<<12)|(4<<8)|(4<<4)|0
str r1, [r0, #CLK_DIV0]
ldr r1, =(1<<4)|1
str r1, [r0, #CLK_SRC0]
2.DRAM初始化
- 依照手册初始化步骤进行ram初始化
//2
ldr r0, =DMC0_BASE
ldr r1, =(0x10<<16)|(0x10<<8)|(1<<1)
str r1, [r0, #PHYCONTROL0]
//3
ldr r1, =(8<<4)|6
str r1, [r0, #PHYCONTROL1]
//4
ldr r1, =(0x10<<16)|(0x10<<8)|(1<<1)|1
str r1, [r0, #PHYCONTROL0]
//5
ldr r1, =0x0FFF2010
str r1, [r0, #CONCONTROL]
//6
ldr r1, =0x00202400
str r1, [r0, #MEMCONTROL]
//7
ldr r1, =0x20E00313
str r1, [r0, #MEMCONFIG0]
//8
ldr r1, =0xFF000000
str r1, [r0, #PRECHCONFIG]
//9
ldr r1, =0x00000618
str r1, [r0, #TIMINGAREF]
ldr r1, =0x2B34438A
str r1, [r0, #TIMINGROW]
ldr r1, =0x24240000
str r1, [r0, #TIMINGDATA]
ldr r1, =0x0BDC0343
str r1, [r0, #TIMINGPOWER]
//11
wait_lock:
ldr r1, [r0, #PHYSTATUS]
and r2, r1, #0x07
cmp r2, #0x07
bne wait_lock
//12
and r1, #0x3fc0
mov r1, r1, LSL #18
ldr r2, =(0x10<<16)|(0x10<<8)|(1<<1)|1
orr r1, r2, r1
str r1, [r0, #PHYCONTROL0]
ldr r1, =0x07000000
str r1, [r0, #DIRECTCMD]
ldr r1, =0x01000000
str r1, [r0, #DIRECTCMD]
ldr r1, =0x00020000
str r1, [r0, #DIRECTCMD]
ldr r1, =0x00030000
str r1, [r0, #DIRECTCMD]
ldr r1, =0x00010400
str r1, [r0, #DIRECTCMD]
ldr r1, =0x00000542
str r1, [r0, #DIRECTCMD]
ldr r1, =0x01000000
str r1, [r0, #DIRECTCMD]
ldr r1, =0x05000000
str r1, [r0, #DIRECTCMD]
ldr r1, =0x05000000
str r1, [r0, #DIRECTCMD]
ldr r1, =0x00000442
str r1, [r0, #DIRECTCMD]
ldr r1, =0x00010780
str r1, [r0, #DIRECTCMD]
ldr r1, =0x00010400
str r1, [r0, #DIRECTCMD]
ldr r1, =0x0FF02030
str r1, [r0, #CONCONTROL]
ldr r1, =0xFFFF00FF
str r1, [r0, #PWRDNCONFIG]
ldr r1, =0x00202400
str r1, [r0, #MEMCONTROL]
// dram end
//跳转到代码搬运函数
b copy_code_to_dram
3.代码搬运(SD->RAM)
- 代码搬运函数
typedef unsigned int (*CopySDMMCtoMem) (unsigned int channel, unsigned int start_block, unsigned short block_size, unsigned int *trg, unsigned int init);
void copy_code_to_dram(void)
{
unsigned long ch;
void (*uboot)(void);
ch = *(volatile unsigned int *)(0xD0037488);
CopySDMMCtoMem copy_data = (CopySDMMCtoMem) (*(unsigned int *) (0xD0037F98));
unsigned int ret;
led2_on();
if (ch == 0xEB000000)
{
ret = copy_data(0, 6, 1000,(unsigned int *)0x20000000, 0); //Uboot
ret = copy_data(0, 1006, 100,(unsigned int *)0x200C8000, 0); //Dtb
ret = copy_data(0, 1106, 20000,(unsigned int *)0x20100000, 0); //linux kernel
}
uboot = (void *)0x20000000;
(*uboot)(); //跳转到uboot执行
}
代码下载地址,可直接用交叉编译器编译
http://download.youkuaiyun.com/download/qq_15506653/10109107