Wince500下ARM空间的应用 地址映射 .bib文件分析-相当经典

本文转载,地址:http://blog.csdn.net/xuguod20042576/archive/2009/10/12/4656746.aspx,版权问题,马上删除

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zengdebiao/archive/2009/04/15/4074753.aspx

如果我们要在 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 页表的时候有用到,此代码通常位于 Bootloader 中 StartUp.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       ; r0 在 KernelStart 被调用之前就已经赋值等于 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;

}

                       存储空间配置文件

     到目前为止,我们已经让程序本身知道了目标系统中有哪些有效的物理地址空间,但这些信息对我们的开发环境是透明的,我们的开发环境要建立 BOOT 和 NK 的映射文件,也需要知道我们目标系统的地址空间的配置情况。这就导致了另一个概念的提出: 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
 当创建了一个使用 BinFS 的 image 的时候, 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 image 在 SDRAM

     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 image 的 RAM 被用作 WinCE 系统的 RAM 。默认值为 ON 。
 
COMPRESSION
 允许 Romimage.exe 压缩 WinCE image 中的可写入部分。默认值为 ON 。
 
BOOTJUMP
 定义了跳转跳转页在 RAMIMAGE 空间的地址。而不是默认情况下的 RAMIMAGE 的首地址。默认值为 NONE 。
 
FSRAMPERCENT
 定义了文件系统使用的内存的百分比。默认值为 0x80808080 。 Byte 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 表示停止刷新 TLB 。 0x40 表示按照 /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

 

3 . MODULES 项和 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 只支持 S , H , N , D 几个类型,而 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.bib , config.bib , platform.bib 和 project.bib 。下面简单介绍一下:

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

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

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

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

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

                                                                      总结

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

adr,adrl和ldr指令的用法比较
ADR :
    这是一条小范围的地址读取伪指令,它将基于PC的相对偏移的地址值读到目标寄存器中。

    使用的格式:ADR register,exper。

    在编译源程序时,汇编器首先计算出当前PC到exper的偏移值#offset_to_exper,然后会用一条ADD或者SUB指令来替换这条伪指令,例如:ADD register,PC,#offset_to_exper。

    注意,标号exper与指令必须在同一代码段。
ADRL :
    这是一条中等范围的地址读取伪指令,它将基于PC的相对偏移的地址值读到目标寄存器中。

    使用的格式:ADRL register,exper。

    在编译源程序时,汇编器会用两条合适的指令来替换这条伪指令。

    例如:

             ADD register,PC,offset1

             ADD register,register,offset2  

    与ADR相比,它能读取更大范围的地址。

    注意,标号exper与指令必须在同一代码段。
LDR :
   第一种情况:

        当LDR用做ARM指令时,它将基于PC的相对偏移地址处存储的值读到目标寄存器中。

        应用格式:LDR register,[expr]
   第二种情况:

         当LDR用做ARM伪指令时,它用于大范围的地址读取。

         其实说它用于大范围的读取,还不如说它用于大范围的地址赋值。我们来看一下这条伪指令的应用格式:LDR register,=expr/label_expr ,显然,我们可以直观的看出,指令的目的就是要将expr或label_expr赋值(=)给register.所以在编译时,当expr或 label_expr的值没有超出MOV和MVN的范围时,采用MOV或MVN指令来代替这条伪指令就显得理所当然了。当expr或label_expr 的值超出MOV和MVN的范围时,汇编器将expr或label_expr放入文字池中,并使用一条程序相对偏移指令LDR从文字池读出常量。例如:LDR register,[PC,#offset to literal pool]

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xuguod20042576/archive/2009/10/12/4656746.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值