WINCE基于hive注册表的实现
********************************LoongEmbedded********************************
作者:LoongEmbedded(kandi)
時間:2010.12.26
類別:WINCE嵌入操作系統
********************************LoongEmbedded********************************
?
1.WINCE注冊表概述
WINCE注冊表保存著應用程序、驅動、用戶參數配置和其他配置設定的數據,WINCE提供自由選擇基于RAM還是基于hive的注冊表,其中基于RAM注冊表本質是堆棧文件,保存在RAM中,如果RAM的供電掉電了,除非OEM實現了注冊表備份的功能,否則基于RAM的注冊表數據會丟失,而基于hive的注冊表是作為文件保存在掉電不丟失的保存介質中。注冊表也可以用于系統初始化,并且可以在一個永久性存儲設備中被加載和可以被保存到另另一個永久性存儲設備。
?
?
2.WINCE支持的注冊表類型
?
我們知道了WINCE支持hive-based注冊表和RAM-based注冊表,但對于WINCE5.0,系統默認使用基于RAM的注冊表;而對于WINCE6.0,系統默認使用基于hived的注冊表。
?
2.1基于RAM的注冊表
基于RAM注冊表把所有的注冊表數據保存在對象存儲中,也就是保存在RAM中。就速度和大小方面來說基于RAM的注冊表用在有電池備份RAM的設備上面是非常有效的,在系統掉電后,只要備用電池對RAM還有供電,基于RAM注冊表的注冊表數據就不會丟失。但如果對系統進行冷啟動或者系統斷電,對注冊表的所有改動都會丟失。
如果使用基于RAM的注冊表,對注冊表的讀寫訪問操作會變得非常高效。因此基于RAM的注冊表比較適用于沒有外部存儲,而且有電池保存內存數據(battery-backed RAM)的設備。如果有外存且經常冷啟動的設備采用基于RAM的注冊表,則需要在系統斷電的時候對注冊表進行保存,等系統再次啟動時對保存的注冊表進行還原。這些特點就決定了基于RAM的注冊表多用于經常熱啟動(Warm Boot)的設備上面,而很少用在冷啟動(Cold Boot)設備上面。
?
2.2基于hive的注冊表
基于hive的注冊表把所有的注冊表數據保存在文件系統的文件上面,這樣就讓OEM可以輕易在冷啟動的情況下保存注冊表的設置。也就不再需要想基于RAM注冊表一樣在系統斷電和啟動的時候進行保存恢復注冊表的操作了。
???????? 基于hive的注冊表用在經常需要冷啟動的設備上非常高效,而很少或者從不用在熱啟動的設備上,最適合用在有永久保存介質或者多用戶的設備上。也提供不同的用戶hive,所以可以為每一個用戶定義不同的注冊表配置信息,這樣,一個多用戶的系統會辦含多個用戶的hive(user.hv),一個用戶的hive在登陸時被加載,注銷的時候被卸載。
?
???????? 基于hive的注冊表包含三部分:引導hive,系統hive和用戶hive,分別對應于boot.hv,system.hv和user.hv。Boot.hv主要用于系統引導時候所需的注冊表設置,這部分設置不會被保存在flash或者磁盤上面,也就是說,在系統掉電以后就會丟失。實際上,這部分應該說是屬于RAM-Based注冊表,由于這部分數據不需要改動,所以也就無所謂了。System.hv存放關于系統的注冊表設置,user.hv存放和用戶相關的注冊表設置。
?
在PB編譯WinCE系統的時候,Platform Builder會根據common.reg和platform.reg文件中的注釋標簽來判斷哪些注冊表設置放入boot.hv中,凡是在注釋標簽”;HIVE BOOT SECTON”和”;END HIVE BOOT SECTION”之間的設置都會被放入boot.hv中,其他的都會放到default.hv和user.hv中。
?
在WinCE第一次(更新系統)引導的時候,所有的.hv都會被放到RAM中,WinCE系統會首先讀取boot.hv進行相關引導時候的設置,然后把default.hv和user.hv放到磁盤的指定路徑下面,這個路徑也是在注冊表中設置的,然后default.hv會被重命名為system.hv。依據common.reg或者是platform.reg中的內容,比如我的系統下面的common.reg內容如下:
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE/init/BootVars]
?? "SystemHive"="Documents and Settings//system.hv"
?? "ProfileDir"="Documents and Settings"
?? "Flags"=dword:1
; END HIVE BOOT SECTION
; @CESYSGEN ENDIF FILESYS_FSREGHIVE; END HIVE BOOT SECTION當系統第二次啟動的時候,檢查內核default.hv/user.hv是否同磁盤的system.hv/user.hv一致,如果一致,則直接運行RAM中的注冊表配置,否則根據磁盤上system.hv/user.hv的內容更新RAM中的注冊表配置,這樣我們可以看出,實際上HIVE注冊表在運行的時候也是放在RAM中的,這樣速度比較快。啟動的時候會從磁盤上讀出,在用戶更改注冊表以后,會被保存在磁盤上,保存的時機也是可以設置的,可以選擇在用戶更改后立刻保存到磁盤上,也可以選擇在reboot的時候保存。
?
3.基于hive注冊表的實現
?
3.1實現基于hive注冊表
⑴在系統工程中加入基于hive注冊表的組件,見圖1
圖1
?
⑵核實OS的common.reg中是否有下面的注冊表信息
[HKEY_LOCAL_MACHINE/init/BootVars]
?? "SystemHive"="<your system hive location>"
?? "Flags"=dword:<your value>
我的系統下的common.reg相關注冊表信息如下
[HKEY_LOCAL_MACHINE/init/BootVars]
?? "SystemHive"="Documents and Settings//system.hv"
?? "ProfileDir"="Documents and Settings"
?? "Flags"=dword:1
SystemHive:系統HIVE文件的保存路徑與文件名。
ProfileDir: 用戶配置文件保存路徑。
這樣的設置在系統起來之后我們看到的相關注冊表信息如下:
圖2
但是,其實如果沒有指定SystemHiv和ProfileDir的值,只要在platform.reg中實現了profile(在此profile name是ResidentFlash)并且可以掛載在根目錄下,去掉SystemHiv和ProfileDir的值也可以,去掉之后,見系統起來之后看到的注冊表信息如下:
圖3
⑶在OS的common.reg中設置下面的內容來指定默認加載的user.hv
[HKEY_LOCAL_MACHINE/init/BootVars]
?? "DefaultUser"="<username>"
我的系統中common.reg相關信息如下:
[HKEY_LOCAL_MACHINE/init/BootVars]
?? "DefaultUser"="kandi"
DefaultUser:默認加載的用戶HIVE文件。
這樣在Documents and Settings目錄下面會有kandi這個目錄,這個目錄下保存的內容就是kandi用戶的user.hv,見下圖
圖4
但如果common.reg或者platform.reg中沒有指定DefaultUser,那么系統會生成一個默認的用戶,見下圖
圖5
⑷在系統啟動的第一階段所需要開始加載的驅動,要核實是否包含到HIVE BOOT SECTION和END HIVE BOOT SECTION注釋之間的注冊表中,如:
; HIVE BOOT SECTION
<your registry settings>
; END HIVE BOOT SECTION
因為PB編譯的時候就是根據此信息來把HIVE BOOT SECTION和END HIVE BOOT SECTION注釋之間的注冊表信息房子boot.hv中的。
⑸為在系統啟動第一階段被加載的驅動設置下面的標志位
[HKEY_LOCAL_MACHINE/Drivers/...]
?? "Flags"=dword:1000
這個標志位告訴設備管理器在系統啟動的第一階段(boot registry)加載此驅動,這樣,在系統啟動的第二階段(加載system registry)的時候就不會第二次來加載此驅動,這樣可以防止此驅動被加載兩次,我的系統的nandflash驅動就需要在系統啟動的第一階段被加載,因為nandflash需要先加載起來,后面才能把加載的system.hv和user.hv保存在掛載于nandflash的分區中。
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/NANDFLASH]
??? "Prefix"="DSK"
??? "Dll"="smflash.dll"
??? "Index"=dword:1
??? "Order"=dword:0
??? "Profile"="NANDFLASH"
??? "IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
IF IMGHIVEREG
??? "Flags"=dword:00001000
ENDIF ;IMGHIVEREG
?
這里"Flags"=dword:00001000告訴設備管理器在hive-base注冊表初始化的第一個階段來加載驅動。
?
⑹設置包含了注冊表的文件系統驅動的profile,這個值是在介質的文件系統驅動對應的存儲管理(storage manager)profile中設置,WINCE5.0及之后的版本的注冊表信息如下:
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/<ProfileName>/<FileSystemName>]
?? "MountBootable"=dword:1
?我的系統對應的注冊表信息如下:
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/NANDFLASH/FATFS]
??? "Flags"=dword:14
???????? "Folder"="ResidentFlash" ;掛載在nandflash中的分區目錄,對應此分區的
??? "FormatExfat"=dword:1
??? "CheckForFormat"=dword:1
??? "EnableWriteBack"=dword:1
IF IMGHIVEREG???
??? "MountAsBootable"=dword:1
ENDIF ;IMGHIVEREG
?
這里"MountAsBootable"=dword:1表示FATFS文件系統包含系統注冊表。
?
?3.2基于hive注冊表的建立
Platform.reg中的關于hive注冊表信息如下,有幾部分:
⑴IO資源管理器部分相關注冊表信息
Describes how the I/O Resource Manager manages interrupt requests (IRQs) and I/O address spaces and describes how to configure IRQs and I/O address space resources yourself.
?
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE/Drivers/Resources/IRQ]
?? "Identifier"=dword:1
?? "Minimum"=dword:1
?? "Space"=dword:20
?? "Ranges"="1-0x20"
;? "Shared"=""
?
[HKEY_LOCAL_MACHINE/Drivers/Resources/IO]
?? "Identifier"=dword:2
?? "Minimum"=dword:0
?? "Space"=dword:10000
?? "Ranges"="0-0xFFFF"
; END HIVE BOOT SECTION
現在大概認識一下IO資源管理器部分:
當系統引導(system boot)的時候,總線枚舉器根據注冊表信息(上面的注冊表信息就是其中一部分,我們可以配置 )枚舉注冊表和裝載內置設備。接著I/O資源管理器(resource manager)追蹤系統中可用資源的當前狀態,而且通過總線驅動(bus drivers)管理所有I/O資源請求和分配。因此,所有的總線驅動在為可安裝設備或其他類型設備加載客戶端驅動(client driver)的時候通過I/O資源管理器來請求I/O資源。
?
I/O資源管理器是設備管理器固有的一部分(instrinsic part),其在任何設備被加載之前追蹤通過注冊表初始化的有效系統資源,這樣是為了防止兩個或者多個設備驅動嘗試去使用相同的資源的時候出現的意外沖突(accidental collision)情況。
?
OAL和注冊表一般預分配總線驅動請求的IRQ(中斷請求)和I/O空間資源。可是I/O資源管理器不限于管理I/O和IRQ位置(也就是哪個I/O發送的IRQ請求吧),當然,我們可以定義有效資源的特定的集合。比如,PCI總線驅動在加載它發現的設備的設備驅動的時候會通過I/O資源管理器請求IRQ和I/O空間資源,這和PC Card總線驅動加載PC Card客戶端驅動的時候,為PC Card客戶端驅動請求I/O資源是一樣的,而在用戶拔掉從系統中拔掉PC Card的時候PC Card總線驅動會釋放這些資源。
?
每個硬件平臺有唯一的IRQs集和可用的I/O空間資源(應該可以理解為地址空間資源),內置的和固定設備的IRQs應該映射到OAL中的中斷標識符(interrupt identifiers,SYSINTR),至于怎么映射呢?我們通過camera驅動來闡述一下:
定義:
UINT32 g_CamIrq = IRQ_CAM;?????? //這個就是camera通道對應的IRQ的值
UINT32 g_CamSysIntr = SYSINTR_UNDEFINED;//在沒有被映射之前,需要賦值為//SYSINTR_UNDEFINED
映射:
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_CamIrq, sizeof(UINT32), &g_CamSysIntr, sizeof(UINT32), NULL))
??? {
??????? RETAILMSG(1, (TEXT("ERROR: CIS_INIT: Failed to request sysintr value for Camera interrupt./r/n")));
??????? return(0);
??? }
通過KernelIoControl和IOCTL_HAL_REQUEST_SYSINTR來動態映射IRQ_CAM到g_CamSysIntr,映射之后系統會分配一個邏輯中斷號給g_CamSysIntr。
?
設置中斷關聯時間:
bSuccess = InterruptInitialize(g_CamSysIntr, CameraEvent, NULL, 0);
?
IRQs和I/O空間資源是預先定義,HKEY_LOCAL_MACHINE/Drivers/Resources/IRQ和HKEY_LOCAL_MACHINE/Drivers/Resources/IO注冊表值規定了I/O資源管理器的初始化狀態,下面就來看學習其中的含義:
[HKEY_LOCAL_MACHINE/Drivers/Resources/IRQ]
?? "Identifier"=dword:1
?? "Minimum"=dword:1
?? "Space"=dword:20
?? "Ranges"="1-0x20"
;? "Shared"=""
?
[HKEY_LOCAL_MACHINE/Drivers/Resources/IO]
?? "Identifier"=dword:2
?? "Minimum"=dword:0
?? "Space"=dword:10000
?? "Ranges"="0-0xFFFF"
Identifier:資源標識符,在%_WINCEROOT%/Public/Common/DDK/Inc/Resmgr.h,如下
圖6
Minimum:Smallest numbered resource of this type,這種類型的最小有限資源。
Space:Number of resources in the resource space,資源空間里的資源數。
Ranges:initially available resources ranges,初始化的可用資源范圍。
Shared:initially available sharable resources,初始化的可用共享資源,共享資源如果可用,能在任何時候被請求。只有當資源低于或等于32時,才能設置共享資源。
⑵NandFlash驅動及分區部分注冊表信息
; HIVE BOOT SECTION
IF IMGHIVEREG
[HKEY_LOCAL_MACHINE/Init/BootVars]
??? "Flags"=dword:3
??? "RegistryFlags"=dword:1
ENDIF ;IMGHIVEREG
?
Flags:
Flags=3就是告訴系統在hive-base注冊表初始化的第一個階段來啟動存儲管理器和設備管理器的,具體的定義如下:
圖7
RegistryFlags:
RegistryFlags =1表示注冊表每次改動后自動flush到system.hv
?
?
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/NANDFLASH]
??? "Prefix"="DSK"
??? "Dll"="smflash.dll"
??? "Index"=dword:1
??? "Order"=dword:0
??? "Profile"="NANDFLASH"
??? "IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
IF IMGHIVEREG
??? "Flags"=dword:00001000
ENDIF ;IMGHIVEREG
?
"IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}":表示這是塊設備驅動
"Flags"=dword:00001000告訴設備管理器在hive-base注冊表初始化的第一個階段來加載驅動,也就是加載此nandflash驅動。
?
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/NANDFLASH/FATFS]
??? "Flags"=dword:14
???????? "Folder"="ResidentFlash" ;掛載在nandflash上面的目錄名稱。
??? "FormatExfat"=dword:1 ;表示格式化為ExFat。
??? "CheckForFormat"=dword:1
??? "EnableWriteBack"=dword:1
IF IMGHIVEREG???
??? "MountAsBootable"=dword:1
ENDIF ;IMGHIVEREG
?
CheckForFormat:
如果沒有設置這一項,或者這項對應的值為0,那么在filesysl.dll就不會用IOCTL_HAL_QUERY_FORMAT_PARTITION來通過OEMIoControl函數來調用OALIoCtlHalQueryFormatPartition函數,如果為1,則會調用OALIoCtlHalQueryFormatPartition函數來查詢在系統啟動的時候是否格式化對應的分區。
?
EnableWriteBack:
Enables a write-back(回寫) or write-through(連續寫入) cache.
0 - To use a write-through cache
1 - Enables write-back cache
?
MountAsBootable":
?Specifies that the file system may contain the system registry. The first mounted partition on the store gets the hive. Set to 1 to enable.在這里指定FATFS文件系統包含基于hive的注冊表,而FATFS文件系統對應的FATFS分區是在nandflash分區出來的,這樣保存在ResidentFlash目錄中的內容也就保存在nandflash中。
?
?
[HKEY_LOCAL_MACHINE/System/StorageManager/AutoLoad/NANDFLASH/Filters/CacheFilt]
??? "Dll"="cachefilt.dll"
??? "LockIOBuffers"=dword:1
?
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/NANDFLASH/FATFS/Filters/CacheFilt]
??? "Dll"="cachefilt.dll"
??? "LockIOBuffers"=dword:1
?
ENDIF ; BSP_NONANDFS
?
; END HIVE BOOT SECTION
?
?
參考鏈接:
?
WinCE中的RAM-Based Registry與HIVE-Based Registry
http://blog.csdn.net/nanjianhui/archive/2008/06/15/2550292.aspx
?
wince Hive注冊表實現機制
http://ponymaggie.blog.sohu.com/108452364.html
?
初識WINCE的HIVE注冊表
http://peyodsp.blog.51cto.com/888526/188665
?
WINCE恢復默認HIVE注冊表的方法
http://blog.csdn.net/fredzeng/archive/2006/08/23/1108227.aspx
?
總結
以上是生活随笔為你收集整理的WINCE基于hive注册表的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在WINCE5.0中应用CMD(比如运行
- 下一篇: WINCE基于CH7024实现TV OU