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