從
nand flash
啟動cpu
時,cpu
會自動將
nand flash
開始的4k
資料複製到
4kb的內部
ram中(起始位址
0),然後位址
0開始執行。
本例程先用彙編設定好
sdram
,將程式從內部
ram複製到
sdram
,然後跳轉到
sdram
執行。源**包括
sdram.s
、gpio.c
、s3c2440.h,編譯為二進位制檔案後燒寫到nandflash執行
。sdram.s
如下:
@*****************************************
@ file name : sdram.s
@ project name: sdram
@ author : bob
@ date : 2011-7-9
@ description : 設定sdram,將steppingstone中的程式複製到sdram,然後跳轉到sdram執行。
@*****************************************
.data
.equ mem_ctl_base, 0x48000000 @ 儲存器控制器的暫存器首位址
.equ sdram_base, 0x30000000 @ sdram的起始位址
.text
.global _start
_start:
bl disable_watch_dog
bl memsetup
bl copy_steppingstone_to_sdram
ldr pc, =on_sdram @ 跳轉到on_sdram,這是sdram中的位址
on_sdram:
ldr sp, =0x34000000 @設定棧
bl main
halt_loop:
b halt_loop
@ 禁止watch dog
disable_watch_dog:
mov r1, #0x53000000 @ watch dog 暫存器的位址
mov r2, #0x0
str r2, [r1]
mov pc, lr @返回
@ 將steppingstone的內容全部複製到sdram
copy_steppingstone_to_sdram:
mov r1, #0 @ r1存放steppingstone的起始位址
ldr r2, =sdram_base @ r2存放sdram的起始位址
mov r3, #4*1024 @ steppingstone的大小時4kb
1: ldr r4, [r1],#4 @ 從steppingstone中讀取4byte,[r1]->r4,r1=r1+4
str r4, [r2],#4 @ 將4byte複製到sdram,r4->[r2],r2=r2+4
cmp r1, r3 @ 判斷是否複製完4kb,r1等於4*1023時,複製結束
bne 1b @ 如果不相等,跳回1處
mov pc, lr @ 返回
@ 設定儲存器控制器的暫存器
memsetup:
mov r1, #mem_ctl_base @ r1存放儲存器控制器的暫存器首位址
adrl r2, mem_cfg_val @ r2存放mem_cfg_val的起始位址
add r3, r1,#52 @ r3=r1+52,r3存放mem_cfg_val的結束位址,有13個暫存器,13*4=52
1: ldr r4, [r2],#4
str r4, [r1],#4
cmp r1, r3
bne 1b
mov pc, lr
@ 儲存器控制器的13個暫存器的值
.align 4 @ 以下資料都以4byte對齊
mem_cfg_val:
.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 @ mrsrb6
說明:ldr
:
當第二個運算元前面沒有「
=」時,表示記憶體訪問指令,從記憶體中讀取
4byte
資料到暫存器,語法格式如下:
ldr
目的暫存器, 儲存器位址
如果第二個運算元前面有「
=」,表示大範圍位址讀取偽指令,用於載入
32位的立即數或乙個位址到指定暫存器,語法格式如下:
ldr
目的暫存器,
=32位立即數/位址
str:
記憶體訪問指令,從源暫存器將乙個
32位資料傳送到儲存器中,語法格式如下:
str
源暫存器, 儲存器位址
adrl r2, mem_cfg_val
:
adrl
是中等範圍位址讀取偽指令,
將基於pc相對偏移的位址值或基於暫存器相對偏移的位址值讀取到暫存器中,在彙編編譯器編譯源程式時,adrl偽指令被編譯器替換成兩條合適的指令。若不能用兩條指令實現,則產生錯誤,編譯失敗。這條**會替換為:
30000050: e28f2018 add r2, pc, #24 ; 0x18
30000054: e1a00000 nop (mov r0,r0)
adrl偽指令格式:
adrl register, expr
位址表示式
expr
的取值範圍:
當位址值是位元組對齊時,其取指範圍為
: -64k
~64k
;當位址值是字對齊時,其取指範圍為
: -256k
~256k
;nop
:
空操作偽指令,在彙編是替換成
arm中的空操作,例如
mov r0, r0
cmp
:
比較指令,格式如下:
cmp
運算元1
, 運算元
2用與將乙個暫存器的內容和另一暫存器的內容或立即數進行比較,然後更新
cpsr
中條件標誌位的值,標誌位表示運算元
1和運算元
2的關係(大於、小於、相等)。
bne 1b
:
b(跳轉指令)
+ne(條件:不相等),如果
cpsr的z
位為0(不相等),就跳轉到後面的
1標號處。
b表示向後搜尋,已經執行過的**為『後』;
f表示向前搜尋,還未執行的**為『前』。
mov pc
,
lr
從子程式返回。
lr為子程式鏈結暫存器(
r14),當執行
bl子程式呼叫指令時,
lr會備份
pc(程式計數器
r15)。
.align
指定對齊方式,
gnu彙編命令都以乙個點開頭。
.equ
賦值命令,格式如下:
.equ symbol, expression
設定symbol
的值為expression
。.long
定義乙個
4byte
的資料。
程式源**:
sdram
參考:韋東山:《嵌入式linux應用開發完全手冊》
Mini2440學習筆記(三) SDRAM
2440的儲存控制器有個8個bank bank0 bank7,對外引出27根位址線 addr0 addr26 訪問範圍是128m,有8個片選訊號 ngcs0 ngcs7 與之對應,所有可以訪問1g的位址空間。bank6和bank7的可訪問位址空間是可以設定的。只有bank6和bank7可以外接sdr...
Mini2440學習筆記(一) Start
win7 openocd openjtag mini2440 按照 eclipse,openocd,openjtagv3嵌入式開發教程 將軟硬體安裝好。然後執行openocd ftd2xx。這個程式會作為乙個守護程序執行,等待客戶端 telnet或gdb 的連線,可以使用 h引數檢視該程式的一些可選...
(三)MINI2440的時鐘配置
時鐘源 om 3 2 選擇時鐘源 mpll main pll 主鎖相環 在mini2440開發板中,1 nreset為低時復位晶元,延時一段時間等待電壓穩定後,nreset才輸出高電平,cpu才可以工作。2 根據om 3 2 的值,選擇輸入時鐘源,在mini2440中,輸入時鐘源是12mhz的晶振 ...