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

发布者:数字驿站最新更新时间:2023-05-06 来源: elecfans关键字:启动代码 手机看文章 扫描二维码
随时随地手机看文章

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


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

 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中完成。


关键字:启动代码 引用地址:S3C2410-WinCE6.0-OAL的启动代码分析

上一篇:s3c2410 MMU详述
下一篇:S3C2410中文芯片手册-11.串口

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved