在S3C2440A user manual.pdf 的第五章有 Memory Controller的介紹。設置memory controller是為了明確各個bank(硬件決定出的地址空間)屬性,包括數據位寬、WAIT信號、訪問時序、刷新周期、bank起始位置和大小 (僅對bank6、7)及SDRAM模式。《嵌入式Linux應用開發完全手冊》第6章對各寄存器有較詳細敘述,再配上 S3C2440A user manual.pdf 各寄存器個字段含義應屬明確。只可惜這些還不夠,舉例來說要設置SDRAM各參數,沒有SDRAM數據手冊是沒法做的,在這個百花齊放的世界裡真沒什麼是 通吃的。
韋東山《嵌入式Linux應用開發完全手冊》PDF光盤源代碼等全套 http://www.linuxidc.com/Linux/2011-01/31114.htm
《嵌入式Linux應用開發完全手冊》對應的SDRAM是K4S561632C,我手頭的mini2440開發板上的號稱是 HY57V561620FTP,但芯片上的絲印被刻意劃掉了,隱約看到一個M的logo和無法辨認的一串數字,而且2片還不一樣!面對此情此景除了發自肺 腑的一句“你妹呀~”實在不知再說些什麼。
mini2440 板子入手在nor 上已有可正常運行的 supervivi,進入它的命令行模式,輸入:
mem info,它自曝了 memory controller 各寄存器設置,既然它工作正常就用這套值吧
Supervivi> mem info
RAM Information:
Default ram size: 64M
Real ram size : 64M
Free memory : 61M
RAM mapped to : 0x30000000 - 0x34000000
Flash memory mapped to : 0x10000000 - 0x12000000
Available memory region : 0x30000000 - 0x33d80000
Stack base address : 0x33defffc
Current stack pointer : 0x33defb6c
Memory control register vlaues
BWSCON = 0x22111112
BANKCON0 = 0x00000700
BANKCON1 = 0x00000700
BANKCON2 = 0x00000700
BANKCON3 = 0x00000700
BANKCON4 = 0x00000700
BANKCON5 = 0x00000700
BANKCON6 = 0x00018009
BANKCON7 = 0x00018009
REFRESH = 0x008e04eb
BANKSIZE = 0x000000b2
MRSRB6 = 0x00000030
MRSRB7 = 0x00000030
DSC0 = 0x00000000
DSC1 = 0x00000000
准 備工作還有如何拷貝內存數據。真正有意義的是從flash 拷貝到sdram但鑒於我還沒到這步,先搞點無意義的從片內ram到sdram吧,這裡的重點是“位置無關指令”這個概念。如果這個解決了剩下就是位置相 關指令的定位,換言之怎麼鏈接,怎麼加載,也就是如何保證運行地址的正確性。
S3C2440A 是 ARM920T 處理器類型,屬於 ARMv4T 架構,其位置無關指令包括 b bl。
假 想我有一些大個函數必須在 sdram 中調用,它們開機時是存在 flash 中的,那麼必須先設置好內存控制器,然後從flash中讀出這些函數的機器碼寫到sdram中去,然後再“跳”到sdram 中執行之。mini2440的sdram 起始地址是在bank6的(S3C2440A允許在bank7也掛sdram,但mini2440把它們都掛在bank6了)故這些大個函數在連接時必須 指定其所處段的運行地址在 0x30000000 之上。
位置相關指令要用以運行地址計算出來的絕對地址,上面那些大個函數中的絕對地址一定會在0x30000000之上,在沒有初始化內存控制器之前bank6中的地址是不存在的,此時只能用位置無關指令。這些指令無論你在鏈接時指定的運行地址是什麼都能通過相對值正確跳轉。
軟件分成2部分,一個匯編用於必要寄存器初始化和拷貝內存,再加設置sp和跳轉main;一個cpp用於模擬大塊頭。
先是 head.s
.text
.global _start
_start:
bl kill_dog
bl control_mem
bl copy2sdram
ldr pc, =sdram
sdram:
mov sp, #0x34000000
bl main
_end:
b _end
kill_dog:
mov r0, #0x53000000
mov r1, #0
str r1, [r0]
mov pc, lr
control_mem:
mov r0, #0x48000000
ldr r1, =0x22111112
str r1, [r0], #4
mov r1, #0x00000700
str r1, [r0], #4
mov r1, #0x00000700
str r1, [r0], #4
mov r1, #0x00000700
str r1, [r0], #4
mov r1, #0x00000700
str r1, [r0], #4
mov r1, #0x00000700
str r1, [r0], #4
mov r1, #0x00000700
str r1, [r0], #4
ldr r1, =0x00018009
str r1, [r0], #4
ldr r1, =0x00018009
str r1, [r0], #4
ldr r1, =0x008e04eb
str r1, [r0], #4
mov r1, #0x000000b2
str r1, [r0], #4
mov r1, #0x00000030
str r1, [r0], #4
mov r1, #0x00000030
str r1, [r0], #4
mov r1, #0x00000000
str r1, [r0], #4
mov r1, #0x00000000
str r1, [r0], #4
mov pc, lr
copy2sdram:
mov r0, #0
mov r1, #0x30000000
ldr r2, =0x1000
loop:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r0, r2
bne loop
mov pc, lr
注意其中 ldr pc, =sdram