0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

WinCE启动失败的原因及解决方案

电子设计 来源:郭婷 作者:电子设计 2019-01-02 10:33 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

WindowsCE是微软公司嵌入式、移动计算平台的基础,它是一个开放的、可升级的32位嵌入式操作系统,是基于掌上型电脑类的电子设备操作系统,它是精简的Windows 95,Windows CE的图形用户界面相当出色。

Windows CE作业系统是Windows家族中最新的成员,专门设计给掌上型电脑(HPCs)所使用的电脑环境。这样的作业系统可使完整的可携式技术与现有的Windows桌面技术整合工作。Windows CE 被设计成针对小型设备(它是典型的拥有有限内存的无磁盘系统)的通用操作系统,Windows CE 可以通过设计一层位于内核和硬件之间代码来用设定硬件平台,这即是众所周知的硬件抽象层(HAL)。不象其它的微软 Windows 操作系统,Windows CE 并不是代表一个标准的相同的对所有平台适用的软件。为了足够灵活以达到适应广泛产品需求, Windows CE 采用标准模式,这就意味着,它能够由一系列软件模式做出选择,从而使产品定制。另外,一些可利用模式也可作为其组成部分,这意味着这些模式能够通过从一套可利用的组份做出选择,从而成为标准模式,通过选择,能够达到系统要求的最小模式, OEM 能够减少存储脚本和操作系统的运行。

Windows CE中的C代表袖珍(Compact)、消费(Consumer)、通信能力(Connectivity)和伴侣(Companion);E代表电子产品(Electronics)。与Windows 95/98、Windows NT不同的是,Windows CE是所有源代码全部由微软自行开发的嵌入式新型操作系统,其操作界面虽于Windows 95/98,但Windows CE是基于WIN32 API重新开发、新型的信息设备的平台。Windows CE具有模块化、结构化和基于Win32应用程序接口和与处理器无关等特点。Windows CE不仅继承了传统的Windows图形界面,并且在Windows CE平台上可以使用Windows 95/98上的编程工具(如Visual Basic、Visual C++等)、使用同样的函数、使用同样的界面风格,使绝大多数的应用软件只需简单的修改和移植就可以在Windows CE平台上继续使用。Windows CE并非是专为单一装置设计的,所以微软为旗下采用Windows CE作业系统的产品大致分为三条产品线,Pocket PC(掌上电脑)、Handheld PC(手持设备)及Auto PC.

我们的嵌入式系统用的是arm处理器+WinCE平台,目的是要把WinCE平台从旧版本移植到WinCE6.0平台上。但结果是这个WinCE系统在启动的时候经常会出现失败,而且每次失败的原因都莫明其妙和不尽相同。

为什么会出现这种情况呢?经过分析和研究,原来主因是系统的引导过程、内核加载过程、OAL启动过程和硬件驱动加载过程时都存在可能导致的失败的隐忧。本文通过对以上因素进行分析,并提出相应的解决办法。但由于WinCE启动失败会非常取决于硬件平台,因此在具体应用时需要综合考虑和分析。

一 什么是WinCE启动过程?

WinCE系统在启动时一般需要三个基本元素:引导初始化、内核加载和OAL初始化等。它们的作用是要完成引导过程的初始化和操作系统执行环境的初始化。其中引导初始化是由引导工具BootLoader完成,主要是完成板级、片级的初始化。例如,通过设置寄存器来完成硬件的初始化,如设置时钟、设置中断控制寄存器、完成内存映射和初始化MMU的工作方式等。内核加载是指将操作系统内核映像从只读存储器加载或者拷贝到系统的RAM中并执行。OAL是位于操作系统的内核与硬件之间的适配层,也是连接系统内核与硬件的枢纽,它具有屏蔽硬件设备细节以及抽象硬件功能的作用。而OAL初始化则是指通过一组函数来体现出0AL屏蔽和抽象硬件设备的作用。

此外,如果要WinCE系统成为完整的操作系统,还得加上硬件驱动程序、硬件接口程序和应用程序组。因此,即使在一个简单的嵌入式系统里,WinCE系统启动时是需要加载内核和加载许多组件或驱动程序。

WinCE系统在启动时调用函数的顺序:①CPU执行引导向量,跳转到硬件初始化代码,即Startup函数。②在start up函数完成最小硬件环境初始化后跳转到KernelStart函数,来对内核进行初始化。③Kernelstart函数调用OEMInitDebugSerial完成对调试串口的初始化;同时调用0EMInit函数来完成硬件初始化工作以及设置时钟、中断;最后,调用OEMGetExtensionDRAM函数来判断是否还有另外一块DRAM.至此,内核加载完毕。由此可见,WinCE系统启动的重中之重是Startup函数的正确加载,如果这个Startup函数调用失败,则会使到系统在启动频繁出错。WinCE启动时调用函数顺序如下图所示:

WinCE启动失败的原因及解决方案

WinCE启动失败可能会存在于引导初始化失败、内核加载失败、0AL函数初始化失败、驱动程序加载失败、组件加载失败和应用程序加载失败。也就是说,WinCE启动失败一方面可能是在Startup函数的处理上,例如引导初始化和OAL初始化。另一方面还存在于驱动程序和组件自启动的失败上,例如基本的驱动程序、注册表配置或自运行的程序等。就不能被使用。所以,当注册表在启动时加载错误或者注册表配置有错误时,也是会导致WinCE系统启动失败的。

二 导致WinCE启动失败的主因分析

Windows CE在启动时为什么会失败呢?这个问题也一直让我头痛。因为Windows CE启动失败既有软件因素,也有硬件因素。例如,可能是WinCE的启动引导过程有问题、也许是内核加载时有问题、也许是OAL函数调用的隐性问题或者硬件设备本身的问题造成的。所以,解决起来比较麻烦和比较耗时间,也是最让我们头疼的事情。

一般来说,解决和分析WinCE启动失败有一个原则,就是"先软后硬"的原则,也就是说要先分析软件因素再到硬件因素。本文主要是在arm微处理器和Windows CE 6.0平台上进行分析软件因素造成的失败。

(1)引导程序BootLoader导致的失败

在Windows CE系统中,整个系统的加载启动任务由BootLoader来完成,BootLoader是在WinCE内核运行之前运行的一段小程序。通过这段小程序,可以初始化硬件设备、建立内存空间的映射图和初始化MMU等。从而将系统的软硬件环境带到一个合适的状态,为调用操作系统内核准备好环境。因此,只有在引导程序正确的完成自己的任务后,才会将控制权移交给内核。

在WinCE平台上,引导装载程序是在硬件上执行的第一段代码,通常将引导程序放置在不易丢失的存储器的开始地址或者是系统冷启动时PC寄存器的初始值。如果这段小程序代码编写错误,则系统无法完成第一步的引导操作,这是导致启动系统失败的第一个因素。

①BootLoader初始化硬件失败

BootLoader第一个功能是要实现板级和片级初始化硬件,主要是把CPU初始化到一已知状态。在BootLoader目录下,会发现一些。s文件,可能会是init.s或者是reset.s等,这样的文件是CPU加电后最先执行的代码。StartUp 函数是BootLoader的入口函数。该函数一般是使用汇编语言编写,与CPU关系非常紧密,能完成初始化CPU、内存等核心硬件。然后,BootLoader在平台初始化完毕后就可以在不用人工干预的情况下自动加载WinCE内核了。但如果BootLoader在初始化硬件时失败,就会直接导致系统的启动失败了。

②BootLoader加载内核时失败

一般在平台调试完毕后,BootLoader就会加载WinCE内核映像,这也是BootLoader的功能之一。WinCE内核映像文件通常叫做nk.bin,它是Windows CE二进制数据格式文件,不仅包含了有效的程序代码,还有按照一定规则加入的控制信息。

在系统启动时BootLoader可以通过两种不同的方式来加载WinCE内核文件nk.bin.一种是下载模式,另一种是本地启动模式。本地启动模式也称为自主模式,即 BootLoader 从目标机上的某个固态存储设备上将操作系统加载到 RAM 中运行,整个过程并没有用户的介入。而下载模式则是目标机上的 BootLoader 将通过串口连接或网络连接等通信手段从主机(Host)下载文件。当BootLoader正确的把nk.bin解压到RAM后,就会把CPU控制权交给CE内核。因此,如果Boot Loader处理不当,就可能会造成加载和解压nk.bin文件的失败,这样自然也就会造成系统启动的失败了。

(2)OAL导致的启动失败

OAL(OEM Adaptation Layer)是指OEM 适配层,它是位于Windows CE内核和硬件之间的一层适配层,是OAL各个模块代码被编译后(。lib)和其它内核库链接到一起形成Windows CE的内核可执行文档NK.EXE.OAL包括了和系统硬件通讯的最底层代码,内核是通过OAL跟硬件进行交互。逻辑上,OAL是介于CE内核和设备硬件之间的一个代码层,是一个抽象的概念。物理上,OAL和其它一些库一起链接成可执行文件。

与以前的Win CE旧版本不同的是,在Win CE 6.0中内核(Kenerl)和OEM代码被分成oal.exe、kernel.dll和kitl.dll三个部分,其中启动代码(startup)和 OAL层的实现部分不再与内核链接生成NK.exe,取而代之的是启动代码(startup)和硬件相关且独立于内核的OAL层的实现部分编译成 oal.exe;而与内核相关且独立于硬件的OAL层代码包含在kernel.dll中,内核无关传输层(KITL)的支持代码从OAL层分离出来编译成 kitl.dll.因此,WinCE6.0的启动只与oal.exe和kernel.dll有关。至于kitl.dll,只有将操作系统编译成具有 KITL功能时才用到。这样做的好处是可以单独升级OAL,但整体的OAL结构并没有改变。

①OAL初始化硬件时失败

oal.exe是通过Startup函数来完成硬件的初始化。一般来说,OAL的启动代码(Startup.s)与该硬件平台的Bootloader的启动代码(Startup.s)是可以共享的。例如,其中PreInit 函数主要完成将arm处理器工作模式切换到管理员模式,同时关闭MMU,并检测系统启动原因。如果是热启动,即在该函数调用之前已经启动过 Bootloader的启动代码(Startup.s),相当基本硬件初始化已经完成,则可直接跳转到OALStartUp函数中;否则需要进行硬件中断屏蔽、内存、系统时钟频率、电源管理等硬件的基本初始化过程。

在StartUp 函数初始化CPU等核心硬件并跳转到Main函数后,系统就会转入C语言代码执行环境。这时Main函数分为3个模块:BLCOMMON、Download Function、FLASH Function.其中BLCOMMON模块是由微软提供的,执行一些逻辑上的功能。而Download Function、FLASH Function中的函数与硬件平台息息相关。因此,对于每种硬件平台都要将函数的实现进行适当修改,这种修改是需要对硬件非常熟悉的。当修改出现错误时,就会导致系统启动失败了。

在硬件平台初始化完成后,oal.exe的启动任务基本完成,余下的启动工作由内核相关且独立于内核的OAL层实现体kernel.dll接管。也就是说,这时Startup会调用OALStartUp函数,OALStartUp函数主要完成将OEMAddressTable表传递给内核,然后调用KernelStart函数跳转到内核。因此,如果此时OAL的启动Startup函数调用失败的话,就也会导致系统的启动失败了。

这里需要特别注意的是,Bootloader和OAL中均包含启动Startup函数。它的功能大致相同,都是要初始化最小硬件环境。Bootloader的启动Startup函数是在为自己的执行准备硬件环境,OAL的启动Startup函数则是为kernel的执行准备硬件环境。由于这两种硬件环境要求基本相同,所以它们的代码也有很大部分可以相互借鉴。但应该明白Bootloader与OAL在物理上是独立的,它们并不是同一段代码。当然,如果可以确定这一部分在Bootloader已经初始化过如热启动,则在OAL中不必重复执行。

②OAL入口位置定位失误导致的失败

从上述WinCE启动流程可知,在OAL初始化硬件后而在内核启动前,系统是需要调用KernelStart函数来跳转到内核。因此,这里有一个要点,就是WinCE需要找到OAL的入口位置,然后才能调用入口函数与全局块进行指针交换,这样内核才能使用OAL层中的信息,同样OAL层也才能访问内核(kernel)导出的函数。

OAL入口位置函数的调用实际上是通过OEMGLOBAL结构体实现的,实际调用位置为OEMInitDebugSerial和OEMInit.也就是说,OEMGLOBAL结构体构建了内核和OAL层之间进行通信的桥梁。OEMGLOBAL结构体定义了OAL层所有必须的函数,该结构体在oemglobal.c文件中被初始化,并会被编译在OEMMain.lib和 OEMMain_StaticKITL.lib两个库中。如果OAL链接这两个库,则必须要有正确的该结构体的函数实现体,同时还需要调用ARMSetup来设置物理地址和非缓冲的虚拟内存地址的映像、arm中断向量以及内核模式所需要的堆栈、调用OEMInitDebugSerial函数初始化调试串口、调用OEMInit进行平台初始化等。否则,如果OAL入口位置函数有误,则内核和OAL层之间的访问就会失败,也就会导致系统在启动时出错和失败。

三 导致的WinCE启动失败的其它相关因素

(1)驱动程序加载错误导致的失败

在调试中,我们还发现系统在启动时执行到OEMInit时也经常会出现错误。一般来说,系统调用OEMInit运行完成之后,就会跳回Private或Public下的代码继续运行,然后再启动device.exe加载各个驱动程序。由于这一段代码是微软提供的default代码,基本上不会有问题。所以,我们就有理由怀疑如果加载的驱动程序出了问题,是也会造成系统启动失败的。一般来说,这些加载的驱动程序主要是 BSP中的Audio、Display、SDMMC、Serial、USB等。

(2)启动时加载配置有误的注册表导致的失败

与桌面Windows一样,WinCE注册表(Registry)也是一个系统数据库,用来保存应用程序、驱动程序、用户的设定以及其它一些系统的配置信息,通常还存储着操作系统运作和调用程序的状态信息。例如,每个用户的配置文件、安装的应用程序以及每个应用程序可以创建的文档类型、文件夹和应用程序图标的属性表设置、系统上存在哪些硬件以及正在使用哪些端口等。

对于硬件外设来说注册表是一个记录驱动程序设置和位置的数据库。当WinCE系统在启动时需要启动某些必要的硬件设备时,就会需要使用外设驱动程序。但如果在WinCE中这个外设驱动是独立于操作系统的,WinCE系统就需要知道从哪里找到它们,例如文件名、版本号、其它设置和信息。因此,注册表上没有此设备的记录时,它们就不能被使用。所以,当注册表在启动时加载错误或者注册表配置有错误时,也是会导致WinCE系统启动失败的。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 微软
    +关注

    关注

    4

    文章

    6719

    浏览量

    107353
  • 嵌入式
    +关注

    关注

    5186

    文章

    20149

    浏览量

    328851
  • WINDOWS
    +关注

    关注

    4

    文章

    3697

    浏览量

    93231
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CANoe与Simulink联合仿真编译失败

    问题描述:在使用VS作为编译器的情况下,Matlab编译后失败,如下图:解决方案原因:安装VS时,Windows的SDK版本未安装或者安装选项没有选择正确。1.打开VS,可以看到VS中的错误提示:2.打开此项目的属性设置:3.
    的头像 发表于 11-14 12:13 1636次阅读
    CANoe与Simulink联合仿真编译<b class='flag-5'>失败</b>

    电流探头消磁失败原因与解决策略

    探头的消磁失败现象时有发生,这不仅会降低测量结果的准确性,还可能影响测试进度。本文深入剖析了消磁失败的常见原因,并提出了针对性的解决策略。 一、 消磁失败的常见
    的头像 发表于 09-18 13:46 440次阅读
    电流探头消磁<b class='flag-5'>失败</b>的<b class='flag-5'>原因</b>与解决策略

    rt-thread-studio资源包安装失败原因

    如图,添加任何的软件包都失败,更改github或者gitee源都不起作用,有什么解决方案吗?
    发表于 09-17 07:18

    汉思新材料:环氧底部填充胶固化后有气泡产生原因分析及解决方案

    的详细分析以及相应的解决方案:汉思新材料:环氧底部填充胶固化后有气泡产生原因分析及解决方案一、气泡产生原因分析1.材料本身原因:预混胶中残留
    的头像 发表于 07-25 13:59 570次阅读
    汉思新材料:环氧底部填充胶固化后有气泡产生<b class='flag-5'>原因</b>分析及<b class='flag-5'>解决方案</b>

    宽温启动失败?聚徽揭秘防爆显示屏-40℃低温启动的加热膜配置技术

    防爆显示屏的低温启动难题,解析加热膜配置的核心技术,为工业场景提供可靠解决方案。 一、低温启动失败的核心挑战 1. 液晶材料性能衰减 在-40℃环境下,液晶材料粘度增加,响应时间延长,
    的头像 发表于 06-18 16:17 565次阅读

    rt-thread-studio添加任何的软件包都失败,更改github或者gitee源都不起作用,有什么解决方案吗?

    如图,添加任何的软件包都失败,更改github或者gitee源都不起作用,有什么解决方案吗?
    发表于 06-13 08:17

    晶振不起振的常见原因解决方案

    在电子电路设计和调试中,晶振为电路提供稳定的时钟信号。我们可能会遇到晶振有电压,但不起振,从而导致整个电路无法正常工作的情况。今天凯擎小妹聊一下可能的原因解决方案
    的头像 发表于 04-21 10:53 2684次阅读

    NXP IMX8M Mini启动失败原因有哪些?

    NXP IMX8M Mini启动失败原因有哪些?
    发表于 04-11 07:21

    QSPI启动模式EMMC跳转失败原因

    我正在使用 S32g274ardb2 板并使用 bsp42进行测试; 我成功尝试了以下启动过程: 1. SD 卡直接启动成功。 2. 直接成功启动 EMMC。(使用闪存工具刻录与 SD 卡相同的程序
    发表于 04-02 08:07

    芯片流片失败都有哪些原因

    最近和某行业大佬聊天的时候聊到芯片流片失败这件事,我觉得这是一个蛮有意思的话题,遂在网上搜集了一些芯片流片失败原因,放在这里和大家一起分享。1.Design的版本拿错,这个问题比较要命,如果ROM
    的头像 发表于 03-28 10:03 1455次阅读
    芯片流片<b class='flag-5'>失败</b>都有哪些<b class='flag-5'>原因</b>

    RT1052芯片启动失败原因?怎么解决?

    最近遇到RT1052芯片启动失败问题,10次里有5次启动失败,但接上示波器观察RT1052电源时序波形后,启动
    发表于 03-27 07:00

    芯知识|WT588F02B语音芯片烧录失败原因解析及解决方案

    、线路长度三大核心因素出发,深入分析烧录失败原因并提供系统化的解决方案。一、检查下载器与芯片的物理连接问题表现烧录时提示"连接超时"或"设备未响应",或烧录进度条卡
    的头像 发表于 03-26 09:05 887次阅读
    芯知识|WT588F02B语音芯片烧录<b class='flag-5'>失败</b>的<b class='flag-5'>原因</b>解析及<b class='flag-5'>解决方案</b>

    通过DLPDLCR4710EVM-G2的光机进行测试,断断续续会出现启动失败,最终彻底连接不上,是什么原因导致的?

    您好,我们自制了4710-g2evm的控制板,通过4710-g2evm的光机进行测试,断断续续会出现启动失败,最终彻底连接不上。使用放大镜查看发现,DMD芯片损坏,请问可能是什么原因导致的?
    发表于 02-18 06:36

    Simcenter Anovis声学噪声和振动信号解决方案

    SimcenterAnovis?获取完整的解决方案,进行合格/不合格检查SimcenterAnovis(声学噪声和振动信号)是一款的完整解决方案,可针对以下应用进行准确、客观的通过或失败
    的头像 发表于 01-17 11:32 770次阅读
    Simcenter Anovis声学噪声和振动信号<b class='flag-5'>解决方案</b>

    鸿蒙原生页面高性能解决方案上线OpenHarmony社区 助力打造高性能原生应用

    Nodepool、HMrouter和DataCache 三大解决方案,并上架OpenHarmony开源社区分,分别针对应用页面滑动、跳转、首页冷启动等关键性能场景提供高效易用的工具,助力伙伴和开发者打造
    发表于 01-02 18:00