【原創】關於noot的學習筆記

預備文章

//-----------------------------------------------------------------------//

Nboot程序詳細分析

Nboot和Eboot中的虛擬地址與物理地址的關係

By:昔日之ID:formerman

//-----------------------------------------------------------------------//

S3C2410&&WINCE6.0&&NBOOT

By:WE-HJB

//-----------------------------------------------------------------------//

【原創】關於WinCE中bootloader:nboot/eboot的那點事兒

【原創】關於WinCE中config.bib的問題

By:Mercury

//-----------------------------------------------------------------------//

補充資料

http://download.csdn.net/source/1929962 學習文檔附屬資料.包括所有的代碼和文檔

 

閱讀完了上面一些達人的文章以及我的那兩片惡搞的文章,大家應該對nboot有個大概的瞭解.

下面我們再來一起看看nboot.有描述不對的地方如果大家看出來請給予指出.多謝了!!

先以mini2440不帶eboot的wince5.0的nboot程序爲例,首先我們從文件上來看看nboot大概的一個輪廓:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//第一部分:地址定義
244X_addr.h
244X_addr.inc

這個部分主要是根據samsung的手冊,對相應的寄存器定製進行一個定義的工作,同時在244X_addr.inc中有一句比較重要話

   1:  
        GBLL   BIG_ENDIAN__
   2:  
BIG_ENDIAN__   SETL   {FALSE}        ;採用little_endian
這句話給出了系統的模式,有的習慣叫成大端和小端模式.具體關於大端小端模式簡單的來說用下面一個圖就可以解釋清楚了:

Big Endian
   低地址                                             高地址
   ----------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      12      |       34     |      56       |      78     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Little Endian
   低地址                                             高地址
   ----------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      78      |       56     |      34       |      12     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

big endian是指低地址存放最高有效字節(MSB),而little endian則是低地址存放最低有效字節(LSB)。

說句題外話,這裏有個小程序大家可以試試,用來測試MCU是大端還是小端

   1:  
u8 checkCPU( )
   2:  
{
   3:  
   {
   4:  
       union w
   5:  
       {  
   6:  
           u8 a;
   7:  
           u16 b;
   8:  
       } c;
   9:  
       c.a=0;
  10:  
       c.b = 1;
  11:  
       return
 (u8)(c.a!=0?1:0);
  12:  
   }
  13:  
} 
這段代碼在很多嵌入式工程師面試裏面都提及過。作爲2440是一個32位的這裏我們對程序進行稍微修改就可以了。這裏不多說。
至於如何來判斷大小端這是一個比較麻煩的問題,這裏大家可以參考samsng2440的手冊。在第二章明確指出了

ARM920T can treat words in memory as being stored either in Big-
Endian or Little-Endian format.
這句話會是我們更加迷茫,那如何來使用了。我找了一個帖子博主給出了一個解釋,文章來自:
http://www.icdev.com.cn/?1833/viewspace-2112.html

反正先不管大端小端,不用匯編基本沒什麼區別.只要在端口配置的時候注意一下就可以編程時都用大端訪問就沒事了.

這是其中的一個解釋,另外我們需要知道的是,nboot的開發環境是ADS1.2或者vs2005,這兩個環境下關於arm的編譯器ADS是armasm,vs2005的實際上也是調用的armasm.exe,具體文章請參考:
http://www.cnblogs.com/huaping-audio/archive/2009/03/18/1415893.html
這裏需要點下題目了,因爲我們在ADS開發的時候會做一個選擇芯片類型的動作,2440是ARM920T,而ADS需要對其進行修改,同時,默認的字節順序是小端,所以我們這裏設置成一個小端的模式。也只在爲了彙編部分的開發方便,在下面我們還會提及到一次這個問題。到遇到了我們再細說。這裏第一個部分我們就說的差不多了。進入下一個部分
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//第二部分:2440初始化部分
244x_init.s
Memcfg.inc

這個地方是非常重要的部分,上面準備文章中有對2410_init.s文件進行簡單的描述,這裏2440和2410的功能是完全相同,所以我們稍微更換一個主語:

244x_init.s是彙編程序,所作的工作有:屏蔽所有中斷、設置CPU的速度和時鐘頻率、RAM的初始化、LED的初始化等。

這裏需要讀者有一定的彙編知識,在附加資料中的other文件夾中我附上了一個arm指令集的pdf文檔,ARM指令(宛城布衣).pdf,這個是公認比較全面描述arm彙編指令集的資料,有需要的可以仔細閱讀。

下面分析一下244x_init.s的執行流程,對程序裏面細節的部分我不做過多的描述,這裏對程序的流程進行梳理,操作上大同小異。

進入244x_init.s首先引用了兩個彙編的頭文件,一個是地址初始化的頭文件,這個文件在上面我們已經介紹了,接着是memcfg.inc,這個文件對內存設置進行了定義,這裏我們用的是64MB的SDRAM。接下來定義的是將$HandleLabel地址空間中的數據給PC,中斷服務程序的入口並導入要用到的字符常量。這些都是常規的一些操作,完成後我們將進入本文件的主要入口點,首先需要做的是關閉中斷和看門口,接着是設置時鐘頻率,這個地方大家需要閱讀一下samsung2440手冊的第7章,關於時鐘和電源管理這個部分的內容,因爲在這裏我們要對ARM的一些基本功能進行設定,所以,程序上的順序是首先完成時鐘初始化工作,產生時鐘後,電源管理部分纔可以正常工作,然後進入電源管理部分,對電源的一些屬性進行初始化工作。這裏對電源管理部分的初始化中,大家要注意到芯片有幾種狀態,普通狀態,等待狀態,低功耗狀態和休眠狀態,對於這幾種狀態的控制上需要結合時鐘來設定,這也就是爲什麼時鐘和電源部分需要同時來完成初始化。另外要格外注意的是休眠狀態,因爲一般情況下機器都要做一個休眠的功能,而此狀態的實現從這個階段開始一直到ISR以及IST階段都是緊密聯繫的,一個環節有問題都可能導致無法休眠喚醒。關於休眠喚醒到說到ISR和IST中斷的時候在詳細來看。在手冊上249頁有詳細描述休眠喚醒的流程。
接下來完成了時鐘和電源的初始化,將需要對內存SDRAM,Flash進行一個初始化和片選的工作。這裏包括初始化各種模式下的堆指針,以及將數據段拷貝入SDRAM當中,並準備跳入C語言的main入口,完成bootloader的初始化工作。

到這裏對2440的初始化即將告一段落,跳入main入口後將進入另外一個階段,這裏我們看到main有一種特別的親切感,用過51單片機的朋友一定對這個入口不會陌生,我們在回頭思考下,51的初始化也不是差不多這樣的一個流程?剛剛還覺得非常難以理解的arm其實他的流程與51還是有相同之處,這裏又帶出了一個話,嵌入式系統的通性。進入main後就是一個無窮無盡的死循環,直到斷電,或者如果有無限的電源,將會循環到世界的末日。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////第三部分:2440其他一些外設的初始化
244X_lib.c
244X_lib.h
Def.h
Option.h

這個部分很好理解,而且是我們熟悉的C語言寫的,所以讀起來非常快,也好懂,這裏主要是對2440的一些外設進行初始化,比如說GPIO口,串口進行初始化,同時在這裏需要提到的是,串口的初始化是很重要,因爲這是唯一讓我們能知道當前系統是否正常運行一個可見的條件,當然可以通過測量始終來判斷,但是通過串口如果能看到一些打印信息,咱們就基本上可以宣佈boot成功了。所以這個地方大家可以仔細看看uart的處理部分。說起來也很簡單一共也就5個函數,初始化,接受和發送,發送包括髮送字節和字符串,這裏就不對程序進行仔細分析了,c語言的。比剛纔看彙編的親切多了。

在這裏有一個很重要的問題,mmu,在Option.h裏面定義了關於MMU_EnableICache和MMU_EnableDCache兩個函數,這兩個函數主要功能是使能數據和指令cache,這裏找了一個代碼分析的文章:
http://blog.csdn.net/garby2004/archive/2009/09/28/4605048.aspx

void MMU_EnableDCache(void)當地址Cache數據Cache分開­時,使能數據Cache;當地址Cache數據Cache統一時,使能­整個Cache。­

這裏再看一個帖子:
http://blog.csdn.net/gooogleman/archive/2009/01/05/3705173.aspx

cache:一個和CPU很近的高速存儲器,用來存儲一些不是經常變化的數據,提高速度。在經常改變的數據的時候不適合啓用,否則效率會更低
比如我們訪問GPIO等不能使用cached 地址,就是這個原因,經常替換,效率很低的。(這個東西,也是我們PC的CPU的重要指標)


MMU:用在多任務操作系統中,給每個任務提供獨立的虛擬地址空間,其實現原理是:在主存中存貯頁表等數據,通過MMU映射到CPU,然後CPU就可以使用虛擬地址調度任務,訪問外設等,虛擬地址和物理地址映射是固定的,這樣操作系統比較安全穩定。

在bootloadr中的mmu是使得arm以及cache的使用效率更高。而在oal層的mmu上,是真正的處理地址與映射表之間的關係。並不衝突。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//第四部分:對nandflash的初始化
nand.c
Nand.h
nand_s.s
爲啥叫nboot呢,寫全了就是nandflash boot,從nandflash啓動,這裏當然要對nand好好的來一番設定和配置。這裏一共包含三個文件,nand_s.s,nand.c和nand.h。這裏還是要回到手冊第六章,關於nand的操作上,基本的流程爲,初始化,完成後分析壞塊,完成後讀取nandflash內容。在這裏mini2440多做了一手也就是多了個分析flash大小的功能。具體的功能實現大家可以自己閱讀代碼連通手冊一起分析。這裏提一下ECC校驗的事情,這個篇文章也是被轉摘了無數次,大家可以閱讀下了解下ECC校驗

http://bluefish.blog.51cto.com/214870/60695

在samsung的手冊219頁對ECC進行了特別的介紹。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//第五部分:NBOOT.c
這是全文的最後一個部分,也是nboot的終結之處。因爲友善新做了一個開機logo動態進度條的功能,nboot.c第一眼看上去很複雜,其實和以往的是一樣,最關鍵的還是在ReadImageFromNand函數中。在《Nboot程序詳細分析 》一文中的2410loader.c就是我們這裏的nboot.c。所以大家可以直接閱讀此文對nboot和2410loader.c進行一個比較。其他一些功能函數比如圖片加載和動態條大家可以學習一下,在項目開發中可以用到。

 

到這裏整個nboot的程序結構我們都梳理了一遍。至於怎麼生成一個nboot.bin或者nb0,如果你用ADS的話會直接生成一個bin文件,而用vs2005,大家就可以參考《S3C2410&&WINCE6.0&&NBOOT 》這篇文章中介紹的編譯方式。

nboot開發部分學習筆記結束

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章