從NandFlash啟動CPU的時候,CPU會自動通過其內(nèi)部硬件結(jié)構(gòu)復(fù)制NandFlash中的前4K代碼到cpu的自帶SRAM中,注意這是CPU自帶的SRAM,區(qū)別于本文所講的SDRAM,本文所指的SDRAM是外接SDRAM,開發(fā)板對應(yīng)的芯片為K4S561632,即內(nèi)存。
一般來說,嵌入式系統(tǒng)都有NandFlash(硬盤)和SDRAM(內(nèi)存),我們把程序燒到NanFlash中,然后選擇從NandFlash啟動CPU,CPU啟動后會自動復(fù)制NandFlash中前4K代碼到CPU的SRAM中,這前4K代碼接著完成程序從NandFlash復(fù)制到SDRAM的任務(wù)。
參考韋東山大哥的書,做了sdram的實(shí)驗(yàn):
(1)head.S,這個是最關(guān)鍵的,設(shè)置SDRAM控制器,來控制外部SDRAM即:K4S561632,然后把程序放在這個芯片里執(zhí)行的。
@*************************************************************************
@ File:head.S
@ 功能:設(shè)置SDRAM,將程序復(fù)制到SDRAM,然后跳到SDRAM繼續(xù)執(zhí)行
@*************************************************************************
.equMEM_CTL_BASE,0x48000000
.equSDRAM_BASE,0x30000000
.text
.global _start
_start:
bldisable_watch_dog @ 關(guān)閉WATCHDOG,否則CPU會不斷重啟
blmemsetup @ 設(shè)置存儲控制器
blcopy_steppingstone_to_sdram @ 復(fù)制代碼到SDRAM中
ldr pc,=on_sdram @ 跳到SDRAM中繼續(xù)執(zhí)行
on_sdram:
ldr sp,=0x34000000 @ 設(shè)置堆棧
blmain
halt_loop:
b halt_loop
disable_watch_dog:
@ 往WATCHDOG寄存器寫0即可
movr1,#0x53000000
movr2,#0x0
strr2,[r1]
movpc,lr @ 返回
copy_steppingstone_to_sdram:
@ 將Steppingstone的4K數(shù)據(jù)全部復(fù)制到SDRAM中去
@ Steppingstone起始地址為0x00000000,SDRAM中起始地址為0x30000000
movr1,#0
ldr r2,=SDRAM_BASE
movr3,#4*1024
1:
ldr r4,[r1],#4 @ 從Steppingstone讀取4字節(jié)的數(shù)據(jù),并讓源地址加4
strr4,[r2],#4 @ 將此4字節(jié)的數(shù)據(jù)復(fù)制到SDRAM中,并讓目地地址加4
cmpr1,r3 @ 判斷是否完成:源地址等于Steppingstone的未地址?
bne 1b @ 若沒有復(fù)制完,繼續(xù)
movpc,lr @ 返回
memsetup:
@ 設(shè)置存儲控制器以便使用SDRAM等外設(shè)
movr1,#MEM_CTL_BASE @ 存儲控制器的13個寄存器的開始地址
adrl r2,mem_cfg_val @ 這13個值的起始存儲地址
addr3,r1,#52 @ 13*4=54
1:
ldr r4,[r2],#4 @ 讀取設(shè)置值,并讓r2加4
strr4,[r1],#4 @ 將此值寫入寄存器,并讓r1加4
cmpr1,r3 @ 判斷是否設(shè)置完所有13個寄存器
bne 1b @ 若沒有寫成,繼續(xù)
movpc,lr @ 返回
.align4
mem_cfg_val:
@ 存儲控制器13個寄存器的設(shè)置值
.long 0x22011110 @ BWSCON
.long 0x00000700 @ BANKCON0
.long 0x00000700 @ BANKCON1
.long 0x00000700 @ BANKCON2
.long 0x00000700 @ BANKCON3
.long 0x00000700 @ BANKCON4
.long 0x00000700 @ BANKCON5
.long 0x00018005 @ BANKCON6
.long 0x00018005 @ BANKCON7
.long 0x008C07A3 @ REFRESH
.long 0x000000B1 @ BANKSIZE
.long 0x00000030 @ MRSRB6
.long 0x00000030 @ MRSRB7
(2)leds.c
#defineGPFCON(*(volatileunsignedlong*)0x56000050)
#defineGPFDAT(*(volatileunsignedlong*)0x56000054)
#defineGPFUP (*(volatileunsignedlong*)0x56000058)
#defineGPF0_out(1<<(0*2))
#defineGPF1_out(1<<(1*2))
#defineGPF2_out(1<<(2*2))
#defineGPF3_out(1<<(3*2))
voidwait(unsignedlongdly)
{
for(;dly>0;dly--);
}
intmain(void)
{
int i=0;
GPFCON=GPF1_out|GPF2_out|GPF3_out|GPF0_out;// 將LED1-4對應(yīng)的GPB5/6/7/8四個引腳設(shè)為輸出
GPFUP=0;
while(1){
for(i=0;i<4;i++){
GPFDAT = ~(1< wait(30000);
}
}
return0;
}
(3)Makefile:
sdram.bin:head.S leds.c
arm-linux-gcc-c-o head.o head.S
arm-linux-gcc-c-o leds.o leds.c
arm-linux-ld-Ttext 0x30000000 head.o leds.o-o sdram_elf
arm-linux-objcopy-O binary-S sdram_elf sdram.bin
arm-linux-objdump-D-m arm sdram_elf>sdram.dis
clean:
rm-f sdram.dis sdram.bin sdram_elf*.o