小弟用的是AT91R40008,內部有256KB的SRAM,以前沒有用過帶REMAP功能的ARM,這是第一次。
一開始,忘了設置FLASH remap之后的基址,remap之后,內部的SRAM再也不能用了,還好Flash是PLCC封裝的,帶電熱插拔(小弟的電路板是自己設計的自己焊的平時跑著都不放心,熱插拔的時候心里怦怦直跳)。
第二次,事先設置好了FLASH remap之后的地址。沒想到,remap之后,還是當機。這是恍然大悟,remap之后PC指向了SRAM,難怪會跑飛。不知為什么,這次加載到SRAM中的程序仍然運行不起來,不想那么多了先把remap搞定,再次熱插拔。
為了保證remap之后,程序仍然能夠正常運行,看來要把程序實現復制到SRAM中,不過感覺這種辦法好苯。于是在網上找呀找,終于找到了另一種remap方法,如下:
InitTableEBI:
dcd EBI_CSR_0
dcd EBI_CSR_1
dcd EBI_CSR_2
dcd EBI_CSR_3
dcd EBI_CSR_4
dcd EBI_CSR_5
dcd EBI_CSR_6
dcd EBI_CSR_7
dcd 0x00000001 /* REMAP command */
dcd 0x00000006 /* 6 memory regions, standard read */
PtEBIBase:
dcd EBI_BASE /* EBI Base Address */
PtInitTableEBI DCD InitTableEBI
PtInitRemap DCD InitRemap
ldr r10 , PtInitTableEBI
mov r10 , r10 , LSL #12
mov r10 , r10 , LSR #12
R10的高12位必須清0,因為鏈接是運行域地址是FLASH remap之后的地址,而這時實際運行在remap之前的地址處。
ldr r12,addr_after_remap
ldmia r10!, {r0-r9,r11}
stmia r11!, {r0-r9} /* 拷貝片選寄存器映像到存儲控制器和命令remap */
mov pc, r12
原理就是利用ARM流水線,最后一條指令在上一條指令之前完成,具體原理我也不清楚,查了一些資料都沒有解釋,不知哪位大蝦能說一說。不過在remap之前加載絕對地址時要注意絕對地址和實際地址不一樣呦。
事實上,通過上面的方法就可以實現remap了,不過小弟寫程序太馬虎了,又經歷了幾次熱插拔才成功(不過我對我的板子越來越有信心了,看來那種熱插拔BIOS的言論也是危言聳聽):)。