Wince500下ARM空间的应用

来源:互联网 发布:linux php ssh2 编辑:程序博客网 时间:2024/06/07 08:20

 

   如果我们要在WINCE环境下进行ARM项目开发,清楚的了解WINCE系统环境下ARM空间的应用机制是很必要的。

                                  g_oalAddressTable地址映射表

  在我们的开发中,不同类型不同功能的产品,需要使用不同的外设,从而也占用了不同的ARM总线物理空间。那么我们怎么让操作系统和BOOTLOADER知道硬件外围占用了ARM的哪些物理空间,并如何让操作系统和BOOTLOADER高效的管理这些空间呢?g_oalAddressTable这个映射表,就是为了满足这个要求提出来的。

g_oalAddressTable的每一行都定义了一个存储段的映射,格式:段的虚拟起始地址,段的物理起始地址,段的长度(单位是M.以下是个实际的例子:

g_oalAddressTable

    DCD 0x88000000, CSP_BASE_MEM_PA_CSD0,     128     ; DDR RAM

    DCD 0x80000000, CSP_BASE_MEM_PA_CS0,        32      ; NOR Flash

    DCD 0x90000000, CSP_BASE_MEM_PA_CS2,        32      ; CS2

    DCD 0x92000000, CSP_BASE_MEM_PA_CS3,        32      ; CS3

    DCD 0x94000000, CSP_BASE_MEM_PA_CS4,        32      ; CPLD

    DCD 0x96000000, CSP_BASE_MEM_PA_CS5,        32      ; SRAM

    DCD 0x98000000, CSP_BASE_MEM_PA_PCMCIA_CF,  64      ; PCMCIA/CF

    DCD 0x9C000000, CSP_BASE_REG_PA_AIPI1,       1       ; Internal registers (AIPI1 +                  AIPI2 + AITC + ROM Patch)

    DCD 0x9C100000, CSP_BASE_REG_PA_CSI,          1       ; CSI + ATA

    DCD 0x9C200000, CSP_BASE_REG_PA_NANDFC,    1       ; EMI modules (NANDFC + ESDRAMC + WEIM + M3IF + PCMCIA)

    DCD 0x9C300000, CSP_BASE_MEM_PA_VRAM,      1       ; VRAM (45K)

DCD 0x00000000, 0x00000000,                   0       ; Terminate table

以上映射表实例中,DDR RAM占用了以虚拟地址0X88000000为起始的128M的空间,它所对应的物理地址空间是以宏CSP_BASE_MEM_PA_CSD0定义值为起始地址的128M的空间。而NOR FLASH占用了以虚拟地址0X80000000为起始的32M的空间,其对应的物理地址空间是CSP_BASE_MEM_PA_CS0起始的32M空间。其它依此类推。

以上这个结构是给系统程序本身用的,对开发编译环境是不可见的。这个映射表在以下几个地方用到了:

第一,   bootloader建立MMU页表的时候有用到,此代码通常位于BootloaderStartUp.s文件中,举例如下:

; Load address of OEMAddressTable into r0

adrl    r0, g_oalAddressTable

; Load base address of page tables into r1

ldr     r1, =(MmuPageTableBase)

 

; Branch to set up MMU & enable caches

; to avoid SDRAM multiple read failure

b       mmuSetup    //此函数进行MMU页表的构建,并启动MMU

。。。。。。。。。。

 

第二,    WINCE OS建立MMU页表的时候也有用到,此代码位于C:/WINCE500/PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM/armtrap.s文件的KernelStart函数中:

LEAF_ENTRY KernelStart

mov     r11, r0       ; r0KernelStart被调用之前就已经赋值等于g_oalAddressTable

。。。。。。。。

第三,    虚拟地址和物理地址相互转换的函数中用到了:

下面抄了一段代码如下, 从这个代码看出ARM虚拟内存和物理内存的关系。

VOID* OALPAtoVA(UINT32 pa, BOOL cached)

{

    OAL_ADDRESS_TABLE *pTable = g_oalAddressTable;

    VOID *va = NULL;

    OALMSG(OAL_MEMORY&&OAL_FUNC, (L"+OALPAtoVA(0x%x, %d)/r/n", pa, cached));

     // Search the table for address range

    while (pTable->size != 0)

    {

         if ( pa >= pTable->PA && pa <= (pTable->PA + (pTable->size << 20) - 1) )

               break;            // match found 找到表中相近的内存

        pTable++;

     }

      // If address table entry is valid compute the VA

      if (pTable->size != 0) 

      {

            va = (VOID *)(pTable->CA + (pa - pTable->PA));

            // If VA is uncached, set the uncached bit

            if (!cached) (UINT32)va |= OAL_MEMORY_CACHE_BIT;

      }

      // Indicate the virtual address

      OALMSG(OAL_MEMORY&&OAL_FUNC, (L"-OALPAtoVA(va = 0x%08x)/r/n", va));

      return va;

}

                       存储空间配置文件

     到目前为止,我们已经让程序本身知道了目标系统中有哪些有效的物理地址空间,但这些信息对我们的开发环境是透明的,我们的开发环境要建立BOOTNK的映射文件,也需要知道我们目标系统的地址空间的配置情况。这就导致了另一个概念的提出:BIB文件,其全称Binary Image Builder File

BIB文件中分为4大项:MEMORY项,CONFIG项,MODULES项和FILES项。下面会详细介绍上面的4大项:

1.     MEMORY

一般都在config.bib文件中定义,开头会有MEMORY的字样。这里定义了为WinCE image以及其他模块预留的RAM,同时也定义了WinCE可以使用的RAM。具体格式如下:

MEMORY NAME Start Address Memory Size Type 

NAME:该内存区域的名字,必须是唯一的。

Start Address:该内存区域的起始地址,用十六进制表示。

Memory Size:该内存区域的大小,用十六进制表示。

Type:内存区域的类型。包涵的多种类型如下:

类型值

描述

FIXUPVAR

用于在WinCE编译的Makeimg阶段,就初始化一个内核中的全局变量。

NANDIMAGE

当创建了一个使用BinFSimage的时候,NAND设备上的WinCE kernel重定向到RAM中的区域,当系统访问该区域的时候,BinFS会负责访问Nand设备上相应的位置,并返回数据给系统,实际上就是在Nand设备上面实现了XIP的功能。

RAM

定义了被WinCE系统使用的RAM区域,这块内存必须是连续的,这里有一点要注意就是从硬件的角度来说,这块内存不能跨越两片SDRAM,也就是说整个区域空间必须在一片硬件SDRAM上。

RAMIMAGE

定义了一块内存区域用于加载WinCE image,实际上WinCE启动以后,image会被拷贝到这块内存区域上面运行。一个image只能有一个连续的RAMIMAGE区域。

RESERVED

这块内存区域会被预留出来,一般用于Frambuffer或者是DMA Buffer,或者是一块共享内存用于EBOOT传递参数给WinCE系统。

EXTENSION

定义了一块WinCE image中的区域作为ROMHDR extension的数据区域。

下面是一个内核映像配置实例:

MEMORY

; ----------------- Reserved Region Mapping (2 MB) ---------------------

;   Start Addr        End Addr        Mem Type    Region Name     Size

;   0x88000000      0x88000FFF      SDRAM       DRV_GLB           4 KB

;   0x88001000      0x880FFFFF      SDRAM       EBOOT_USED     1020 KB

;   0x88100000      0x881FFFFF      SDRAM       FRAMEBUFFER       1 MB

; ----------------------------------------------------------------------

;      Name        Address      Size          Type

      ARGS          88000000    00001000    RESERVED

       VPU          88001000    000FF000    RESERVED

     FRAMEBUFFER   88100000    00100000    RESERVED

 

IF IMGFLASH !

; --------------------------- RAM image --------------------------------

;   Start Addr        End Addr        Mem Type    Region Name     Size

;   0x88000000      0x881FFFFF      SDRAM       reserved         2 MB

;   0x88200000      0x8B1FFFFF      SDRAM       NK              48 MB

;   0x8B200000      0x8FFFFFFF      SDRAM       RAM             78 MB

; ----------------------------------------------------------------------

;     Name        Address     Size        Type

      NK          88200000    03000000   RAMIMAGE        //nk imageSDRAM

     RAM         8B200000    04E00000   RAM

ENDIF

 

IF IMGFLASH

; --------------------- FLASH image with EBOOT -------------------------

;   Start Addr        End Addr        Mem Type   Region Name     Size

;   0x80000000      0x8003FFFF      FLASH       resident EBOOT   256 KB

; IF BSP_KITL_ETHFEC

;   0x80040000      0x81FF7FFF      FLASH       NK              31.75 MB - 32KB

; ELSE

;   0x80040000      0x81FFFFFF      FLASH       NK              31.75 MB

; ENDIF

;   0x88000000      0x881FFFFF      SDRAM       reserved            2 MB

;   0x88200000      0x8FFFFFFF      SDRAM       RAM               126 MB

; ----------------------------------------------------------------------

IF IMGEBOOT

;     Name        Address     Size        Type

  IF BSP_KITL_ETHFEC

      NK          80040000    01FB8000    RAMIMAGE

  ELSE

      NK          80040000    01FC0000    RAMIMAGE

  ENDIF

      RAM         88200000    07E00000    RAM

ENDIF

 

; ------------------- FLASH image without EBOOT ------------------------

;   Start Addr      End Addr        Mem Type    Region Name     Size

; IF BSP_KITL_ETHFEC

;   0x80000000      0x81FF7FFF      FLASH       NK              32 MB - 32KB

; ELSE

;   0x80000000      0x81FFFFFF      FLASH       NK              32 MB

; ENDIF

;   0x88000000      0x881FFFFF      SDRAM       reserved         2 MB

;   0x88200000      0x8FFFFFFF      SDRAM       RAM            126 MB

; ----------------------------------------------------------------------

IF IMGEBOOT !

;      Name        Address     Size        Type

   IF BSP_KITL_ETHFEC

       NK          80000000    01FF8000    RAMIMAGE

   ELSE

       NK          80000000    02000000    RAMIMAGE

   ENDIF       

       RAM         88200000    07E00000    RAM

 ENDIF

ENDIF

 

2.     CONFIG

一般在config.bib文件中定义,定义了一些额外的配置参数,其中一些对于WinCE image来说也很重要。具体格式如下:

CONFIG   ITEM=Parameter

ITEM

描述

AUTOSIZE

允许未被使用的WinCE imageRAM被用作WinCE系统的RAM。默认值为ON

COMPRESSION

允许Romimage.exe压缩WinCE image中的可写入部分。默认值为ON

BOOTJUMP

定义了跳转跳转页在RAMIMAGE空间的地址。而不是默认情况下的RAMIMAGE的首地址。默认值为NONE

FSRAMPERCENT

定义了文件系统使用的内存的百分比。默认值为0x80808080Byte 0:第一个2MB中,每1MB所包含的4KB的倍数。Byte 1:第二个2MB中,每1MB所包含的4KB的倍数。Byte 2:第三个2MB中,每1MB所包含的4KB的倍数。Byte 3:剩下的内存中,每1MB所包含的4KB的倍数。

KERNELFIXUPS

定义了Romimage.exe是否重新定向内核的可写入区域。默认值为ON,内核的可写入区域被重新定向到RAMIMAGE的起始位置。

OUTPUT

定义了最终生成的image存放的路径。默认为%_FLATRELEASEDIR%

PROFILE

定义了是否在WinCE image中包含profiler的结构和符号。默认值为OFF

RESETVECTOR

重新指定跳转页的位置,一般针对MIPS芯片从0x9FC00000开始引导的问题。

ROMFLAGS

内核标记位,可以进行组合:0x01表示禁用按需分页。0x02表示禁用完全内核模式,完全内核模式表示所有的线程都运行在内核模式。0x10表示只信任ROM MODULES中的模块。0x20表示停止刷新TLB0x40表示按照/base链接选项中的地址加载DLL

ROMSTART

WinCE image在内存中的起始地址。

ROMSIZE

WinCE image的大小。

ROMWIDTH

指数据总线的宽度。

ROMOFFSET

指定一个偏移量来修改.bin文件中的每一个记录的地址。一般用于ROM中的.bin文件加载到RAM来运行的情况,主要是表示存储.bin的位置和运行.bin的位置不一样。

SRE

使Romimage.exe产生一个.sre文件。默认值为OFF

X86BOOT

定义是否插入一条跳转指令,在x86复位向量地址的时候。

具体例子如下:

CONFIG

; ---------------------- All Image Types Settings ----------------------

;   KERNELFIXUPS = ON (sections to which the kernel can write are

;                      relocated to the start of RAM)

;   SRE = ON (Romimage.exe produces an .sre file)

; ----------------------------------------------------------------------

    KERNELFIXUPS=ON

; --------------------------- RAM image --------------------------------

;   AUTOSIZE = ON (allows NK and RAM space to resize automatically)

;   ROMSIZE  = 0x04000000 (64 MB)

;   ROMSTART = 0x88000000 (SDRAM virtual address base)

;   ROMWIDTH = 32 (32-bit wide memory, entire image in one file)

; ----------------------------------------------------------------------

IF IMGFLASH !

    AUTOSIZE=ON

    ROMSIZE=04000000

    ROMSTART=88000000

    ROMWIDTH=32

ENDIF

; ------------------- FLASH image with/without EBOOT -------------------

;   ROMSIZE  = 0x02000000 (32 MB) for without EBOOT and FEC support

;                                 else should eliminate their size

; IF IMGEBOOT

;   ROMSTART = 0x80040000 (256KB(0x40000) area is reserved for EBoot)

; ELSE

;   ROMSTART = 0x80000000 (NOR virtual address base)

; ENDIF

;   ROMWIDTH = 32 (32-bit wide memory, entire image in one file)

; ----------------------------------------------------------------------

IF IMGFLASH

    IF IMGEBOOT

        IF BSP_KITL_ETHFEC

            ROMSIZE=01FB8000

            ROMSTART=80040000

        ELSE

            ROMSIZE=01FC0000

            ROMSTART=80040000

        ENDIF

    ENDIF

    IF IMGEBOOT !

        IF BSP_KITL_ETHFEC

            ROMSIZE=01FF8000

            ROMSTART=80000000

        ELSE

    ROMSIZE=02000000

    ROMSTART=80000000

        ENDIF

    ENDIF

    ROMWIDTH=32

ENDIF

; ------------------------------ COMPRESSION ---------------------------

;   NK COMPRESSION

; ----------------------------------------------------------------------

; @CESYSGEN IF !NK_NKNOCOMP

    COMPRESSION=ON

; @CESYSGEN ENDIF !NK_NKNOCOMP

; @CESYSGEN IF NK_NKNOCOMP

; @CESYSGEN ENDIF NK_NKNOCOMP

; ---------------------- Profiling-enabled kernel ----------------------

;   PROFILE = ON (includes profiler structure and symbols in image)

; ----------------------------------------------------------------------

IF IMGPROFILER

   PROFILE=ON

ENDIF

 

; --------------------- Profiling-disabled kernel ----------------------

;   PROFILE = OFF (does not include profiler structure and symbols)

; ----------------------------------------------------------------------

IF IMGPROFILER !

   PROFILE=OFF

ENDIF;

; ROMFLAGS is a bitmask of options for the kernel

;   ROMFLAGS    0x0001  Disallow Paging

;   ROMFLAGS    0x0002  Not all KMode

;   ROMFLAGS    0x0010  Trust Module only

;

IF IMGTRUSTROMONLY

    IF IMGNOTALLKMODE

       ROMFLAGS=12

    ENDIF

    IF IMGNOTALLKMODE !

       ROMFLAGS=10

    ENDIF

ENDIF

 

IF IMGTRUSTROMONLY !

    IF IMGNOTALLKMODE

       ROMFLAGS=2

    ENDIF

    IF IMGNOTALLKMODE !

       ROMFLAGS=0

    ENDIF

ENDIF

 

3MODULES项和FILES

该项列出了所有被包含在WinCE image中的模块以及文件,以及这些模块和文件以什么方式被加载到内存中。具体格式如下:

MODULES

Name     Path     Memory    Type 

Name:模块的名字,比如一个dll或者exe文件的文件名。

Path:路径,一般都是WinCE的工程的Release目录。

Memory:指定该模块被放在哪个区域,一般都是NK区域。

Type:定义了文件的类型。具体如下:

类型

描述

S

系统文件。

H

隐藏文件。

R

只压缩模块的资源部分。

C

压缩模块的所有部分。

D

禁止调试。

N

模块是不可信任的。

P

告诉Romimage.exe不需要检查CPU的类型。

K

告诉Romimage.exe必需固定该模块的内核地址。有该标记的模块只能被LoadKernelLibrary函数加载。

X

告诉Romimage.exe对该模块签名。

M

运行时加载整个模块,不要按需分页。

L

告诉Romimage.exe不要分离ROM DLL

一般FILES项的Type只支持SHND几个类型,而MODULES项的Type是都支持的。

举例如下:

FILES

; Name                  Path                        Memory    Type

; --------------------        --------------------------------------          ------     ----

  ETCHA.exe          $(_FLATRELEASEDIR)/ETCHA.exe        NK      U

  ETCHA.lnk          $(_FLATRELEASEDIR)/ETCHA.lnk         NK      U

  tcal.exe            $(_FLATRELEASEDIR)/tcal.exe           NK      U

IF BSP_FSL_WLAN_LP1070

uwa_airoha.bin $(_TARGETPLATROOT)/SRC/DRIVERS/LP107X/LP1070/uwa_airoha.bin 

NK    U

mac_airoha_STA.bin $(_TARGETPLATROOT)/SRC/DRIVERS/LP107X/LP1070/mac_airoha_STA.bin NK   U

ENDIF

对于BIB文件来说同样支持条件编译,在上面例子中我们也看到了,我们可以通过设置环境变量来选择性地将某些模块打包到WinCE image中。一般在BSP中,对于一些驱动模块的环境变量我们IF来进行条件判断。而对于WinCE的系统模块来说,一般都是SYSGEN变量,应该使用@CESYSGEN IF来判断。

我们在BSP的开发中最常见的主要就是eboot.bibconfig.bibplatform.bibproject.bib。下面简单介绍一下:

project.bib:该文件主要自创建的WinCE工程中所需的一些文件。

platform.bib:该文件包含了和硬件平台相关的文件,主要以驱动程序为主。

config.bib:该文件描述了WinCE系统的内存的配置。

eboot.bib:该文件描述了WinCEeboot的内存的配置。

还有其他的一些bib文件,在WinCE系统编译后都会背拷贝到工程的release目录下面。比如common.bibie.bib等。这些文件列出了WinCE的组件相关的文件,根据用户订制的系统,会被选择性的打包到WinCE image中。 

                                                                      总结

  到此,我们对ARM空间的应用有了一个基本的了解。在结束本话题之前,我想再强调一点,g_oalAddressTable地址映射表对程序本身可见,但对开发环境是透明的。而BIB文件是给开发环境使用的,当然在编译链接阶段会把BIB中设置的某些信息通过TOC传递给OSbootloader. 由于g_oalAddressTable的内容开发环境不可见,而BIB文件的内容OSbootloader不可见,所以我们开发的时候必须手动维护这两者的一致性,不能有冲突。