ARM啟動程式碼的分析
估計以後會忘記,所以記下來。
一上電,硬體自動把NandFlash中的前4K資料拷貝進片內的SRAM。開始執行指令
@*************************************************************************
@ File:head.S
@ 功能:設定SDRAM,將程式複製到SDRAM,然後跳到SDRAM繼續執行
@*************************************************************************
.equ MEM_CTL_BASE, 0x48000000 @定義儲存控制器的起始地址
.equ SDRAM_BASE, 0x30000000 @定時SDRAM的起始地址
.text
.global _start
_start:
bl disable_watch_dog @ 關閉WATCHDOG,否則CPU會不斷重啟,這是在SRAM中執行的。
bl memsetup @ 設定儲存控制器,相對跳轉指令,與程式處於片內或者片外無關,在SRAM中執行。
bl copy_steppingstone_to_sdram @ 複製程式碼到SDRAM中,相對跳轉指令,在SRAM中執行。
ldr pc, =on_sdram @ 跳到SDRAM中繼續執行,絕對跳轉指令,會跳轉到SDRAM中,在SRAM中執行。
在編譯連結的時候,會在某個記憶體中儲存(0x30000000+偏移地址)這個值,而偏移地址就是 on_sdram的偏移地址。 反彙編ldr pc,【pc,#144】, 當前pc+144就找到了這個記憶體,並把 記憶體裡面的值賦給pc,使pc指向了SDRAM。而0x3000000在Makefile中指定的。
on_sdram:
ldr sp, =0x34000000 @ 設定堆疊。在SDRAM中執行的第一條指令
bl main @跳轉到main函式。
halt_loop: @一直迴圈。
b halt_loop
@以下為子函式
disable_watch_dog:
@ 往WATCHDOG暫存器寫0即可
mov r1, #0x53000000
mov r2, #0x0
str r2, [r1]
mov pc, lr @ 返回
copy_steppingstone_to_sdram:
@ 將Steppingstone的4K資料全部複製到SDRAM中去
@ Steppingstone起始地址為0x00000000,SDRAM中起始地址為0x30000000
mov r1, #0
ldr r2, =SDRAM_BASE
mov r3, #4*1024
1:
ldr r4, [r1],#4 @ 從Steppingstone讀取4位元組的資料,並讓源地址加4
str r4, [r2],#4 @ 將此4位元組的資料複製到SDRAM中,並讓目地地址加4
cmp r1, r3 @ 判斷是否完成:源地址等於Steppingstone的未地址?
bne 1b @ 若沒有複製完,繼續
mov pc, lr @ 返回
memsetup:
@ 設定儲存控制器以便使用SDRAM等外設
mov r1, #MEM_CTL_BASE @ 儲存控制器的13個暫存器的開始地址
adrl r2, mem_cfg_val @ 這13個值的起始儲存地址
add r3, r1, #52 @ 13*4 = 54
1:
ldr r4, [r2], #4 @ 讀取設定值,並讓r2加4
str r4, [r1], #4 @ 將此值寫入暫存器,並讓r1加4
cmp r1, r3 @ 判斷是否設定完所有13個暫存器
bne 1b @ 若沒有寫成,繼續
mov pc, lr @ 返回
@以下為記憶體分配
.align 4
mem_cfg_val:
@ 儲存控制器13個暫存器的設定值
.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