WINCE6.0+S3C2443的启动过程---eboot5
2.3.5 SD卡控制器的相關初始化
一個相關的帖子http://topic.csdn.net/u/20100812/16/d0d5108b-dce1-4535-9e15-6f87bad57e43.html?r=67649425
?
GPG8---nCD_SD,這個引腳用于判斷是否有SD卡存在。
GPH8---WP_SD,這個引腳用于判斷SD卡是否lock。
GPE5---SD_CLK
GPE6---SD_CMD
GPE7---SD_DATA0
GPE8---SD_DATA1
GPE9---SD_DATA2
GPE10---SD_DATA3
⑴把GPG8和GPH8設置為輸入,以便判斷SD卡是否存在?SD卡是否lock?并且把GPE5到GPE10配置為SD卡的功能腳。
?
?
⑵初始化SD卡控制器并且初始化并且通過調用函數f_mountdrv來安裝文件系統(tǒng),
SD_card_init()即是初始化SD卡控制器的,在這里就不詳細描述這兩個函數了。
?
⑶解析FAT/FAT32格式,找到NK.BIN,并能將其讀取到內存中,再假設NK.BIN如下載一般到內存中,將其燒寫到nand flash中。
?
2.3.6顯示bootloader更新NK的進度條
?
?
2.4 OEMPreDownload (),對于SD卡的更新方式,這里只是根據之前的條件判斷當前的動作是正常啟動還是要更新NK,在這里應該也可以對bootloader和OS之間共享的數據進行設置。
?
?
2.5 DownloadImage()
下圖是BootloaderMain函數的主要函數體,也即更新NK并且跳到特定地址啟動OS的主要實現部分
?
這里我們看看DownloadImage函數,主要內容如下:
⑴通過調用函數dwImageType = GetImageType()來獲取
?
調用函數OEMReadData來得到SD卡中映像文件,并且取出這個文件的前面7個字符保存在g_hdr數組中,接下來便判斷當前的映像文件是什么類型的。我們要
更新的是NK.bin,我們來看看NK.bin的格式
?
可以知道NK.bin的頭7個字符是B000FF,所以GetImageType函數返回BL_IMAGE_TYPE_SIGNED_BIN值來為后面的更新動作做好準備,我們在這里來看看OEMReadData函數功能:
?
接下來會調用函數SdMmcReadData
?
SdMmcReadData函數中的
volatile U32 readLenIndex = SDBUFFER;
#define SDBUFFER 0x32200000
這里SDBUFFER是SDRAM地址,從SD卡從讀取到NK就放在以這個地址為開始地址的內存中。
?
⑵DownloadSignedBin函數,就是download NK的函數。
根據前面得到的image type是BL_IMAGE_TYPE_BIN來執(zhí)行DownloadImage函數中下面的語句
case BL_IMAGE_TYPE_BIN:
??? rval &= DownloadBin( pdwImageStart, pdwImageLength, pdwLaunchAddr );
break;
下面來詳細學習DownloadBin這個函數的函數體:
①通過調用OEMReadData函數來獲取NK.bin的起始地址和長度。
圖中串口輸出的信息如下
DownloadBin image dwImageStart = 0x80200000, dwImageLength = 0xE82498
?
②目前我們的bootloader是downloade單個bin。
?
g_DownloadManifest 的定義如下:
static DownloadManifest g_DownloadManifest;
在這之前bootloader沒有對g_DownloadManifest變量的初始化,所以g_DownloadManifest.dwNumRegions的初始值是0.
接著看看DownloadManifest結構體的定義:
?
從上面的定義可知
dwNumRegions:表示當前要downloade的映像個數,在這里知識download NK.bin,所以dwNumRegions=1.
Region:用來描述某個映像文件的其實地址,長度和這個映像文件的名字,這里描述的
?
③調用OEMMultiBINNotify函數來提供download的信息給OEM,也即給bootloader
?
OEMMultiBINNotify的主要函數體如下
?
上圖中第1798行就是把download的NK.bin的信息賦值給bootloader中定義的全局變量g_BINRegionInfo。
?
④通過調用OEMVerifyMemory函數來判斷當前download的NK.bin(也可以downloader eboot.bin等)
?
?
下圖中第1730和第1731行的宏的定義如下:
//
// Nk Memory reigions defined in config.bib...
//
#define ROM_RAMIMAGE_START????????? 0x80200000
#define ROM_RAMIMAGE_SIZE?????????? 0x02300000
這些值是要和files/config.bib下指定的值一直,是用來判斷當前要download的NK.bin是否在0x80200000到0x825000000的范圍之內,在這里我們這次download的NK.bin信息是:dwImageStart = 0x80200000, dwImageLength = 0xE82498
?
?
從而可以知道當前的image type是IMAGE_TYPE_RAMIMAGE。
?
?
⑤調用函數OEMReadData來讀取NK.bin的內容到SDRAM內存中
每次的讀取是以一個record為單位,分別讀取這個record的開始地址,長度和校驗碼,上圖的第1128行用于判斷當前讀取的record是否是最后的一個record,如果是,就退出while循環(huán),也即把整個NK.bin讀取到SDBUFFER指向的內存中,所以要保證有足夠的內存來保存NK.bin,NK.bin的格式如下:
?
……………………
?
在NK.bin文件的最開端,會放置一個BinFile結構,imageStart和ImageLength分別對應鏡像展開后在內存中存放的首地址和長度。該結構中的RecordNum為不確定的,通常在最后一個記錄之后增加一個address和Chksum都為0的紀錄表示結束,而這個表示結束的結構中的Length則標示其實際入口點。
?
⑥ 調用函數OEMMapMemAddr將FLASH地址映射到RAM地址中。
?
如果目標系統(tǒng)的需求是要能支持把操作系統(tǒng)的鏡像文件下載到FLASH中去,就必須調用本函數。由于FLASH操作速度比RAM慢,在片擦除的時候甚至會使讀寫操作停滯,這樣在每次下載操作系統(tǒng)鏡像文件時,由于FLASH的擦寫都會使下載停滯。而OEMMapMemAddr使用了RAM緩沖操作系統(tǒng)鏡像文件的方式,使得用戶在下載操作系統(tǒng)鏡像文件時感覺不到停滯,這個函數將FLASH地址映射到RAM地址,這樣向FLASH寫的數據實際上先被緩沖到RAM中,然后再寫到FLASH中。下面是相關帖子的鏈接:http://topic.csdn.net/u/20091218/11/e56acdfd-23a0-4542-bfac-2364a97fe2e7.html
有必要看看OEMMapMemAddr函數體:
?
#define CACHED_TO_UNCACHED_OFFSET?? 0x20000000
#define FILE_CACHE_START?? (0x80200000 | CACHED_TO_UNCACHED_OFFSET)??????? // Start of file cache (temporary store for flash images).
得到這個cache地址后,就把讀出出來的數據塊放在這個cache地址處,這個地址就是上面函數注釋中提到的file cache location
?
⑦讀出當前的record的數據塊并且校驗
?
讀取到的數據塊就保存在FLASH地址映射的RAM地址lpDest上。
?
⑧通過查找ROMHDR的地址來計算ROM的偏移量
?
?
#define ROM_SIGNATURE_OFFSET 64 //0x40
#define ROM_SIGNATURE 0x43454345??? //cece 4byte??? =>ROMHDR 在0x44偏移處,每個bin 都有個pToc指向ROMHDR開頭的地址,看下面的bin 文件結構,在0x44offset處地址里面放的是ROMHDR地址,開始是-1,由romimage.exe來設置的
上圖的第1154行主要用于判斷當前的NK.bin是否為CE的映像文件。
第1169的串口輸出信息是:rom_offset=0x0.
?
?
⑨判斷當前下載的bin文件是否包含TOC和內核(nk.exe)
?
第1188行用于判斷NK.bin文件中地址為0x80200000+0x40=0x80200040地址處保存的內容是cece,也即是否是WINCE的NK.bin,通過IsKernelRegion函數來判斷NK.bin中是否包含有NK.exe,因為有包含,所以通過1194到1196行返回NK.bin的起始地址,長度和跳轉地址給DownloadImage函數,下面看IsKernelRegion函數體:
?
這個函數的串口輸出信息如下:
kandi IsKernelRegion dwCacheAddress =0x81080628
TOC的指針地址是0x80200044處,這個地址保存的值就是TOC記錄的地址,也即從0x80200044處獲取其值(0x81080628),也就知道TOC存放在哪個record上了,在本NK.bin中,是第161個record,可從下面的圖片看出來
kandi IsKernelRegion toc copy number =191
kandi IsKernelRegion pROMHeader =0x81080628
kandi IsKernelRegion testTet =0x20
kandi IsKernelRegion plTOC =0x8108067C
0x8108067C-0x81080628=0x54(84),也就是ROMHDR結構體占用的字節(jié)數,通過下圖的Length=0x00000054也可得知。
?
第1458行為什么還要加上ROM_SIGNATURE_OFFSET(0x40)呢?因為這從0x8020000到0x8020003F是用于記錄NK.bin的開始地址和長度,而加上sizeof(ULONG)是表示0x80200040到0x80200043是用于記錄WINCE的“cece”恰好是4個字節(jié),public/common/oal/inc/romldr.h下面的定義可以讓我們更清晰去理解:
?
這里的physfirst address=image start=0x80200000。
第1471行的while用于查詢NK.bin中是否包含NK.exe,如果沒有就表示此NK.bin沒有包含內核,這樣的NK.bin就不是所需要的。
上圖第1463行的dwNumModules=191,表示NK.bin中包含的模塊的數量,包括exe和dll文件,下圖是通過viewbin –t nk.bin >aoutput.txt中關于module的內容:
?
……………………………………………
從上圖也可以看出NK.bin中包含的modules是236-46+1,正好是191個,而第一個就是NK.exe
?
⑶把NK.bin解壓到SDRAM中后,接著就計算NK.bin的檢驗碼,并且判讀是否馬上在DownloadImage函數中把解壓后的映像寫到flash中。
?
ComputeChecksum函數計算校驗碼的原理很簡單,就不介紹了,下面看WriteImageToFlash的函數體
?
串口輸出信息如下(換了個NK.bin,所以大小不同啊,哈哈):
Completed file(s):
-----------------------------------
[0]: Address=0x80200000? Length=0xE50694? Name="" Target=RAM
這個函數也很簡單,就不介紹了,到此DownloadImage函數的工作就完成了,接著回到BootloaderMain函數中,后面將繼續(xù)。
總結
以上是生活随笔為你收集整理的WINCE6.0+S3C2443的启动过程---eboot5的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在WINCE5.0开始菜单中添加应用程序
- 下一篇: WINCE下如何设置/删除/查询这些环境