wince6移植

 
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 http://bluefish.blog.51cto.com/214870/58118
     在整个移植过程中首先要做的第一步就是创建.pbcxml文件。
     这个文件的功能就与以前版本的.cec文件一样,只是在wince6下ms将其换了一种格式。如果你很牛比的话,而且有充足的时间,你完全可以自己创建并完善一个.pbcxml文件。
     比较省事一点的做法就是vs2005去打开一个wince5版本的.cec文件,并另存为.pbcxml文件即可。由于目前项目组没有基于wince5进行开发,手头上所有的bsp都是基于wince4.2的。然而经过多次试验证明wince4.2或者更早的版本的.cec文件是不能转换成.pbcxml文件的。具体的操作如下:
1.在vs2005开发环境中File/Open/File,在弹出的对话框中选择要打开的文件类型为“.pbcxml;.cec”,找到要打开的.cec文件。
2.如果你选择的.cec文件不是纯粹的基于wince5的,这时系统不出问题的话会弹出一个error对话框,有一堆的warnning和error!如果是基于wince5的(例如在安装wince5时自带的smdk2410),那么这时你就可以看到相应的各组件。
3.File/Save as为.pbcxml文件。
4.将上述保存的.pbcxml文件拷贝到winceroot/platform/[xxxx]/Catalog目录下。
      接下来就可以创建对应该bsp的os了。当然这只是一个起步,离完全将bsp移植到wince6下还有很长一段路要走。
大家都知道wince6下面oal与kernel不再链接成kern.exe,kernel部分单独为一个dll文件。它会被oal.exe所加载。所以首先要确保oal.exe可以被编译通过。
      这个文件编译的时候会链接大量的.lib文件,比较重要的一个就是oal.lib(WINCE600/PLATFORM/xxx/SRC/OAL/oallib目录下的文件编译后就是oal.lib),其余所要链接的一些.lib是io,intr,timer,cache,ioctl,power等一系列相关的文件。
      这里就说下上述所列的一些.lib文件的编译情况。从wince5下的bsp移植到wince6下,要注意一些文件目录的变动。WINCE600/PLATFORM/COMMON,这个目录就比较重要,主要放一些cpu相关的代码。这里主要关注WINCE600/PLATFORM/COMMON/SRC/SOC这个目录,可以看到,这里所放的文件夹的名称都是以cpu名称命名的。所以要移植一个wince6自身不带的bsp过来,就先要在这里创建一个类似的文件夹,不过不用去改dir文件,因为dir文件中的内容是DIRS=*。不用担心,在这个新建的文件夹下的代码不需要自己写,可以直接从wince5那里拷贝过来(不过改是必不可少的)。这个目录的代码主要来自两个地方:WINCE500/PUBLIC/COMMON/OAK/CSP/和WINCE500/PLATFORM/COMMON/SRC/下的相对应的cpu文件夹。第一部分直接拷贝过来放到WINCE600/PLATFORM/COMMON/SRC/SOC/xxx/下,第二部分的内容要放到WINCE600/PLATFORM/COMMON/SRC/SOC/xxx/oal/下。大体情况可以参考WINCE600/PLATFORM/COMMON/SRC/SOC/PXA27X_MS_V1下的文件布局。
      我现在的目标是能把整个os编译过去,所以没有怎么修改原代码,所修改的一般都是source文件。通过编译WINCE600/PLATFORM/xxx/SRC/OAL/oalexe这个目录可以生成oal.exe,在这个编译的过程中就会知道需要将哪些.lib文件编译进去了。WINCE600/PLATFORM/xxx/SRC/OAL文件是如何来的,可以参考ms的help文档。
     WINCE600/PLATFORM/COMMON/SRC/COMMON这个文件夹也很有用。如果oal.exe需要的哪个.lib文件,而你拷贝过来的那些代码实现不了,就可以用这个文件夹下的相应项。(如果没有链接相应的.lib文件,在编译oal.exe的时候会报某个该.lib文件提供的函数不能链接,这样搜索这个函数是在哪个.lib文件中,然后将这个.lib文件加到WINCE600/PLATFORM/xxx/SRC/OAL/oalexe下的source文件中去)。
      成功就是这样一步一步的从不断探索修改中走过来的。
   到目前,我移植的s3c2440bsp在wince6下可以跑到oeminit了,并且已经跑完。下面的事情似乎就是移植相关的drivers了。
      其实从可以编译nk.nb0到可以跑完oal没有什么太多要做的事情。首先调整了下config.bib文件中的nk的地址,以至于可以让原来现成的bootloader与其配套。修改debug.c中的调试串口的初始化,由于代码中用的是uart1,而我现在板子上要用uart0。
      在这里主要简单说下wince6内核的启动过程:
在bootloader加载内核到指定地址,并跳到内核中运行的时候,WINCE600/PLATFORM/SMDK2440/Src/oal/oallib下的startup.s文件中便包含了第一条要执行的命令。进行一些硬件的初始化(看门狗,中断,和时钟等),然后就是直接跳到KernelStart(此处kernelstart,我的理解是kernel.dll的入口,而并非armtrap.s中的kernelstart)。
     下面就是进入内核了,传说中的kernel.dll。NKStartup是这个文件的入口函数。具体实现在WINCE600/PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM下的mdarm.c中。在这里有调用OEMInitDebugSerial,OEMInit。在这个函数的最后调用了一个KernelStart()。
     KernelStart的实现在WINCE600/PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM下的armtrap.s文件中。在这里call了一个KernelInit和跳到FirstSchedule处执行调度第一个进程。
KernelInit函数在WINCE600/PRIVATE/WINCEOS/COREOS/NK/KERNEL下的nkinit.c中,主要是为内核启动做准备。调用的函数有APICallInit ();HeapInit ();InitMemoryPool ();PROCInit ();VMInit (g_pprcNK);THRDInit ();MapfileInit ();以后有空再详细分析下这几个函数。
     可惜我的nk跑着跑着出现了一个abort,在gwes中,郁闷!
   在移植的过程中,要经常更改.pbcxml文件以适应build时出现的一些error。这里就说下vs2005如何管理.pbcxml文件的。
     vs2005没有wince4.2(wince5)的PB中cec文件的管理工具。如果是在第一次拷贝某个bsp到wince600/platform目录下时(确保该bsp包的catalog目录下有相应的.pbcxml文件),直接打开vs2005创建os就可以了,vs2005会自动搜索platform目录下的.pbcxml文件,并将其列出(在创建os的第二步中)让用户选择创建的os是基于哪个bsp的。
     如果想更改一个现有的.pbcxml文件,并且假设已经有对该.pbcxml进行了修改并保存。首先,需要将platform/下的这个bsp包整个备份到另外一个地方,并将其删除(至于你建立的os项目最好也同时删除了,至少可以节省空间,留着也没有什么用)。其次,就是打开vs2005去创建一个os,其实这一步并不用真正去创建工程,只是跑到第二步去检查是否还可以看到被删除的bsp(正常情况下看不到了)。再次,就是将刚才备份的bsp再拷贝回到platform目录下,并将改好的.pbcxml文件复制到catalog文件夹下。并再次打开vs2005,这次是真正去创建你需要的os项目了。这时在选择bsp列表中就会出现刚才修改过的.pbcxml文件的对应项了。
      在这里再提一下对wince4.2的cec文件的转换(成为.pbcxml)。由于我们现在几乎所有的项目都是跑在wince4.2下,以前弄的那个基于wince5的cec文件转换非常不爽(主要是有些东西没有)。今天索性将wince4.2下目前的一个项目的cec文件转换了。对于出现的n多错误,没有办法,只能根据提示更改(可以参考wince6下的emulator的.pbcxml文件)。对于warnning你可以先不管,这时可以将其转换成你想要的.pbcxml文件,不过这里不能确定这些warnnings对你的移植工作有没有什么影响。
     通过对比发现,在自己转换的.pbcxml文件基础上创建的os工程里有很多这个bsp(移植的那个)的组件不让选择,然而用wince6自带的bsp通过创建os工程却可以。通过对比试验,主要是转换的.pbcxml文件中对应的组件项缺少<Module>xxxx.dll</Module>这项,用vs2005打开.pbcxml文件,选source页找到相应的项并加上就可以了。
     很无奈没有见过MS的gwes的实现代码。GWES是负责处理图形、窗口和事件的子系统,主要的工作就是处理图形输出和用户交互。显示设备驱动就是被它加载的,同时被GWES加载的还有打印机驱动,键盘驱动,鼠标驱动,触摸屏驱动。
MS的经典图:
      CE下所有的显示驱动都必须实现DDI函数集,这些函数用于初始化显示驱动以及把把图像用块传输(Blit)送往显示设备。显示驱动默认的名字叫做Ddi.dll,它本身所导出的函数只有DrvEnableDriver(实际的显示驱动也必须实现)一个,但是这个函数返回了一个包含27个函数指针的数组。GWES就是通过这些函数指针调用显示驱动(打印驱动)的。
看下DrvEnableDriver(是DDI函数之一),MS的解释:This function is the initial driver entry point exported by the driver DLL for devices that link directly to GWES。由于用到MS的GPE类,所以这个函数就直接调用了GPEEnableDriver,这两个函数连参数都一样。还是看下MS对这个函数的解释:This function initializes the callbacks that GDI provides for display drivers. It also fills in the driver entry points for the display driver in the DRVENABLEDATA structure。
      最终的xxxDISP类(最终继承于GPE)也就是真正的display驱动类的实例化是在GetGPE函数中实现。GetGPE通过DDI函数DrvGetModes被调用。
      GWES加载显示驱动的过程是:去访问候选显示设备列表(这个列表放在HKEY_LOCAL_MACHINE/System/GDI/DisplayCandidates下面,一般是在Platform.reg里建好的),看看是否有驱动程序已经在本机上实例化,如果有的话,GWES会使用它找到的第一个已经实例化的驱动;如果驱动程序没有在本机上实例话或者找不到合适的驱动程序,接下来GWES尝试加载Ddi.dll。默认情况下加载的是Ddi.dll,但是如果注册表项HKEY_LOCAL_MACHINE/System/GDI/Drivers/Display存在,GWES会加载此注册表项所指定的显示驱动。
 
下面是MS的一个列表可以对照上图进行理解
Element
Description
Application
The application can be simple, such as a Hello World application, or complex, such as a three-dimensional engineering application.
Whichever it is, the application calls GDI functions. Coredll.dll exposes these functions.
Coredll.dll
The major set of functions is exposed through a single DLL, called Coredll.dll.
In most cases, this library does not perform the work. Instead, the library packages the parameters for the function call and then triggers a Local Procedure Call (LPC) to another process.
The specific process depends on the function call. All drawing and windowing calls are sent to Gwes.dll.
Gwes.dll
The Graphics, Windowing and Events Subsystem (GWES) is responsible for all graphical output and all interactions with the user.
The drivers that reside in the GWES address space include display drivers, printer drivers, keyboard drivers, mouse drivers, and touch screen drivers.
Ddi.dll
The default name for the display driver is Ddi.dll. As with most DLLs, Ddi.dll communicates through exported functions.
Ddi.dll exports only the DrvEnableDriver function, which returns a pointer to an array of 27 function pointers to the caller. When GWES requires a display driver, it calls one of these 27 functions.
Writing a device driver involves writing the code for these 27 functions.
Three of these functions are specific to printer drivers, which leaves 24 for the display driver developer.
Hardware
The graphic pipeline ends at the hardware. The display driver communicates to the hardware using the mechanism required by the hardware.
This process typically involves a combination of memory-mapped video buffers and I/O registers.
 移植的wince6系统今天终于可以在S3C2440的板子上跑了。
      在整个移植过程中没有遇到什么技术上的难题,之所以会有以前的gwes.dll启动的时候abort。是因为没有将display的驱动放到内核模式中去,但是在加载的时候是用内核模式加载的,所以有些东西它是没有权限读写的,因此而挂掉了。
      与其说让MS给忽悠了,还不如说被自己忽悠了。人家明明说了要分内核模式和用户模式驱动的,但却不去关心这些事,只是一个劲的瞎改,能正常才怪。通过在.bib文件中的memory type项中加K就可以将相应的驱动指定为内核模式了。就这么简单。
      虽然系统可以跑起来了,但是目前我只加了一个驱动--display的,所以现在也就只能看看wince6的界面了。在porting别的驱动的时候应该也会遇到不少问题,不过也应该没有什么太大的问题,毕竟做的工作是移植。

本文出自 “bluefish” 博客,请务必保留此出处http://bluefish.blog.51cto.com/214870/58124

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值