WinCE中OEM适配层点滴之系统初始化

wince6—创建初始化函数 在给控件添加类以后我没有在文件中找到有初始化的函数,由于是初学,很多东西不太懂,整了好久才弄明白怎么添加初始化函数OnInitDialog() 立即下载

 

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)。 
SpringBoot 指标监控——Actuator 1、 访问:localhost:8000/actuator 设置健康监控显示具体情况 metrics http://localhost:8000/actuator/metrics/jvm.gc.live.data.size 定制化health信息 //利用构造器,在注册中心中添加cityService.saveCity.count指标 public CityServiceImpl(MeterRegistry meter... 阅读详情

相关推荐

操作系统原理:【优麒麟】linux内核添加系统调用

在底端添加如下代码。

Joyce_zz的博客 2709

WINCE6.0体系结构学习

********************************LoongEmbedded******************************** 作者:LoongEmbedded(kandi) 时间:2012.02.14 类别:WINCE系统开发 ********************************LoongEmbedded**************...

weixin_30251587的博客 249

LDPC码译码原理——概率公式推导

怎么说呢,一直以来都想写一下博客。近半年多来我一直在学习LDPC码译码上的东西,主要是在FPGA实现上的,所以这次想写一些关于这方面的内容,包括译码的原理、仿真以及实现。(当然是基于准循环LDPC码上实现的)不过呢,我写这个的初衷是为了让初学者理解入门用的,而不是在大牛面前班门弄斧,有错误之处欢迎大家批评指正。不知道会不会有人一开始像我一样,为了学好LDPC码,先去好好了解其它的诸如RS码或者是卷...

stand_by_me123的博客 2万+

WinCE学习笔记之三

WinCE被设计成一种分层结构,从底层至上分别为:硬件层、OEM层、操作系统层和应用层。OEM层又分为:OAL(OEM适配器)、Boot Loader(启动加载程序)、配置文件及驱动程序。1.OAL   OAL是WinCE内核与目标硬件之间的一个代码层,主要用来处理WinCE内核与目标硬件设备之间的通信,其功能主要包括CPU初始化、处理中断、计时器等。2.Boot Loader    

vallonce_cxx的专栏 373

聚类模型-层次聚类

聚类模型 1、层次聚类 2、原型聚类-K-means 3、模型聚类-GMM 4、EM算法-LDA主题模型 5、密度聚类-DBSCAN 6、图聚类-谱聚类 一、层次聚类 一、聚类理论 ​ 一般来说,聚类是在训练样本的标签信息不知的情况下,学习样本内在的性质和规律,将有限的集合划分成ccc类。根据“方以类聚,物以群分”的思想,类内对象尽可能的相似,...

myazi 6503

Scissor算法实战:利用bulkRNA表型数据精准定位单细胞亚群

本文详细介绍了Scissor算法的实战应用,该算法通过整合bulkRNA-seq的丰富表型信息与单细胞数据,精准识别与特定临床结局(如不良预后)相关的单细胞亚群。文章深入解析了算法三步走的核心思想,并提供了适配Seurat v5的完整代码解决方案,帮助研究者从海量数据中提炼具有生物学和临床价值的洞见。

ww90123的博客 254

认识OAL

1、OAL是什么?    MSDN的解释:  An OEM adaptation layer (OAL) is a layer of code between the Windows CE kernel and the hardware of your target device   我的理解:OAL是目标设备和系统内核间的代码层,从制作实现OAL的OEM函数就可以知道,内核(NK

2005

保姆级教程:在摩尔线程MTT S80上快速部署Ollama运行DeepSeek R1模型(附性能测试)

本文提供了一份详细的保姆级教程,指导用户在摩尔线程MTT S80显卡上部署Ollama并运行DeepSeek R1模型。内容涵盖从驱动安装、Docker环境配置到模型拉取、性能测试的全流程,并分享了实测数据与优化技巧,旨在帮助开发者快速在国产GPU平台上实现高效的大语言模型推理。

weixin_29091837的博客 521

系统掉电丢失设置的问题的分析

系统掉电丢失设置的问题的分析

androidfan的专栏 1317

【气候极端指数】MATLAB计算各种气候极端指数

简介各类气候极端指数,及其MATLAB计算代码

WW、forever的博客 4917

数据分析案例-车辆二氧化碳排放量数据可视化分析

本实验数据集来源于Kaggle,该数据集捕获了车辆二氧化碳排放量随不同特征变化的详细信息。数据集取自加拿大政府官方开放数据网站。其中包含 7 年期间的数据。总共有 7385 行和 12 列。各列变量含义解释如下:Make:车辆的品牌或制造商。Model:车辆的具体车型名称。Vehicle Class:车辆的分类,如紧凑型、SUV等。Engine Size(L):车辆发动机的尺寸,以升为单位。Cylinders:车辆发动机的气缸数。

m0_64336780的博客 1万+

原生JS实现向下滚动导航栏自动固定在顶部,向上滚动到顶部又恢复效果

前言 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: 全新的界面设计 ,将会带来全新的...

q18742509891的博客 3821

Sigrity Power Tree如何生成电源树操作指导

Sigrity Power Tree可以方便地生成电源树,仅需要网表文件就能将系统的电源树直观的显示出来,生成的电源树文件可以用Power DC,optimizePI进行直流和交流仿真,下面介绍如何生成电源树。Base on [Device_TYPE and VALUE]就是识别网表中器件的Device_TYPE作为power tree中的模型的名字。Allegro layout netlist file,就是从Allegro layout文件中输出的netlist第三方网表文件。如何生成电源树操作指导。

weixin_54787054的博客 1532

js滚动到指定位置导航栏固定顶部

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>js滚动到指定位置导航栏固定顶部</title> <style type="text/css"> body{height: 25...

afwzkklp73654的博客 274

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

js-滚动到指定位置导航栏固定顶部

最近整理一下之前做的一个项目,把滚动条动态固定顶部的代码整理出来和大家分享,上代码 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta...

lumot的博客 1366

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

react项目中实现滚动页面后 导航栏固定在页面顶部

1.有个css需求:每一个卡片需要占一行,但是他的宽度又需要随着卡片里面的内容变化,你会怎么解; 答:我设置了一个display: inline-block,将div从k

今天你被AI优化了么 2994

页面滚动到指定位置导航栏固定顶部

页面滚动到指定位置导航栏固定顶部

sunshine5050的博客 1万+

html怎么置顶导航栏,css怎么实现滚动页面导航栏固定在顶部

css怎么实现滚动页面导航栏固定在顶部(吸顶效果)功能:当网页向下滚动时,导航栏一直在固定在顶部一、css设置这里主要用到css中position中的relative与fixed;其中relative是生成相对定位的元素,相对于其正常位置进行定位。fixed是生成绝对定位的元素,相对于浏览器窗口进行定位。思路就是当导航栏滚动到 top: 0 时,把相对定位改成绝对定位,这样就相对于浏览器窗口进行定...

weixin_39562615的博客 4711

鼠标往下滚动,导航栏固定在最顶部

window.onscroll = function(){ var topScroll = getScrollTop();//滚动的距离,距离顶部的距离 var bignav = document.getElementById('bignav'); if (topScroll > 150){ //滚动的高度 bignav.style....

weixin_42330061的博客 1149

导航栏滚动到顶部固定

<div id="testNavBar"> <div :class="{ fixedNavbar: isfixTab }">这是导航</div> </div> mounted() { window.addEventListener('scroll', this.handleTabFix, true) }, methods: { // 先分别获得id为testNavBar的元素距离顶部的距离和页面滚动的距离 //

halouKti的博客 614

uni-app 导航栏滚动后固定到顶部

完整代码 <template> <view class="content"> <view class="wrap"> <view class="list" v-for="i in list_data"> <text>{{ i }}</text> </view> </view> ...

qq_59795720的博客 3322

导航栏滚动到顶部后固定

导航栏滚动到顶部后固定 http://blog.youkuaiyun.com/moqiang02/article/details/17995033 &lt;div style="height:500px;background:#999"&gt;&lt;/div&gt; &lt;div id="fixedMenu" style="background:#eee;width:100%;"&gt;MENU&

weixin_33712881的博客 271

UniApp 实现顶部固定导航栏 Tab 及滚动变色效果

摘要:本文介绍了在UniApp+Vue3+TypeScript项目中实现固定顶部Tab导航栏的方法。该导航栏具有以下特点:固定在顶部不随滚动消失,滚动时背景色渐变,支持Tab切换并高亮当前选项,适配不同设备状态栏高度。通过sticky定位实现固定效果,利用onPageScroll监听滚动事件动态改变样式,使用uni.getSystemInfoSync()获取状态栏高度实现适配。文章详细讲解了模板结构、脚本逻辑和样式设计的关键实现点,包括动态样式绑定、Tab切换功能以及平滑的过渡动画效果。

大胆尝试,小心实践 1079
上一篇: 如何控制CE系统的重启或者关机
下一篇: 监控进程创建代码
JamesXing
博客等级 码龄20年 30粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值