DM365的UBL源碼分析(四)

轉自:http://blog.chinaunix.net/space.php?uid=7214824&do=blog&id=160528

下面繼續分析,由於後面的代碼和函數量相對的多且複雜,所以不再貼上代碼,只說流程,只要把程序源碼打開對着看很容易就明白了。

 
      在DEVICE_init()這個大的平臺初始化函數結束以後,下面要做的工作就是將NAND的中UBOOT複製到DDR中並且跳轉到那裏,然後UBL的歷史使命結束,UBOOT的執行開始,那麼就是調用這個函數,NANDBOOT_copy()。
 
      NANDBOOT_copy()函數主要分三大塊,第一大塊是調用NAND_open()函數對NAND控制器和NAND芯片進行初始化,它傳遞的參數是CE的地址(一般是CE0)和總線位寬(一般是8位)。好,我們跳到NAND_open()函數中。
 
      NAND_open()函數在common\driver\src\nand.c中,與平臺無關。首先定義一個NAND_InfoHandle結構 hNandInfo,這個結構包含了所有與NAND有關的參數,比如廠商ID,設備ID,基址,位寬,塊數,頁數每塊,頁大小及與ECC,BB有關的一些 函數。然後對這個hNandInfo進行賦值,這裏最重要的是把 DEVICE_NAND_PAGE_layout,DEVICE_NAND_ECC_info,DEVICE_NAND_BB_info,DEVICE_NAND_CHIP_infoTable 這四大全局結構賦給了hNandInfo的相關字段。這四大全局結構在每個平臺目錄下都有定義(比如dm36x\common\src \device_nand.c),編譯不同平臺的UBL,會將不同平臺的四大全局結構傳遞給nand.c中使用,這樣就做到了NAND的驅動分離中平臺無 關部分和平臺有關部分,這種思想也貫穿在整個LINUX的架構中,先不提這個。然後,操作AEMIF寄存器使能NAND的哪一個CE中,這個由傳遞的基址 決定,一般是CE0,並使能這段片選之上有ECC功能。
 
      接着調用NAND_reset()函數對NAND芯片進行復位,這個函數本身很簡單,就是先發復位命令0xFF,再等待操作完成,懂得NAND操作過程的 會很容易這個操作。但是這裏多說一點,一般我們遇到的芯片操作NAND,其CPU內部會有一個NAND控制器,對NAND的操作會通過這個寄存器來操作, 發命令發地址等都是操作這些寄存器來完成。但是DM365不是這樣,它沒有實質上的NAND控制器,它還是將NAND當做是一個類RAM一樣的操作,通過 總線上的時序來完成。CLE和ALE連在地址總線A2和A1上,這樣的話發命令實質上就是在總線地址0x00000010u上寫值(注意DM365的地址 線問題,有個32位問題),發地址實質就是在總線地址0x00000008u上寫值,讀寫數據實質就是在總線地址0x00000000u上讀寫值。這些地 址的操作隱含着CLE和ALE的高低電平,再加上配好的時序參數就把NAND的操作弄成了類RAM的操作。這種操作以前沒有碰到過,TI的工程師很牛。
 
      接着調用LOCAL_flashGetDetails()函數,這個函數很重要,它會得到NAND的很多詳細信息。首先它會判斷NAND是否是ONFI, 這個沒有細究過,跳過不管。然後它會向NAND發讀ID命令,從而得到NAND的廠商ID和設備ID值。有了這兩個值就好辦了,通過一個循環把它們通四全 大局結構中的DEVICE_NAND_CHIP_infoTable中定義的各種NAND的資料進行對比,通過ID來定位是哪一種NAND,然後就得出了 頁數,塊數,頁大小等重要信息。另外,還要區分NAND是大型還是小型(一般看頁大小,大於2K爲大),因爲它們的地址週期不同。這個函數後面還有一些東 西,沒有深究。調用完成後再復位一下NAND,整個NAND_open()函數就結束了。
 
      NAND_open()函數完成後,會調用NAND_readPage()函數從第25塊開始一直搜索到第50塊,只讀第0頁。因爲UBOOT放在第25 塊開始的地方,這是手冊規定的,而且第0頁放一些啓動信息等等。通過MAGIC_NUMBER來判斷是否有效,這個知識點詳見手冊。一旦 MAGIC_NUMBER正確,就會將後面的幾個字段,比如UBOOT的進入點,頁數,UBOOT在哪一個塊,哪一個頁,UBOOT的裝載點等信息就會得 到。而後循環調用NAND_readPage()函數將整個UBOOT從NAND拷貝到DDR裏,最後將剛纔得到的UBOOT的進入點地址複製到 gEntryPoint變量中。然後主函數跳轉到這裏,從此UBL結束,UBOOT正式啓動。
 
      這裏的分析沒有涉及到壞塊處理,ECC校驗的部分,一方面現在太忙沒時間細看。另一方面UBL不是重點,要想深究這個東西,還是到Linux內核裏的 NAND驅動中深究,這裏能用就行了。還有就是一開始擔心的是我們項目用到的NAND是512B每頁的老式NAND,擔心UBL不支持,需要修改UBL源 碼。後來讀了UBL源碼以後,特別是平臺相關的device_nand.c文件,才發現TI的工程師已經把該考慮的都考慮的,都能用,老外就是牛X。不像 國內的代碼,根本沒有普適性和跨平臺性。UBL整個源碼,架構較清晰,註釋也多,代碼整體很完整和美觀,很有參考和學習價值。讀了UBL源碼後,其實很容 易就能讀懂NANDEraser,NANDWriter等的源碼了,說白了就是平臺初始化加NAND讀寫,呵呵。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章