首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
ASP | ASP.NET | JSP | PHP | AJAX | XML | Java script | HTML/CSS | 服务器类
各大城市软件开发培训、软件人才免费咨询热线:400-700-5807
 您现在的位置: 中国IT实验室 >> WEB开发 >> WEB开发 >> 正文
WinCE中OEM适配层点滴之系统初始化
ChinaItLab  2005-1-15  保存本文    收藏本站


  OAL(OEM Adaptation Layer)既OEM 适配层,从逻辑上讲位于Windows CE内核和硬件之间,从物理上讲OAL各个模块代码被编译后(.lib)和其它内核库链接到一起形成Windows CE的内核可执行文件nk.exe。Windows CE内核在OAL层暴露了大量的函数和全局变量,利用这些函数和全局变量OEM可以编写中断处理、RTC、电源管理、调试端口、通用I/O控制代码等。图1更直观地描述了OAL的结构。CE安装目录的子目录中包含了OAL的部分源码,大多数情况下开发者对OAL只要修改即可,甚至无需修改。通过阅读本篇文章,开发者能够了解OAL的结构、暴露的接口的功能,可以在此基础上实现甚至增强OAL的功能。
  

  
图1 OAL结构图

  
  因为OAL层代码大多数和CE启动时系统初始化工作有关,所以本篇文章以CE的启动顺序为线索。其它OAL知识在下一篇文章中讲解。
  
  一、在Boot Loader解压CE内核镜像文件(nk.bin)后开始跳转到StartUp(),StartUp函数属于OAL层,此时CE操作系统内核还没有运行。StartUp函数的功能主要有两个,一是初始化CPU为已知状态(known state),二是调用内核初始化函数(x86平台为KernelInitialize,其它平台为KernelStart)。初始化CPU工作因CPU的不同而不同,如果是arm系列,包括设置CPU为管理员模式、禁止IRQ和FIQ、禁止MMU、清空指令和数据缓冲、检测启动原因、配置GPIO和内存控制器、初始化RTC、保存OEMAddressTable地址等。执行完毕后调用KernetStart。如果是x86系列,包括设置CPU为保护模式、初始化内存控制器、保存OEMAddressTable地址等。执行完毕后调用KernetInitialize。
  
  二、内核初始化函数的功能也因CPU的不同而不同,不过有一些功能是相同的,如初始化串口(为了输出调试信息)、调用OEMInit函数等。对于x86系列,初始化工作除了上述的功能外还包括读取OEMAddressTable内容、确定分页大小、内核重定位、初始化中断分配表、初始化分页表、内存初始化和其它初始化。对于其它系列CPU请参考CE帮助文档。
  
  1. 串口调试:
  
  串口调试函数包括OEMInitDebugSerial、OEMReadDebugByte、OEMWriteDebugByte等。从OEMInitDebugSerial的源码可以看出,系统从BOOT_ARG_PTR_LOCATION为首地址的结构中判断当前连接的串口是哪个,然后配置这个串口。如果你的设备的串口I/O地址设置和CE默认的一致的话,就能在CE内核得到CPU控制权到启动完毕这段时间里通过串口得到调试信息。
  
  2. OEMInit
  
  一般在OEMInit中初始化所有外围的硬件、初始化系统时钟(system tick)和RTC(real time clock)、初始化KITL(Kernel Independent Transport Layer)。例如I486平台的OEMinit函数,它先关联所有的IRQ和中断ID,然后初始化PCI总线、网络适配器、电源管理、PIC(可编程中断控制器)、系统时钟,最后检测是否有扩展内存。另外如果OEM要通过OAL暴露的函数指针或者全局变量来增强功能的话,就要在此函数中实现(在下面详细讲解)。
  
  3. 检测扩展内存
  
  我们都知道在config.bib配置文件中设置CE系统使用RAM总量(如果不知道请参考我的文章Platform Builder之旅系列),注意这个RAM总量不是总的物理内存的大小。PB编译的内核包含一个变量ulRAMEnd,将在config.bib中定义的RAM的起始地址 + RAM大小的和赋值给ulRAMEnd。在CE内核的启动过程中,ulRAMEnd的值赋值给全局变量MainMemoryEndAddress,CE内核通过访问MainMemoryEndAddress得到RAM的总量信息。假如基于CE的设备附加了RAM,而MainMemoryEndAddress的值没有包括这段附加的RAM,结果CE内核无法知道已经附加了RAM。为了让CE内核了解附加RAM的信息,OEM应该编写一个函数检测RAM的总量,并把总量值赋给MainMemoryEndAddress。OAL暴露了一个函数指针pNKEnumExtensionDRAM,OEM应该把编写好的函数地址赋给这个函数指针。如果OEM不准备自己编写内存检测函数的话也可以调用OEMGetExtensionDRAM。从帮助文档中看出OEMGetExtensionDRAM这个函数能够检测内存的总量,但是CE的针对X86 平台的源码中没有具体编写这个函数的实现代码(见%_WINCEROOT%\PUBLIC\COMMON\OAK\CSP\I486\OAL\cfwpc.c)。也就是说在X86平台上调用OEMGetExtensionDRAM是检测不到RAM的。如果OEM有兴趣编写检测RAM总量的函数,可以调用现成的函数IsDRAM。这个函数也保存在cfwpc.c中。
  
  三、内核初始化函数执行完毕后开始按如下步骤执行:
  
  1. 内核创建用于与filesys.exe同步的事件对象SYSTEM/FSReady,之后启动filesys.exe。启动filesys.exe的意义是让filesys.exe读取注册表数据。
  
  2. 内核等待事件SYSTEM/FSReady被触发,这个事件是由filesys.exe在做完一系列工作后触发。这一系列的工作内容如下:
  
  2.1 先检测这是一次冷启动还是热启动,如果是冷启动,那么初始化对象存储内存区域。
  
  2.2 调用OEMIoControl函数,I/O控制代码为IOCTL_HAL_INIT_RTC,也就是初始化RTC。
  
  2.3 初始化数据库子系统和API、文件系统API、消息队列API。
  
  2.4 如果操作系统镜像(nk.bin)包括RAM文件系统,那么读取Initobj.dat文件内容后创建一个RAM文件系统。
  
  2.5 初始化注册表(在内存中形成注册表)。
  
  2.6 如果此时device.exe没有启动,那么读取HKEY_LOCAL_MACHINE\System\StorageManager下“Dll”的值(这个值为存储管理器所在的.dll的文件名)并加载到内存。加载之后创建一个线程专用于初始化存储管理器,初始化之后此线程结束。
  
  2.7 初始化NLS(national language support)。关于NLS请参见我的文章《CE下中文输入法编辑器》。
  
  2.8 为数据库引擎设置本地ID。
  
  2.9 读取Initdb.ini文件,安装在对象存储中的数据库。
  
  2.10 触发SYSTEM/FSReady事件,之后filesys.exe处于等待状态,等待内核发通知给它。
  
  3. 此时注册表已经存在于内存当中,内核开始读取如下位置数据:
  
  HKEY_LOCAL_MACHINE\Loader\SystemPath
  
  HKEY_LOCAL_MACHINE\SYSTEM\OOM\cbLow and cpLow
  
  HKEY_LOCAL_MACHINE\SYSTEM\KERNEL\InjectDLL
  
  HKEY_LOCAL_MACHINE\MUI\Enable and SysLang
  
  HKEY_CURRENT_USER\MUI\CurLang
  
  4. 内核设置低内存处理(out of memory)。低内存处理是指当前可用的内存非常少时,内核所做的解决方案(CE帮助文档中有详细说明)。
  
  5. 内核在做好了上述工作后通知filesys.exe,由filesys.exe做其余工作。filesys.exe所做的工作内容如下:
  
  5.1 读取HKEY_LOCAL_MACHINE\System\Events 下包含的所有事件对象名称并一一创建。
  
  5.2 读取HKEY_LOCAL_MACHINE\Init 下包括的所有应用程序名称并一一启动。如果device.exe在列表中并且此时它已经启动了,那么触发SYSTEM/BOOTPHASE2事件,这会使device.exe重新读取注册表数据来完成最后的驱动程序初始化。
  
  5.3 初始化时间区域(time zone)。
中国IT教育热线咨询
相关文章
Flash+PHP+Mysql简单留言本制作实例教程
基础知识:Java Web三层架构的配置详解
使用AJAX技术构建更优秀的Web应用程序
ASP应用程序设计的Web状态管理分析
Ajax驱动的Web站点
最新文章
·Ajax光环背后的隐患
·Windows操作系统下JSP程序开发环
·如何在Java程序中实现FTP的上传下
·Java应用:编写高级JavaScript应
·初学者学习java第一步——JDK环境
 文章评论

 精彩友情推荐
·Asp源码 PHP源码
·CGI源码 JSP源码
·建站书籍教程
·服务器软件 .net源码
·建站工具软件
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
ASP.NET ASP PHP JSP
·ASP.NET开发中的八个最佳实践09-21
·ASP.NET开发中的验证码技术09-18
·控件开发asp.net处理标签间内容09-18
·程序员成为成为编程高手的二十二条军规09-18
·VS 2005和ASP.NET 2.0中处理CSS样式表09-17
·如何有效监控.NET应用程序09-16
·浅析ASP.NET 2.0 Client Callback09-16
·探讨ASP.NETMVC框架内置AJAX支持编程技术09-15
·ASP.NET2.0的URL映射的实现方法09-13
·Java\.net\PHP比较 程序员眼中的.Net世界09-12
·asp.net中实现观察者设计模式09-12
·谈JSP与XML的交互09-01
·ASP连接11种数据库语法总结09-01
·如何利用ASP实现邮箱访问09-01
·ASP随机数的应用技术09-01
·定时使用DWRUtil.addRow生成表格08-27
·ASP申请单动态添加实现方法及代码08-27
·关于ASP中脚本执行顺序的讲解08-25
·ASP程序实现网页伪静态页源代码08-25
·ASP如何调用webservice08-22
·ASP实例:读取xml文件的程序08-14
·Asp组件检测函数08-11
·Linux系统下让PHP提高性能的工具APC05-06
·一个完整、安全的PHP用户登录系统11-14
·Apache+PHP+MySQL建立数据库驱动的动态网站08-24
·用SSH与PHP相连接 确保数据传输的安全性08-23
·PHP5手动最简安装方法08-03
·PHP程序加速探索之服务器负载测试07-11
·完全讲解PHP+MySQL的分页显示示例分析05-30
·用Suhosin加强PHP脚本语言安全性05-26
·初学入门 PHP 和 MySQL05-17
·传奇的诞生 PHP三位创始人简介05-10
·大型系统上PHP令人不爽的九大原因05-10
·JSTL中fn表达式的使用说明09-18
·JSP Web框架研究:Struts09-16
·JSF在GlassFish管理控制台中的应用09-12
·介绍JSP程序动态网站环境搭建的详细步骤09-12
·Jsp页面中文参数传递get和post方法分析09-12
·Java\.net\PHP比较 程序员眼中的.Net世界09-11
·JavaScript最常用的55个经典技巧09-08
·Windows操作系统下JSP程序开发环境配置09-03
·JSF点滴积累--权限验证09-03
·小小分页帮助程序08-29
·经验分享全过程JSP程序员完全蜕变手册08-27
  培训中心
人才交流中心 技术交流中心
  ITLab技术交流平台: