历史上的今天
返回首页

历史上的今天

今天是:2025年05月07日(星期三)

正在发生

2021年05月07日 | WinCE启动失败原因与解决办法

2021-05-07 来源:eefocus

本文通过一个真实的嵌入式项目进行说明。文中的嵌入式系统用的是arm处理器+WinCE平台,项目的目的是要把WinCE平台从旧版本移植到WinCE6.0平台上。但结果是这个WinCE系统在启动的时候经常会出现失败,而且每次失败的原因都莫明其妙和不尽相同。这使到我们开发团队每个人在启动WinCE系统时都心惊肉跳,非常担心系统又再一次出现让人意想不到的失败。这种频繁的启动失败对开发团队来说显然是一种让人难以忍受的折磨。


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


一.什么是WinCE启动过程?


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


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


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


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


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


推荐阅读

史海拾趣

Analogic Corporation公司的发展小趣事

Analogic Corporation 是一家总部位于美国马萨诸塞州的跨国公司,成立于1967年,主要从事医疗影像和航空安全领域的高性能技术产品的设计、制造和销售。以下是 Analogic Corporation 公司发展的相关故事:

  1. 成立与初期阶段:Analogic Corporation 成立于1967年,由 Bernard M. Gordon 博士和 Raymond J. Stata 博士等人共同创立。公司最初的业务重点是设计和制造用于医学影像诊断的模拟计算机设备。这些设备利用先进的模拟电子技术,帮助医生进行 X 射线、超声波和核磁共振成像等医学检查。

  2. 技术创新与产品优化:Analogic Corporation 在技术创新方面一直处于行业前沿。公司不断投入研发,并开发出一系列先进的医疗影像产品和航空安全技术。其产品包括 CT 扫描仪、核磁共振成像设备、安全检测设备等。这些产品以其高分辨率、高性能和可靠性而闻名,被广泛应用于医疗保健和安全检测领域。

  3. 市场拓展与全球业务:Analogic Corporation 在全球范围内建立了广泛的销售网络和合作伙伴关系。公司的产品远销世界各地,包括北美、欧洲、亚洲等地区。通过与国际合作伙伴的合作,Analogic Corporation 不断拓展业务范围,提升产品的市场占有率和影响力。

  4. 应用领域与客户合作:Analogic Corporation 的产品被广泛应用于医疗保健和航空安全领域。公司与全球各大医院、诊所、航空公司和安检机构等客户建立了长期稳定的合作关系。通过与客户的紧密合作,Analogic Corporation 不断了解市场需求,提供定制化的解决方案,满足客户的特定需求。

  5. 持续发展与未来展望:作为一家具有悠久历史和丰富经验的公司,Analogic Corporation 将继续致力于技术创新和产品研发,以满足不断变化的市场需求。公司将继续加强与客户和合作伙伴的合作关系,不断拓展业务领域,进一步提升产品性能和服务水平。在未来,Analogic Corporation 将继续保持行业领先地位,为客户提供更加优质和可靠的解决方案。

Force Technologies Ltd公司的发展小趣事

背景:随着全球对环境保护意识的增强,Force Technologies Ltd积极响应号召,将绿色环保理念融入企业发展中。

发展:公司投入巨资研发环保型电子产品和制造工艺,致力于减少生产过程中的废弃物排放和能源消耗。同时,公司还积极推动供应链的绿色化转型,与供应商共同制定环保标准和措施。这些努力不仅提升了公司的社会形象,还为其赢得了更多消费者的信赖和支持。

Cretex Companies Inc公司的发展小趣事

在电子行业的早期,Cretex Companies Inc.凭借对半导体技术的深入研究和创新,迅速崭露头角。公司研发出一款具有高效能、低功耗特点的芯片,这一技术突破使得电子设备的性能大幅提升,同时降低了能耗。凭借这一优势,Cretex的产品在市场上获得了广泛认可,公司规模逐渐扩大。

Faraday Electronics Inc公司的发展小趣事

在电子通信领域,Faraday Electronics Inc一直以其卓越的技术创新能力著称。公司自创立之初,就专注于研发高性能的通信芯片。经过多年的技术积累,终于在XXXX年成功推出了一款具有划时代意义的5G通信芯片。这款芯片不仅性能卓越,而且功耗极低,一经推出便迅速占领了市场,为公司带来了可观的利润。

力芯微(ETEK)公司的发展小趣事

2024年第一季度,力芯微公司实现了营业总收入2.20亿元,同比增长23.57%;归母净利润5347.70万元,同比增长93.35%。这一业绩的取得,不仅体现了公司强大的市场竞争力和盈利能力,也为公司未来的发展奠定了坚实的基础。同时,公司在资产结构、现金流量等方面也取得了显著的改善。

请注意,以上故事均基于事实描述,未对力芯微公司进行评价或褒贬。每个故事都力求全面、客观地展现力芯微公司在电子行业中的发展历程和成就。

Electroswitch公司的发展小趣事

面对快速变化的电子行业环境,Electroswitch始终保持着敏锐的洞察力和创新精神。公司不断加大对新技术和新产品的研发力度,推出了一系列具有领先水平的开关产品。同时,公司还积极探索新的业务领域和市场机会,为未来的发展做好充分准备。展望未来,Electroswitch将继续秉承“质量、选择、产品创新和出色的支持”的理念,为客户提供更加优质的产品和服务。

请注意,以上故事框架仅供参考,您可以根据这些框架进一步扩展和丰富故事内容。

问答坊 | AI 解惑

ARM教材(浙江大学)

这绝对是内部资料,分享下…

查看全部问答>

【藏书阁】锁相与频率合成技术

本书讲述模拟与数字锁相环及频率合成器的理论,组成,性能测试和设计,对单环数字式频率合成器,集成电路频率合成器,微计算机控制的频率合成器等作了详细的 阐述. 本书供各类高校本科生作专业课教材用.…

查看全部问答>

wince 驱动如何发送自定义消息??

我想实现在驱动中发送自定义消息。为什么总是无法接收到,也不知道是否发送。 使用SendMessage()函数。 SendMessage(HWND_BROADCAST,WM_COPYDATA ,(WPARAM)(&g_KeyCode),(LPARAM)(&g_KeyCode)); WM_COPYDATA的响应函数根本记不响应。 难道win ...…

查看全部问答>

把iptables移植到linux内核

在宿主机Red Hat Linux 9.0上安装iptables-1.3.6是可以用的,但我修改了内核路径和可执行文件路径到ARM文件系统后烧到板子(内核是Linux-2.6.8.1)上,使用iptables命令时出现bash: /sbin/iptables: cannot execute binary file,我想知道为什么在宿主机 ...…

查看全部问答>

新手问一个EVC很白痴的问题,给予100分

对话框上加了一个编辑框,定义这个编辑框的成员变量为m_now;再按扭里写了当前时间获取的代码SYSTEMTIME tm;     GetSystemTime(&tm);但是怎么把tm的值赋给m_now啊,我做了好几种办法都不对,大家帮帮我啊 …

查看全部问答>

紧急求助:pxa270下SDIO wifi模组的驱动 Marvell 8686

请问谁能发给我一份在PXA270下可以使用的SDIO WIFI模组的驱动,模组型号是USI的WM-G-MR-09,模组使用的芯片是Marvell 8686. 我手里有厂商给的驱动,名称是:SD-8686-WM60-ARMV4I-9.70.3.p23-38.p44.CAB,但是这份是基于PXA310和wince6.0的驱动,我 ...…

查看全部问答>

请教版主,关于fsmc功能地址复用功能的疑惑

版主你好,请问fsmc功能的地址总线复用是不是就对nor而言的,那个8位数据宽度设置是不是对nor是无效的,只能是16位或者32位。复用的时候模式是不是选择D模式…

查看全部问答>

MC34063问题

本帖最后由 paulhyde 于 2014-9-15 04:02 编辑 我们用MC34063做了一个DC-DC降压模块,但是输出不是很稳定,开关稳压为什么会不稳定的?  …

查看全部问答>

惊艳网友!宅男10天自制“iPad”

花费800元,感动女友,惊艳网友都说大学毕业是校园爱情的一道坎,很多恋人由于毕业分隔两地,不能见面就很容易分手。最近有一个大四学生为避免这个爱情魔咒,专门为女友自制了一台平板电脑,可以每天视频聊天。女友晒出这台电脑的照片,引来了无数 ...…

查看全部问答>