WINCE6.0深入理解TOC
********************************LoongEmbedded************************
作者:LoongEmbedded(kandi)
時間:2011.7.17
類別:WINCE 系統開發
********************************LoongEmbedded************************
TOC: Table Of Contents, OEM on disk structure.
?
1.????? pTOC指針指向的結構體
pTOC在\WINCE600\PUBLIC\COMMON\OAK\DRIVERS\ETHDBG\BLCOMMON\blcommon.c中定義,如下:
ROMHDR * volatile const pTOC = (ROMHDR *)-1;// Gets replaced by RomLoader with real address
可知pTOC是指向ROMHDR結構體的指針,在\WINCE600\PUBLIC\COMMON\OAK\INC\romldr.h中定義,如下圖:
圖1
我們通過viewbin –r eboot.bin和viewbin –r nk.bin獲取的信息如下圖:
圖2
由圖2可知eboot.bin的pTOC指向的起始地址為0x80070e7c,大小為0x00000054的內存區域,也就是說eboot.bin的TOC信息保存在這塊內存區域。這塊內存區域的內容可以通過viewbin –d eboot.bin de.txt獲取到的相關內容如下:
圖3
通過同樣的方式,我們也把nk.bin中的TOC相關信息貼出來:
圖4
下面就結合圖3和圖4來學習ROMHDR結構體成員的意義:
1)????? dllfirst成員
這是分配給NK.bin的動態連接庫(dll)使用的虛擬內存的ROM DLL區間的起始地址,在WINCE系統中,0x40000000到0x5FFFFFFF范圍的共512MB的虛擬內存空間被定義為ROM DLL區間。從圖3和圖4可直接看到的值是01C00140,實際是0x4001C001,這是因為ARM采用小端的數據存儲格式,也即高字節數據保存在低地址空間處。
?
我們知道eboot.bin中是不包含dll文件的,這里的值對于eboot.bin來說應該是沒有實際的意義的。
2)????? dlllast
這是分配給NK.bin的動態連接庫(dll)使用的虛擬內存的ROM DLL區間的結束地址,eboot.bin中此值為0x4001C001,和dllfirst的值一樣,這是意料之中的,因為eboot.bin中沒有包含dll;nk.bin中此值是0x416EC101,說明dll實際占用的ROM DLL空間大小為0x416EC101-0x4001C001=0x16D0100,大概22M左右。
3)????? phyfirst
鏡像文件(這里指eboot.bin和nk.bin)的起始存儲地址,這個值等于鏡像文件的image start,對于eboot.bin來說,此值為0x80030000,通過圖2可知就是eboot.bin的image start的值,這個值在eboot.bib中定義,如下圖所示:
圖5
也可以看出nk.bin中此值為0x80100000,通過下圖的命令
圖6
可知此值等于nk.bin的image start,此值由config.bib中的內容來決定的
圖7
4)????? physlast
鏡像文件的結束存儲地址,eboot.bin中此值為0x80071DF4,該值=image start+length=0x80030000+0x00041DF4;nk.bin中此值為0x81CEC494也等于nk.bin中的image start+length。
5)????? nummods
TOC入口(entry)的數目,eboot.bin中該值為0x00000001,也即eboot.bin中有一個TOC入口,而鏡像文件中每個模塊(exe或是dll都有一個TOC入口),所以eboot.bin中包含一個模塊,這個模塊是什么呢?見下圖:
圖8
可知此模塊是NK.exe,這個意思nk.exe實際就是eboot.exe,我們通過eboot.bib下面的內容可知:
MODULES
;Name ???????? Path?????????????? Memory Type
;?? --------------? ----------------------------------------------??????????????????? -----------
nk.exe ? $(_TARGETPLATROOT)\target\$(_TGTCPU)\$(WINCEDEBUG)\eboot.exe????? EBOOT
nk.bin中為0x000000FB,也即nk.bin中有251TOC入口,也就是總共包含有251個模塊(dll或exe)。
6)????? ulRAMStart
表示鏡像文件的RAM的程序內存區域的起始地址,這里RAM的程序內存區域是指沒有被系統保留(RESERVED,見config.bib)的,沒有被用作對象存儲的,也沒有被用作加載時存放操作系統鏡像的,而是可用于操作系統及應用程序在運行過程中分配的RAM內存空間。
?
?
eboot.bin中該值為0x800B0000,是由圖5的“RAM”這一項得值來確定的;nk.bin中該值為0x81CF0000,為什么是這個值呢?根據圖7“RAM”這一項得值是0x82900000啊?原來和config.bib中的下面的內容有關:
AUTOSIZE=ON
因為為ON表示RAM的空間可以根據具體的情況來調整,我們當前nk.bin的Image Start = 0x80100000,length = 0x01BEC494,那么nk.bin被加載到RAM的結束地址=Image Start+ length=0x81CEC494,因為這個值小于圖7中RAMSTART=0x82900000的值,所以程序內存區域會根據nk.bin實際占用的RAM的空間來確定程序內存區域的起始地址。另外我們知道WINCE的內存是基于頁式管理的,WINCE操作系統支持兩種頁大小:1KB和4KB,在WINCE中,虛擬內存的申請分為保留(reserve)和(commit)兩個過程,虛擬空間的保留是以64KB(0X00010000),也就是說在任何一次虛擬內存申請都會返回一個64KB的整數倍的地址,而把虛擬內存提交到物理內存是以頁(在此是4KB為一頁,也就是0x00001000)為粒度的,所以可以得出程序內存區域的起始地址為0x81CF0000。當然了如果AUTOSIZE=OFF,那么就根據圖7指定的范圍來得到ulRAMStart和下面的ulRAMFree的值。結合下圖可以更好理解:
圖9
7)????? ulRAMFree
RAM的程序內存的空閑可用區域的起始地址,eboot.bin中該值為0x800B8000,說明從0x800B0000到0x800B7FFF用于eboot的程序運行時所需要的內存空間,同理可以如此分析nk.bin。
8)????? ulRAMEnd
程序內存區域的結束地址, eboot.bin中該值為0x800C0000,見圖5中隊RAM項的描述可以理解,對于nk.bin可以結合config.bib中來理解,見圖7。
9)????? ulCopyEntries(Number of copy section entries)
全局變量重定位時要復制的入口數,eboot.bin中為0x00000001,也就是1個入口,這個就是eboot.exe的入口;nk.bin中為0x00000002,具體是復制哪兩個模塊的TOC入口呢?希望在后面的學習中可以搞清楚。
10)?? ulCopyOffset
全局變量重定位時要復制的入口的偏移地址,對于eboot.bin,我們知道加載的時候是保存在0x80030000這起始內存處,大小為0x00041DF4的內存區域處,見圖5中EBOOT這項的描述。eboot.bin中該值為0x80070EF0,那么這個地址處對應的內容是什么呢?
圖10
可知eboot.bin中的全局變量重定位時的復制入口的偏移地址就是上圖淡藍色部分,這些值在后面的學習中再來看其作用。Nk.bin中該值為0x81759D78,我們知道nk.bin重定位時要復制的TOC入口數是2個,通過同樣的方式下面就來看0x81759D78對應的地址處的內容:
圖11
也就是對應nk.bin的copy sections的內容。
11)?? ulProfileLen
用于profile調試功能的入口的字節長度,eboot.bin和nk.bin中該值都為0。
12)?? ulProfileOffset
用于profile調試功能的入口的偏移地址,eboot.bin和nk.bin中該值都為0。
13)?? numfiles
鏡像文件中包含的文件個數,因為eboot.bin中沒有包含文件,所以該值為0,而nk.bin該值為0x00000075,也就是117個,我們通過viewbin –t nk.bin >nt.txt獲取到nk.bin包含的文件如下圖所示:
圖12
我們再把FILES最后的文件貼出來:
圖13
結合圖12和圖13可知nk.bin包含的文件個數=417-301+1=117個。
14)?? ulKernelFlags
記錄的是操作系統內核可選屬性的標志位掩碼,因為這個標志位對于eboot.bin沒有意義,所以該值為0,而nk.bin的該位可能包含的標志位掩碼值如下圖:
圖14
這個值是由config.bib的ROMFLAGS這一項的值來決定的,因為本config.bib的內容如下:
ROMFLAGS=0
所以該值為0。
15)?? ulFSRamPercent
表示用于文件系統的RAM內存的百分比,因為這個標志位對于eboot.bin沒有意義,而nk.bin中該值為0x0D0D0D0D,則表示第一個1MB內存保留了13(0x0D)個4KB頁,第二個1MB內存保留了13(0x0D)個4KB頁,第三個和第四個字節也如此,所以用作文件系統的內存空間的百分比=(13+13+13+13)*4KB/4MB=5.07%,盡管計算方式如此,但是分配給文件系統使用的RAM內存地址是連續的。
16)?? ulDrivglobStart
設備啟動程序全局變量的起始存儲地址,eboot.bin和nk.bin中該值都為0。
17)?? ulDrivglobLen
設備啟動程序全局變量占用存儲空間的字節長度,eboot.bin和nk.bin中該值都為0。
18)?? usCPUType
代表我們WINCE系統運行所在的CPU的類型,eboot.bin和nk.bin中該值都為0x000001C2
19)?? usMiscFlags
操作系統鏡像的混合標記選項,nk.bin該值為0x00000002
。
20)?? pExtensions
存放ROMHDR擴展數據的內存區域的指針。Eboot.bin該值為0,nk.bin該值為0x80101020,見下圖:
圖15
0x80101020內存地址處保存的是ROMHDR擴展數據,因為目前的設計中沒有使用到這些數據(應該是XIP內核中使用的),所以其值為0。
21)?? ulTrackingStart
用于Tracking調試功能的內存區域的起始地址,eboot.bin和nk.bin中該值都為0。
22)?? ulTrackingLen
用于Tracking調試功能的內存區域的字節長度,eboot.bin和nk.bin中該值都為0。
?
到此ROMHDR結構體已經介紹完畢,下面來看TOC的應用。
?
2.????? 用到TOC的地方
?
2.1?? eboot中用到TOC的地方
2.1.1???????? main函數調用BootloaderMain函數,而此函數開始就調用KernelRelocate函數來重
定位全局變量:
if (!KernelRelocate (pTOC))
??? {
??????? // spin forever
??????? HALT (BLERR_KERNELRELOCATE);
}
這里的pTOC是指向eboo.bin的TOC數據的,KernelRelocate的函數體如下:
圖16
可以結合對ROMHDR結構體的介紹更容易理解。
2.1.2???????? eboot更新NK的時候,會調用WriteOSImageToBootMedia()->GetKernelExtPointerH
函數來判斷nk.bin中是否包含nk.exe及其擴展指針,下面就來看這個函數:
圖17
圖18
圖19
圖19也就是ROMHDR結構的內容。
圖20
2.2?? NK中用到TOC的地方
2.1.1 ARMInit函數中
在系統啟動過程中會調用ARMInit函數,此函數體如下:
圖21
下面來看FindKernelEntry的函數體
圖22
圖23
系統中還有其他地方用到TOC信息,從上面的描述可知道TOC信息的重要性,到此也進一步學習和理解了TOC。
?
總結
以上是生活随笔為你收集整理的WINCE6.0深入理解TOC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WINCE6.0+S3C6410睡眠和唤
- 下一篇: S3C6410的Bootloader的两