基于uboot的2410調試平臺的實現
發布時間:2010-4-1 17:31
發布者:lelee007
--免燒寫nand flash & 不用仿真機 哈哈,平臺! 名字起的有點大,列位看官莫笑。這年頭,就那么回事。 如果內容對您有什么用或者幫助,鄙人甚感欣慰;如果沒什么大用,首先,您水平肯定在鄙人之上,其次,就當是看閑書了,雖然筆者筆風不是那么詼諧。 其實這個東西對于熟悉ARM的人來說,真不是什么難事,太小case了。確實,筆者自己也感覺不過是雕蟲小技而已。但是為什么要寫出來了?!因為筆者也是從51轉到ARM上來的,開始的時候對這個問題困惑了很久,而且就是找不到答案。同時總結出一個問題,不要迷信網絡!網上并非要什么有什么。!RMB,很明顯無法從網上找到。如果從網上實在找不到答案,那么潛心研究研究,可能比網上“盲目”亂找收獲更大。這里之所以給“盲目”二字打上個小引號是因為,這里的盲目并非指您不知道要找什么而去找,而是指您不知道網上到底存不存在您要找的東東,就比如筆者最近總是時不時在網上找關于X11R7.5下ATI顯卡驅動的解決方案,其實AMD官方都沒給出答案,民間又怎么折騰了?如果沒有,您還要浪費時間跟那死找,..........不過經過筆者本次撰述,您就可以在網上找到答案了,KAKA~~~~~~~ 其實要筆者寫點東西也確實難,筆者自己也知道廢話多,但是木有辦法,真正內容就那么點,不扯點廢話,湊不齊篇章。 廢話到此為止,下面言歸正傳。 關于這個東東,開始的時候,筆者是因為木有錢買仿真機,而且被一遍一遍的燒寫nand flash折騰的很煩躁,因為nand flash的燒寫速度并不像下載到SRAM或者SDRAM里邊那么快。而且相當nand的壽命有限,燒寫有風險,每次都是heart hard-beating下完成的,生怕nand掛了或者CPU掛了,sigh......生亦何哀,死亦何苦。有痛如斯,夫復何求?!無奈當時對于ARM的MMU還不是很熟悉,而且當時是一邊上班一邊業余折騰,遇到問題了就有點躁。痛定思痛,長痛不如短痛!咬著牙花了一晚上把MMU看了兩遍,結果發現有好幾種配置方式,讓人抓狂哇!哈哈,想想當時真的很傻很天真,就因為有多種配置方式,段式,頁式,頁式還分個粗細,就不知道到底該用哪個更合適,后來想到linux下用哪個方式咱就用哪個方式,然后抱著這個想法去看linux內核代碼,結果不了了之--沒看明白,HOHO~~~~~~~~不過后來是在一個關于ARM MMU的例程中找到了定心丸,就用段式映射,這個最簡單!當時還不知道看SAMSUNG的代碼,很多代碼都是網上雜七雜八搜羅過來的。原理弄明白,方案定下來之后,事情就好辦多了,一步一步實施就是了,無非是代碼出問題了再調試。 廢話是不是有點多?不過筆者應該是把事情的背景都交代的一清二楚了。接下來就是具體的方案了,請各位看官務必擦亮眼睛,精彩不容錯過! 原理其實是這樣的,首先移植一個可以用的uboot,至少要包含tftp和go命令,然后將其燒到nand flash里邊,每次系統上電的時候能順利運行uboot;然后我們將編譯鏈接好的目標代碼通過uboot下載到SDRAM里邊,再從uboot里邊go到我們自己的程序去運行。 實施過程中遇到的幾個問題如下: 1、代碼的存儲位置和運行位置的問題 2、中斷向量表的位置問題 3、中斷入口配置 第一個問題中關于兩個位置的問題,這應該是連接器要處理的,這個問題不是這里的闡述重點,有興趣的可以參考《arm學習報告》系列文檔,里邊基本講的非常詳細,而且不像GNU Ld那么長篇大論。雖然這個問題不是咱的重點,但是多少對咱是有影響的,不然.............講講到底怎么影響咱的是正事,廢話就不扯了,嘿嘿,因為,廢話已經扯了很多了,GAGA~~~~~~~~~。因為從原理上來看,我們自己編寫的程序用這種方式來調試的話,就不可能再放到0地址開始,讓系統自動加載了,因此存儲地址和運行地址都不能直接用默認的0了,這個地址需要我們在鏈接腳本里邊親自指定一下。為了節省大家時間,筆者在尼度給倆例子吧,一個是源代碼里邊的鏈接腳本文件,一個是鏈接腳本的書寫規則。 SECTIONS { .text 0x30004000 : { head.o clock.o init.o led.o serial.o timer0.o mmu.o interrupt.o main.o } } 這個是鏈接腳本,其中的 0x30004000地址前面的text是指如下內容全是文本段。關于文本段如果您不想看別的資料,就簡單的理解成是代碼段吧。實際也是代碼的運行地址,更確切的說是運行地址的開始,就是我們目標代碼的入口地址。鏈接以后,程序在執行時的一些相對跳轉中,這個地址就是個基地址了。如果在把程序從別的介質加載到運行內存(SDRAM)時,地址發生了錯誤,有些程序就無法正常執行,這就是位置相關和位置無關代碼的區別。 下面是我注釋的一個lds文件的書寫規則,估計大多數看官都能很快看明白,當然,能把lds的書寫規則系統的研究研究,絕對是大有裨益。 ![]() 可能以上內容講的不夠詳細,但是木有辦法,如果這些東西對于您理解這些東西來說還不夠的話,那么強烈建議您認真閱讀下《arm學習報告》系列文檔,共有3篇,《arm學習報告001》、《arm學習報告002》、《arm學習報告003》,因為那個里邊對這個分析的是比較到位的,而且篇幅并不大,絕對值得品味的,筆者也就不再好意思再擱這廢話了。 之所以講以上關于鏈接的問題,就是因為我們的程序最后不可能放到0地址,然系統一上電就自動去運行,而是要放到SDRAM里邊去,然后從uboot里邊go過去。 如果是一個非常簡單的程序,不涉及中斷的,那么只講講上面的內容,加上筆者推薦的幾篇文檔,差不多足夠了。但是這樣玩起來就太沒意思了,只夠點個流水燈而已!如果加上中斷,那差不多就把ARM的體系全弄明白了吧。接下來就切入ARM的中斷。 ARM的中斷體系實際上也不復雜,向量中斷一共就那么8個,reset一個,幾乎是個CPU都會有這玩意,就像男人的撒尿工具。然后就是什么未定義的一個,軟中斷,預取終止,數據終止,中間還有個未使用的,后面就生外部中斷和快中斷了。這8個里邊我們用到最多的也就是reset、外部中斷這兩個,連快中斷都比較少用。 reset就是一個入口,CPU在上電的時候先找她!如果您有什么工作希望CPU在上電之后就做的話,您也找她! 外部中斷的入口用處是非常強大的,因為一切外部中斷源都要經過他。2410上的外部中斷實際上是這樣安排的,首先在系統的向量中斷中安排了外部中斷這一級,然后在外部中斷中又安排了下一級的中斷表,這一級就不再是向量式的了,但是這一級的中斷入口都是隔4個字節放置一個,即每個入口的地址用4個字節來描述。這就是2410的二級中斷表。第二級的中斷表其實每個地址也是固定對應一個中斷源的。算了,還是廢話少說,上代碼。 _start: @ 0x00: 中斷向量表并非從0地址開始放置,因為我們使用的直接SDRAM調試時,中斷入口是需要通過MMU來映射的 @Reset: b Reset @直接在SDRAM中調試的話,實際是不使用Reset的,因此一Reset,硬件系統將從nand flash中讀取uboot來執行,所以此處實際是個空語句處理 @ 0x04: Undefined instruction exception HandleUndef: b HandleUndef @ 0x08: Software interrupt exception HandleSWI: b HandleSWI @ 0x0c: Prefetch Abort (Instruction Fetch Memory Abort) HandlePrefetchAbort: b HandlePrefetchAbort @ 0x10: Data Access Memory Abort HandleDataAbort: b HandleDataAbort @ 0x14: Not used HandleNotUsed: b HandleNotUsed @ 0x18: IRQ(Interrupt Request) exception ldr pc,HandleIRQAddr @ ldr pc,=HandleIRQ @ 0x1c: FIQ(Fast Interrupt Request) exception HandleFIQ: b HandleFIQ 這幾行是最基本的,不用講也該明白。 |
-
-
29.51 KB, 下載積分: 積分 -1
網友評論