學了點東西,寫點總結。以下是我在做 page130,2.6.8記憶體驅動實驗總結。
我按照書上的指示,完成了**的編寫。對專案作如下配置:
上述的配置中 -ro-base 0x30000000 告訴linker,本程式將被載入到 0x30000000 上執行。
實驗程式的功能是,程式最初是在0x00000000 位址上開始執行。它初始化sdram後,將自己複製到0x30000000位址上,然後跳到sdram中執行。
第乙個問題:我在用axd進行除錯時,總是發現程式執行到 copyallloop 中死掉。
copyall
import |image$$ro$$base|
import |image$$rw$$limit|
ldr r0, = |image$$ro$$base|
ldr r1, = |image$$rw$$limit|
ldr r2, = 0x00000000
copyallloop
teq r0, r1
beq quitcopy
ldr r3 , [r2], #4
str r3 , [r0], #4
b copyallloop
quitcopy
mov pc, lr
copyall函式的功能是將 0x00000000 位址上的所有程式代到複製到sdram的 0x30000000 位址上去。可是總是在copyallloop 迴圈中死掉。
由此可以得知,pc的初始值為0x3000005c,而不是pc = 0x00000000。說明除錯時程式被載入到sdram中執行。
這麼一來,那麼將0x00000000位址區間的資料考到0x30000000位址上來,而程式自身就執行在0x30000000位址上。這樣一來,複製的資料將程式自己給覆蓋了。難怪要死在那裡。
在進入copyallloop之前,反彙編如下:
當r0 = 0x3000000d0時:
此時,0x300000d0之前的指令已被更改。所以,死在這裡了。
令我奇怪的是,程式開始執行時,pc並不等於0x00000000,而是另乙個值。如下所示:
可見,圖中所示a處,pc並不等於0x0000,而是0x005c。不對呀!arm核啟動不是多0x0000開始的嗎?怎麼成了0x005c呢?再看d處,start啟動程式被放到了0x005c的位置。而放在 0x0000 位址上的指令則是xmain函式入口,見c處。
那麼,為什麼編譯器要把 xmain 放在0x0000位址上,而不是 start 呢?我詳細地對比了書上的配置介面的各項設定。發現在 equivalent command line 欄中,我少寫了 "-first init.o" 這句話的意思就是說,把init.o目標檔案的**放在首位。正確的命令串為:
修改配置後,重新編譯。在axd中檢視其反彙編**,如下:
這樣以來,start就被放到了前面了。
第三個問題:如何完成實驗?
現在,我把 ro base設定成了0x30000000 ,只要一進入除錯模式,axd就自動將我的**載入到了 sdram 的 0x30000000 位址上了。
按照書中的要求,**應該被燒錄到 0x00000000 位址上(nor flash)中才對。而且工程編譯後又沒有bin或hex檔案,也沒法直接用h-flasher燒。
(1)我該怎麼讓**在除錯時燒到 0x00000000 上,而不是 0x30000000上。
(2)如何讓工程在編譯時生成燒錄檔案。
關於生成bin檔案方法:
1. debugrel settings->linker->arm fromelf->output format指定plain binary->output file name 路徑
2. debugrel settings->target->post-linker中選擇arm fromelf
3. 重新make,就會生成bin檔案。
ARM9學習筆記之 MMU
我記得有一次我去應聘arm linux軟體工程師。結果被問到arm中的虛擬記憶體是怎麼管理的。由於我只對x86平台下的mmu了解,所以我被問倒了。原來我所學的只是皮毛。還有很多東西值得我去深入。要做arm linux下的驅動,熟悉虛擬記憶體應該是必須的。arm9中的虛擬記憶體是怎麼實現的呢?以下是我...
ARM9學習筆記之 彙編
arm系列晶元與pc系列 可能我說法不太準確 晶元在指令設計上就有本質的區別。arm中每條指令是精簡指令集要麼是32位,要麼是16位。而pc的指令是複雜指令集,一條指令可以由多個位元組組成。1.關於函式呼叫方法 在arm彙編中,函式呼叫非常靈活。1 bl指令 bl initmem 呼叫 initme...
ARM9學習筆記之 MMU
我記得有一次我去應聘arm linux軟體工程師。結果被問到arm中的虛擬記憶體是怎麼管理的。由於我只對x86平台下的mmu了解,所以我被問倒了。原來我所學的只是皮毛。還有很多東西值得我去深入。要做arm linux下的驅動,熟悉虛擬記憶體應該是必須的。arm9中的虛擬記憶體是怎麼實現的呢?以下是我...