SDRAM例程:
從Nand Flash啓動CPU時,CPU會自動將Nand Flash開始的4K數據複製到4KB的內部Ram中(起始地址0),然後地址0開始執行。
本例程先用匯編設置好SDRAM,將程序從內部Ram複製到SDRAM,然後跳轉到SDRAM執行。
源代碼包括sdram.S、gpio.c、s3c2440.h,編譯爲二進制文件後燒寫到NandFlash運行。
sdram.S如下:
1.@*****************************************
2.@ File name : sdram.S
3.@ Project name: sdram
4.@ Author : Bob
5.@ Date : 2011-7-9
6.@ Description : 設置SDRAM,將steppingstone中的程序複製到sdram,然後跳轉到sdram執行。
7.@*****************************************
8.
9..data
10..equ MEM_CTL_BASE, 0x48000000 @ 存儲器控制器的寄存器首地址
11..equ SDRAM_BASE, 0x30000000 @ sdram的起始地址
12.
13..text
14..global _start
15._start:
16. bl disable_watch_dog
17. bl memsetup
18. bl copy_steppingstone_to_sdram
19. ldr pc, =on_sdram @ 跳轉到on_sdram,這是sdram中的地址
20.
21.on_sdram:
22. ldr sp, =0x34000000 @設置棧
23. bl main
24.halt_loop:
25. b halt_loop
26.
27.@ 禁止watch dog
28.disable_watch_dog:
29. mov r1, #0x53000000 @ watch dog 寄存器的地址
30. mov r2, #0x0
31. str r2, [r1]
32. mov pc, lr @返回
33.
34.@ 將steppingstone的內容全部複製到sdram
35.copy_steppingstone_to_sdram:
36. mov r1, #0 @ r1存放steppingstone的起始地址
37. ldr r2, =SDRAM_BASE @ r2存放sdram的起始地址
38. mov r3, #4*1024 @ steppingstone的大小時4KB
39.1:
40. ldr r4, [r1],#4 @ 從steppingstone中讀取4Byte,[r1]->r4,r1=r1+4
41. str r4, [r2],#4 @ 將4Byte複製到sdram,r4->[r2],r2=r2+4
42. cmp r1, r3 @ 判斷是否複製完4KB,r1等於4*1023時,複製結束
43. bne 1b @ 如果不相等,跳回1處
44. mov pc, lr @ 返回
45.
46.@ 設置存儲器控制器的寄存器
47.memsetup:
48. mov r1, #MEM_CTL_BASE @ r1存放存儲器控制器的寄存器首地址
49. adrl r2, mem_cfg_val @ r2存放mem_cfg_val的起始地址
50. add r3, r1,#52 @ r3=r1+52,r3存放mem_cfg_val的結束地址,有13個寄存器,13*4=52
51.1:
52. ldr r4, [r2],#4
53. str r4, [r1],#4
54. cmp r1, r3
55. bne 1b
56. mov pc, lr
57.
58.@ 存儲器控制器的13個寄存器的值
59..align 4 @ 以下數據都以4Byte對齊
60.mem_cfg_val:
61. .long 0x22011110 @ BWSCON
62. .long 0x00000700 @ BANKCON0
63. .long 0x00000700 @ BANKCON1
64. .long 0x00000700 @ BANKCON2
65. .long 0x00000700 @ BANKCON3
66. .long 0x00000700 @ BANKCON4
67. .long 0x00000700 @ BANKCON5
68. .long 0x00018005 @ BANKCON6
69. .long 0x00018005 @ BANKCON7
70. .long 0x008c07a3 @ REFRESH
71. .long 0x000000b1 @ BANKSIZE
72. .long 0x00000030 @ MRSRB6
73. .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{cond} 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的數據。