我們的Image主要由兩部分組成:XIPKERNEL.bin和NK.bin,XIPKERNEL.bin中的東西就是那些WinCE中比較核心的又需要經常加載的一些程序和DLL文件,這些文件會被Boot Loader在剛啓動的時候拷貝到RAM中去,這樣就可以在RAM中XIP(Excute in place)了。在NK.bin中的基本上是需要但不至於要常駐內存的一些程序和DLL了,比如我們BuildIn下的大部分驅動,比如微軟的IE,mediaplayer等應用程序,甚至連設備管理器device.exe也可以放到這裏面,這些文件只有在需要的時候才被複制到內存中去執行,節約了內存並且也加快了啓動的時間。嘿,到這裏大概知道binfs的工作原理和重要性吧。
binfs 在燒image的時候會自動把XIPKERNEL和NK分別保存到flash的特定的邏輯扇區上.啓動的時候Boot Loader會先把XIPKERNEL複製到RAM中,然後跳到RAM中的XIPKERNEL的入口點去執行,這個時候會跑一些OEMinit之類的CPU,內存,中短等初始化的過程,接着OS會從註冊表中找到binfs的一些設置,然後加載binfs的驅動使binfs分區對OS來講是可用的,假如device.exe是在NK.bin中的話,那麼在這個時候就可以用/binfs/device.exe(/binfs是假設的裝載路徑)來調用它了,如果這個時候binfs沒有初始化成功那麼,device.exe得不到執行,那麼系統肯定就起不來了。
現在來講講HIVE,其實HIVE是個很簡單的東西,都怪和binfs牽到一起搞得很多問題都走錯了方向.這麼說吧,WinCE下面就兩種註冊表,一種是RAM based,另外就是HIVE based了,缺省用的是前者,如果用前者PB會在編譯的時候把common.reg和platform.reg的內容做到一個叫reginit.ini的文件然後壓縮成default.***的文件放到XIPKERNEL中去,image在起來的時候會把這個文件解壓到RAM中形成RAM based註冊表,既然是RAM based那麼所有的改動都會在斷電後蒸發,哈哈。怎麼辦呢?其實再笨你也能想出來,保存到磁盤上不就結了嗎!?對你太聰明瞭,但是你想如果你把註冊表全放到磁盤(SDMMC或HDD或Flash)上WinCE怎麼在沒有加載你磁盤的驅動的情況下讀到註冊表呢?而一般情況加載磁盤的驅動程序也是要註冊表的支持啊!嘿,對了,這就是HIVE想到的,看它怎麼做,它把註冊表分成兩部分(其實是三部分,當時大體還是兩步分,把user.hv和system.hv做一部分),第一部分就是叫做boot.hv的註冊表,裏面的東西就是一些在沒有拿到保存在磁盤的註冊表之前引導時需要的一些設置,這部分的註冊表和RAM based的是一樣的,改了之後斷電就沒了,所以這部分的註冊表項都是不需要改動的,需要改動的都放到第二部分就是了,這第二部分就是system.hv和user.hv了,也就是一直提到的要放到磁盤上的註冊表. 編譯的時候PB會根據platform.reg和Common.reg中的標籤判斷哪些表項放到boot.hv中,這個標籤就是;HIVE BOOT SECTION ;END BOOT SECTION,夾在這個標籤之間的表項PB在編譯的時候會把它們塞到boot.hv中去(boot.hv是二進制文件,要看裏面到底放了哪些表項用一個老外寫的工具吧,好像叫d_readvol.exe,到google上找得到的),其他的內容會分別塞到default.hv和user.hv中去,最後會把這三個hv文件統統塞到XIPKERNEL中去,這樣WinCE在引導的第一階段就把所有的hv扔到RAM中去了,然後打開boot.hv拿到必要的資料,這其中包括如何加載放置system.hv的磁盤的驅動,所以那些和加載這個磁盤相關的驅動要統統放到boot.hv中,比如FAT文件系統驅動,mspart分區驅動等等,這裏有一點很重要就是假如你用binfs而且device.exe在NK.bin中,那麼一定在第一階段要保證binfs可用,否則這裏就不可能爲system.hv創造條件了。WinCE第一次啓動時候磁盤上沒有東東,這個時候WinCE會將內存中的default.hv和user.hv複製到註冊表BootVars指定的地方,default.hv往往會被重命名爲system.hv,第二次啓動會先檢查磁盤上的hv是不是和內存中的一致,不一致就加載磁盤上的表項。
整個過程就是這樣子,但要注意一點,HIVE註冊表也是在內存中運行的,不同的是啓動的時候會從磁盤上去讀改動的表項,因爲這樣才能保證速度,所以你做的的註冊表改動也是在內存中做的,這個時候如果你不掉用FlushRegister去將內存中的數值保存到磁盤上那麼這些改動還是會丟失的。兩種方法來避免丟失,一種是認爲去調用FlushRegister,令一種就設置一個flag讓WinCE在每次改動註冊表後自動Flush.
最後總結一下:
1.新建一個工程,把該選的組件都選上。
2.添加HIVE支持。
a. 在PB中加入"Hive-based Registry"、“FAT FILE SYSTEM”。
b.打開platform.reg,完成如下信息:
;HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE/init/BootVars]
"SYSTEMHIVE"="Documents and Settings//system.hv" ;system.hv會保存到/HDD/Documents and Settings/system.hv
"PROFILEDIR"="Documents and Settings" ;user.hv會保存到/HDD/Documents and Settings/default/user.hv
"Start DevMgr"=dword:1 ;這個說是啓動device.exe,但是wince 5.0好像不用這個
"DefaultUser"="default" ;咱們只有一個用戶default,基本上就是決定user.hv的路徑了
"Flags"=dword:3 ;這個應該是wince 5.0下決定在哪個階段啓動device.exe的表項
"RegistryFlags"=dword:1 ;這個就是設置註冊表每次改動後自動flush到system.hv
;"SystemHiveInitialSize"=dword:19000 ; Initial size for hive-registry file
; END HIVE BOOT SECTION
;#####################################################################################################
; HIVE BOOT SECTION
; Add BinFS to partition table
[HKEY_LOCAL_MACHINE/System/StorageManager/PartitionTable]
"21"="BINFS"
[HKEY_LOCAL_MACHINE/System/StorageManager/BINFS]
"Folder"="BINFS"
"FriendlyName"="Bin FileSystem"
"Dll"="binfs.dll"
; MountFlags:
; 0x10 specifies that this file system is to be mounted as an external
; ROM filesystem shadowing the /windows directory
; 0x1 specifies that the mountpoint /BINFS is to be hidden
;
"MountFlags"=dword:10
"BootPhase"=dword:0
[HKEY_LOCAL_MACHINE/System/StorageManager/AutoLoad/SMFlash]
"DriverPath"="Drivers//BlockDevice//SMFlash"
"LoadFlags"=dword:1
"MountFlags"=dword:11
"BootPhase"=dword:0
[HKEY_LOCAL_MACHINE/Drivers/BlockDevice/SMFlash]
"Prefix"="DSK"
"Dll"="BIBDrv.dll"
"Order"=dword:0
"Ioctl"=dword:4
"Profile"="SMFlash"
"FriendlyName"="Samsung Flash Driver"
"MountFlags"=dword:11
"BootPhase"=dword:0
; Bind BINFS to the block driver
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/SMFlash]
"DefaultFileSystem"="BINFS"
"PartitionDriver"="mspart.dll"
"AutoMount"=dword:1
"AutoPart"=dword:1
"MountFlags"=dword:11
"Folder"="ResidentFlash"
"Name"="Samsung Flash Disk"
"BootPhase"=dword:0 ;要在第一階段加載binfs
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/NANDFLASH/BINFS]
"MountHidden"=dword:1
"MountAsROM"=dword:1
[HKEY_LOCAL_MACHINE/System/StorageManager/AutoLoad/SMFlash/Filters/CacheFilt]
"Dll"="cachefilt.dll"
"LockIOBuffers"=dword:1
; END HIVE BOOT SECTION
;#####################################################################################################
;1st fat area
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/FlashDisk]
"Prefix"="DSK"
"Dll"="ONDisk.dll"
"Order"=dword:1
; "Index"=dword:1
"IClass"=multi_sz:"{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
"Profile"="FlashDisk"
"BmlVolumeId"=dword:0 ; BML volume ID = 0
"BmlPartitionId"=dword:8 ; BML parition ID = PARTITION_ID_FILESYSTEM
"WMRStartSector"=dword:0
"WMRNumOfSector"=dword:40000 ; 128MByte
; "Flags"=dword:11000 ; do not load again in boot phase 2 ;
IF IMGHIVEREG
"Flags"=dword:1000 ; do not load again in boot phase 2 ;
ENDIF IMGHIVEREG
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDisk]
"DefaultFileSystem"="FATFS"
"PartitionDriver"="mspart.dll"
"Name"="PocketMory MLC Disk"
; "Folder"="Sys"
"AutoMount"=dword:1
"AutoPart"=dword:1
"AutoFormat"=dword:1
; "MountFlags"=dword:0
; "Ioctl"=dword:4
IF IMGHIVEREG
"MountAsBootable"=dword:1 ; for Hive-based registry,這個是wince 5.0下指定這個分區保存system.hv的關鍵
ENDIF IMGHIVEREG
[HKEY_LOCAL_MACHINE/System/StorageManager/AutoLoad/FlashDisk]
"DriverPath"="Drivers//BuiltIn//FlashDisk"
; LoadFlags 0x01 == load synchronously
"LoadFlags"=dword:1
"BootPhase"=dword:0
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDisk/FATFS]
"FriendlyName"="PocketMory FAT FileSystem"
; "Dll"="fatfsd.dll"
"Flags"=dword:00000014 ; FATFS_ENABLE_BACKUP_FAT | FATFS_DISABLE_AUTOSCAN
"Folder"="Sys"
"FormatExfat"=dword:1
; "EnableCacheWarm"=dword:0
"CheckForFormat"=dword:1
"EnableWriteBack"=dword:1
"EnableCacheWarm"=dword:0
[HKEY_LOCAL_MACHINE/System/StorageManager/AutoLoad/FlashDisk/Filters/CacheFilt]
"Dll"="cachefilt.dll"
"LockIOBuffers"=dword:1
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDisk/FATFS/Filters/CacheFilt]
"Dll"="cachefilt.dll"
"LockIOBuffers"=dword:1
; END HIVE BOOT SECTION
;#####################################################################################################
3.打開SMDK6410/SMDK6410.bat,打開xip開關
set IMGMULTIXIP=1
4.對FILES/config.bib進行修改
;下面這個layout可以隨便改,以適應自己的系統。要注意layout的規律哦。
#define CHAIN_ADDRESS 806C0000
#define CHAIN_LENGTH 00004000
;-----------------------------------------------------
; NAME ADDRESS SIZE TYPE
;-----------------------------------------------------
XIPKERNEL 80100000 005c0000 RAMIMAGE
CHAIN $(CHAIN_ADDRESS) $(CHAIN_LENGTH) RESERVED
NK 80700000 03F00000 NANDIMAGE
RAM 80700000 05600000 RAM
FLASH 92000000 00100000 RESERVED
5.對FILES/platform.bib進行修改
把所有的NK都更改爲$(XIPKERNEL),爲了在xipkernel啓動就把外圍設備驅動load到內存,要不會造成外圍設備用不了。
6.加入最小系統文件。要加入的文件有:
//必須的有
"nk.exe",
"coredll.dll",
"filesys.dll",
"exfat.dll",
"diskcache.dll",
"fatutil.dll",
"binfs.dll",
"fsdmgr.dll",
"mspart.dll",
"ceddk.dll",
"cachefilt.dll",
"kernel.dll",
"k.coredll.dll",
"fpcrt.dll",
"k.fpcrt.dll",
"romfsd.dll",
"device.dll",
"udevice.exe",
"devmgr.dll",
"kitl.dll",
"pm.dll",
"devmgr.dll",
"wince.nls",
"initobj.dat",
"ONDisk.dll",
"initdb.ini",
"boot.hv",
//推薦繼續添加的
"busenum.dll",
"servicesEnum.dll",
"servicesd.exe",
"services.exe",
"servicesStart.exe",
"oalioctl.dll",
添加方法有三種:
1.編譯一次工程,然後修改build下的common.bib,把對應的都改爲XIPKERNEL,MAKE IMAGE.(注意:只能用make image)
2.編譯一次工程,然後修改build下的ce.bib,把對應的都改爲XIPKERNEL,在VS2005中project->open realease...,運行
romimage ce.bib(注意:只能這樣用)
3.把附件中的processbib.exe,preromimage.bat加入到FILES/下,build 該工程即可,編譯一次後也可以直接make image.推薦這個方法,一勞永逸,而且不容易操作出錯哦。
7.用eboot燒寫xip.bin.
轉自CSDN:http://blog.csdn.net/lpt19832003/article/details/4537946