S3C2410-WinCE6.0-OAL的启动代码分析

    到现在为止,我们已经了解了S3C2410平台上WinCE6.0的启动过程,包括NBOOT、EBOOT、OAL.exe、Kernel.dll的工作流程。关于WINCE600的目录也做了介绍。准备工作都做好了,接下来开始介绍S3C2410平台上WinCE6.0的移植。BSP的移植很大一部分是代码的移植,所以,这里仍然以代码为主线,以函数为单位来做介绍。BSP的代码一般来说也不是自己从无到有CODE出来的,大多由芯片厂商或者微软提供,OEM厂商需要做得事情是修改相关代码以满足自己硬件的特定需求,快速推出新的产品。如果BSP的移植从零开始,那么市场的先机就完全丧失了。所以这里的介绍将基于现有代码,着重说明移植时需要修改和注意的地方。

       前面已经提到,EBOOT加载完NK后,执行的第一个函数为OAL.exe中的Startup函数,接下来我们就开始分析这个函数的实现,它的代码如下:
     

Code
 1         INCLUDE kxarm.h
 2 
 3         IMPORT  KernelStart
 4 
 5         TEXTAREA
 6         
 7         ;Include memory configuration file with g_oalAddressTable
 8 
 9         INCLUDE oemaddrtab_cfg.inc
10  
11         LEAF_ENTRY StartUp
12 
13         ; Compute the OEMAddressTable's physical address and 
14         ; load it into r0. KernelStart expects r0 to contain
15         ; the physical address of this table. The MMU isn't 
16         ; turned on until well into KernelStart.  
17 
18         add     r0, pc, #g_oalAddressTable - (. + 8)
19         bl      KernelStart
20 
21         ENTRY_END 
22 
23         END

     

    代码简短,功能明确,完成一个函数调用。之所以能这么简短,是因为我们采用了BOOTLOADER,有关硬件初始化的工作都在BOOTLOADER中完成了,否则这里需要做硬件初始化,DeviceEmulator的对应代码就是如此,读者可以自行查看。

    代码虽然简短,但这里涉及很多内容,下面将一一分解。

    第一行代码,包括了头文件kxarm.h,它主要做了符号的宏定义,以便让我们的代码更简单,如宏定义了TEXTAREA、LEAF_ENTRY。

第二行代码,引入一个外部函数KernelStart,它的实现在NKLDR中,前文已经做过详细介绍,这里不再赘述。

    第三行代码,TEXTAREA是一个宏定义,标明以下为代码段。

    第四行代码,包括了一个头文件,该文件中定义了一个全局变量g_oalAddressTable,它建立了虚拟内存到物理内存的映射关系。有关OEMAddressTable的内容下文会详细说明。

    第五行代码,LEAF_ENTRY StartUp,其中LEAF_ENTRY也是一个宏定义,它似乎是定义了一个入口函数,并将其EXPORT。这里我们只要知道EBOOT最后跳转到NK中,就是跳到这就可以了。

    第六行代码,add     r0, pc, #g_oalAddressTable - (. + 8),简单来说就是将OEMAddressTable的地址放到R0中,但为什么这么写,下文再做分析。

    第七行代码,bl      KernelStart,调用函数KernelStart,开始启动kernel,前文以做介绍,也不再赘述。

    有点啰嗦了,但对于新人来说,还是有必要说明一下。这段代码中,我们需要注意的地方有两处,一是OEMAddressTable的作用,二是第六行代码为什么这么写。

    先说说OEMAddressTable。一般情况下,在WinCE中我们使用的都是虚拟内存地址,甚至在访问IO时都是如此。那么在访问虚拟内存地址时如何控制其对应的硬件或物理内存呢?这个工作由MMU(内存管理单元)来完成,MMU的功能之一就是将虚拟内存地址转换为物理内存地址。当然这种转换得有一定的逻辑关系。对于X86和ARM的CPU来说,OEMAddressTable即定义了虚拟内存到物理内存的映射关系,在MIPS和SH的处理器中,这种关系由CPU内部硬件控制,无须g_oalAddressTable。在WinCE中,这种通过OEMAddressTable的映射称为静态映射,对应的,我们还可以动态映射虚拟地址,一般用到VirtualAlloc()、VirtualCopy()、VirtualFree()这三个函数,而象MmMapIoSpace()等函数是CEDDK对前面几个函数的封装。

    再看第六行代码,add     r0, pc, #g_oalAddressTable - (. + 8),为什么这么写,这个+8是什么意思?反汇编看了下它对应的代码,如下图所示:
                        
     反汇编代码中的ADR是一个伪指令,它将一个地址load到R0中。源代码中采用了那么一行复杂的代码,不光S3C2410的这段代码如此,PXA270的也一样。要解释这个问题,就不得不说一下ARM中的指令预取。ARM处理器是流水线结构的,允许指令预取。在CPU执行当前指令的同时,可以从存储器中预取指令,所以当用户读取PC时,PC指向的是正在取指的指令,而非当前执行的指令,在ARM中,一般是当前执行指令下面的第2条指令(+8个字节)。所以这里的+8就不难理解了。

    本文分析了OAL的启动代码,重点介绍了OEMAddressTable的作用和指令预取对代码的影响。在移植BSP的过程中,如果硬件设备无法正常访问,首先应该确认OEMAddressTable是否建立了正确的映射关系。启动代码如果不正确,将会影响WinCE的启动,这时KITL、串口打印等常规调试方法都还无法使用,所以一定要多加小心,确保顺利通过。实在不行,只能通过点灯来Debug了。这里需要注意,OAL的启动代码执行之前,应该关闭MMU,Disable MMU的工作在EBOOT中完成。

时间: 2024-08-02 18:39:09

S3C2410-WinCE6.0-OAL的启动代码分析的相关文章

WinCE6.0 OAL的特点

     WinCE6.0的OAL跟WinCE5.0中的有较大差别.了解这些差别,对我们移植OAL部分很有帮助.本文将简要介绍WinCE6.0 OAL的特点.      WinCE5.0将内核.OAL和KITL链接成一个内核可执行文件NK.exe.而WinCE6.0将这三者分开,分别对应Kernel.dll.OAL.exe和KITL.dll.显而易见,这样做最大的好处是可以单独升级这三者中的任何一个,而先前的结构则是牵一发而动全身的.WinCE5.0的OAL结构如图1所示:           

S3C2410 && WinCE6.0的中断处理分析

     S3C2410的内核是ARM920T,所以,这里先介绍一下ARM920T的异常.ARM920T中有一个当前程序状态寄存器(CPSR),其中BIT6和BIT7分别控制FIQ和IRQ的使能与否.大家经常说的开中断和关中断,就是指的设置这两个BIT.        ARM体系的异常中断如下图所示:                        可以看到,ARM920T中一共有7中异常模式,如果同一时刻有多个异常发生,系统则通过优先级顺序来决定处理其中的哪一个异常.他们之间的优先级顺序从高到低

WinCE6.0的极速启动

       今天收获了一个道理,无论何事何地,一定要向内挖掘潜力!做WinCE的开发有几年了,今天才见识到WinCE的启动到底有到快.用SnagIT也有几年,竟然不知道它除了截屏,还可以录屏,效果相当好.所以,别以为自己什么都知道,其实更多的时候是处于一个无知的状态,只是自己都不知道罢了.        今天在开发平台上定制了一个支持Shell的微内核,8MB,从上电到看到CE桌面,竟然不到2s!要不是亲自掐表,真的不敢相信,WinCE的启动竟能有这快?绝不虚夸,贴图为证. 图1是WinCE启

S3C2410下WinCE6.0的启动过程详解

通过前两篇文章的介绍,我们已经知道NBOOT用来引导EBOOT,继而EBOOT加载并引导WinCE操作系统(NK).那么,WinCE6.0的启动过程又是怎样的呢?本文基于S3C2410的平台做一个详细的分析.需要说明的是,WinCE6.0的整个启动过程对于同一类型的MCU来说大同小异,如S3C2410和PXA270同属ARM平台的MCU,所以他们的启动过程是类似的,可以说唯一的不同就在OAL处,而WinCE操作系统的启动正是从OAL开始的.      OAL(OEM Adaptation Lay

嵌入式 arm-怎么获得s3c2410启动代码的运行时间和模拟整个启动过程?

问题描述 怎么获得s3c2410启动代码的运行时间和模拟整个启动过程? 我用的是英蓓特公司嵌入式教学平台EduKit-IV试验箱,搭配核心SAMSUNG S3C2410板.现在想获得s3c2410启动代码的运行时间和模拟整个启动过程.但是RTC只是精确到秒,而启动时间却是毫秒级的,一时想不到办法,请各位高手指导小弟!

Siebel Code Analyzer 0.02发布 代码分析工具

Siebel Code Analyzer 是一款发现和分析基于最佳实践的eScript代码http://www.aliyun.com/zixun/aggregation/17253.html">常见问题的代码分析工具.配有的Perl脚本finder.pl包括以下特点:连接对象数据库和分析eScript代码不正确的终止,支持多操作系统平台(支持Perl 5.10),独立数据库(通过使用DBI)和外部的配置文件.以后的版本将会包括一个完整的eScript解析器,识别try/catch/fina

SDL2.0例子代码分析---代码运行平台检测

简介 SDL2.0例子程序中的 testplatform项目代码分析 ,针对不同的平台 检测字节序 CPU支持的指令集 类型宽度 以及断言 代码+注释 #include <stdio.h> #include "SDL.h" #include "SDL_endian.h" #include "SDL_cpuinfo.h" #include "SDL_assert.h" /* * 该例子代码检测运行平台 */ //判断

SDL2.0例子代码分析-----CheckKeys Project

SDL简介 SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux.Windows.Mac OS X等)的应用软件.目前SDL多用于开发游戏.模拟器.媒体播放器等多媒体应用领域. SDL1.2和SDL2的差别 SDK1.2和SDL2.1系列的API接口变动的不小,当然功能也大大增强,支持多线程窗口. 具体的change 请看 h

WinCE6.0内存分析工具

      <Memory Usage Tool for Windows CE 6.x>中介绍了一个用于查看和分析WinCE6.0内存状态的工具,具体内容参见原文.       该工具主要有两部分组成,一个是运行于设备端的命令行程序(DevHealth60.exe),另一个是运行于PC端的分析和显示内存状态报告的工具(DevHealthViewer6.exe).       为了方便使用,写了一个小工具(HealthHelper)配合DevHealth60.exe.用法很简单,将其和DevHe