VxWorks BSP宏梳理

==============================================================

物理内存布局

==============================================================

1.LOCAL_MEM_LOCAL_ADRS/LOCAL_MEM_SIZE

(1) LOCAL_MEM_LOCAL_ADRS – Start(beginning) of RAM. Define in config.h

(2) LOCAL_MEM_SIZE - Size of RAM. Define in config.h

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》的V100R001CPE\config.h中定义了这两个宏:

#define    LOCAL_MEM_LOCAL_ADRS   0x80000000

#define    LOCAL_MEM_SIZE                 0x02000000  /* 32 MB */

--------------------------------------------------------------

 

2.sysPhysMemTop()

Routine returns address of top of physical memory. This routine will provide dynamic memory sizing if LOCAL_MEM_AUTOSIZE is defined in config.h.

The routine is in sysLib.c and its return value is: LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE.

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》的V100R001CPE\sysLib.c中定义了sysPhysMemTop():

char *sysPhysMemTop (void)

{

    static char * memTop = NULL;

 

    if (memTop == NULL)

        memTop = (char *)(LOCAL_MEM_LOCAL_ADRS +LOCAL_MEM_SIZE);

    return (memTop);

}

--------------------------------------------------------------

 

3.RESERVED and SYS_MEM_BOTTOM

(1) RESERVED  - Number of reserved bytes. Memory reserved from bottom of RAM, and will not be cleared on cold boot. Defined in configAll.h.

--------------------------------------------------------------

《VxWorks BSP for Intel's IXDP425(ARM)》的target\config\all\configAll.h中定义了RESERVED:

#if    (CPU_FAMILY==SPARC)

    #define RESERVED       0x2000     /* vector table base plus table size */

#else /* 68000 or others */

    #if   (CPU==MC68000)

        #define RESERVED   0x400    /* avoid zeroing MC68302 vector table */

    #else

        #if   (CPU_FAMILY == PPC)

            #define RESERVED   0x4400   /* avoid zeroing EXC_MSG */

        #else /* all other architectures */

            #define RESERVED       0

        #endif

    #endif /* mips cpp no elif */

#endif

--------------------------------------------------------------

MIPS中RESERVED=0。

(2) SYS_MEM_BOTTOM- For cold boot, memory will be cleared starting at this address. It expands to: LOCAL_MEM_LOCAL_ADRS + RESERVED.

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》的V100R001CPE\bootInit.c中定义了SYS_MEM_BOTTOM:

#define SYS_MEM_BOTTOM    (LOCAL_MEM_LOCAL_ADRS + RESERVED)

--------------------------------------------------------------

 

4.USER_RESERVED and SYS_MEM_TOP/sysMemTop()

(1) USER_RESERVED_MEM- Number of reserved bytes. Memory reserved from top of RAM and will not be cleared on cold boot or used by VxWorks. It will be defined as zero if not defined in config.h.

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》的V100R001CPE\config.h中定义了USER_RESERVED:

#define USER_RESERVED_MEM   0x00040000  /* reserve 256KB */

--------------------------------------------------------------

(2) SYS_MEM_TOP - For cold boot, memory will be cleared up to (but not including) this address. It expands to:

LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE - USR_RESERVED_MEM.

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》的V100R001CPE\bootInit.c中定义了SYS_MEM_TOP:

#define SYS_MEM_TOP    (LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE -USER_RESERVED_MEM)

--------------------------------------------------------------

(3) The routine sysMemTop defined in sysLib.c returns top of system memory. That is the address of the top of usable memoryexcept user reserved, which is just the same as macro SYS_MEM_TOP.

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》的V100R001CPE\sysLib.c中定义了sysMemTop():

char *sysMemTop (void)

{

    static char * memTop = NULL;/* Returned pointer to top of memory */

 

    if (memTop == NULL)

    {

        memTop = sysPhysMemTop () -USER_RESERVED_MEM;

    }

 

    return (memTop);

}

--------------------------------------------------------------

==============================================================

romStart()栈

==============================================================

5._STACK_DIR/STACK_RESIDENT/STACK_SAVE/STACK_ADRS

(1)_STACK_DIR

_STACK_DIR用于指明栈的生长方向,也将直接影响任务控制块windTcb中的pStackBase和pStackEnd取值。

--------------------------------------------------------------

h\types\vxArch.h中定义了默认的_STACK_DIR:

#ifndef  _STACK_DIR

    #define  _STACK_DIR      _STACK_GROWS_DOWN

#endif /* _STACK_DIR */

--------------------------------------------------------------

根据这个宏,说明前面可能有对_STACK_DIR的定义。在这句之前,有根据各个CPU包含相应的arch头文件:

--------------------------------------------------------------

#if (CPU_FAMILY==MIPS)

    #include <arch/mips/archMips.h>

#endif /* (CPU_FAMILY==MIPS) */

 

#if (CPU_FAMILY==PPC)

    #include <arch/ppc/archPpc.h>

#endif /* (CPU_FAMILY==PPC) */

 

#if (CPU_FAMILY==ARM)

    #include <arch/arm/archArm.h>

#endif /* (CPU_FAMILY==ARM) */

--------------------------------------------------------------

也就是说,在每个CPU对应的arch头文件中都会定义栈生长方向;如果没有定义的话,则vxArch.h中默认定义为向下生长。实际上在archMips.h、archPpc.h、archArm.h中均没有找到_STACK_DIR的定义,所以MIPS/PPC/ARM中的栈默认都是向下生长

(2)STACK_RESIDENT

--------------------------------------------------------------

《VxWorks BSP for Intel's IXDP425(ARM)》的target\config\all\configAll.h定义了STACK_RESIDENT:

#if     ((CPU_FAMILY == MIPS) || (CPU_FAMILY ==PPC))

#define STACK_RESIDENT  RAM_DST_ADRS

#else

#define STACK_RESIDENT  _sdata

#endif

--------------------------------------------------------------

在MIPS/PPC中STACK_RESIDENT=RAM_DST_ADRS,结合《VxWorks启动之romStart》中不同的映像类型RAM_DST_ADRS指向不同。

对于非MIPS/PPC体系结构,例如ARM体系中_sdata为数据段的首地址,s即start,与_edata对应(e即end)。

(3)STACK_SAVE

Maximum stack size for romStart(). Architecture specific. Not cleared on cold reboot.

--------------------------------------------------------------

《VxWorks BSP for Intel's IXDP425(ARM)》的target\config\all\configAll.h中定义了STACK_SAVE:

/*Resident ROMs constants */

 

#if     ((CPU_FAMILY==I960) || (CPU_FAMILY==ARM))

    #define STACK_SAVE     512     /* maximum stack used to preserve */

#else /* sparc or others */

    #if   ((CPU_FAMILY==SPARC) || (CPU_FAMILY==PPC))

        #define STACK_SAVE  0x1000

    #else /* all other architecutes */

        #define STACK_SAVE     0x40    /* maximum stack used to preserve */

    #endif             /* mips cpp no elif */

#endif

--------------------------------------------------------------

ARM中为STACK_SAVE=512字节;MIPS中为STACK_SAVE=0x40,即64字节。

VxWorks冷启动(BOOT_COLD,startType=BOOT_CLEAR)时,在romStart.c中的romStart()->bootClear()中或bootInit.c中的romStart()中不对STACK_SAVE部分清零。因为栈正在被romStart使用着。

(4)STACK_ADRS

Initial stack pointer. It is assumed that the romInit.s module has already set the initial stack pointer to STACK_ADRS.

The STACK_ADRS macro defaults to either RAM_DATA_ADRS, or RAM_DATA_ADRS-STACK_SAVE, depending on if the stack grows up or down for the given processor.

--------------------------------------------------------------

《VxWorks BSP for Intel's IXDP425(ARM)》的target\config\all\configAll.h中定义了STACK_ADRS:

#if   (_STACK_DIR == _STACK_GROWS_DOWN)


    #ifdef ROM_RESIDENT

        #define STACK_ADRS STACK_RESIDENT

    #else

        #define STACK_ADRS _romInit

    #endif /* ROM_RESIDENT */


#else /* _STACK_DIR == _STACK_GROWS_UP */


    #ifdef ROM_RESIDENT

        #define STACK_ADRS (STACK_RESIDENT-STACK_SAVE)

    #else

        #define STACK_ADRS (_romInit-STACK_SAVE)

    #endif /* ROM_RESIDENT */

 

#endif /* _STACK_DIR == _STACK_GROWS_UP */

--------------------------------------------------------------

<1>驻留(ROM_RESIDENT)型

对于驻留型,STACK_ADRS被定义为STACK_RESIDENT,而MIPS体系下STACK_RESIDENT被定义为RAM_DST_ADRS,详见下文的分析。

vxWorks_romResident中的CC_ROM_RES_FLAGS定义了RAM_DST_ADRS=RAM_DATA_ADRS=RAM_LOW_ADRS,bootrom_res中定义了RAM_DST_ADRS=RAM_HIGH_ADRS,都为数据段重定位地址。

可见,对于驻留型可引导映像,romStart()的栈STACK_ADRS是从数据段(RAM_DATA_ADRS)开始向下生长的。

For ROM-resident images the stack will begin at the start of data segment forMIPS which grow down.

<2>非驻留(non ROM_RESIDENT)型

对于非驻留型的bootrom(_uncmp)和vxWorks_rom(Compress),STACK_ADRS都被定为_romInit,这个是代码段的起始地址。可见,对于非驻留型的可引导映像,romStart()的栈是从bootstrap代码段开始向下生长的。参见图1 RAM Layout。

For non-ROM-residentimages the stack will begin at the start of the text segment of the VxWorks image forMIPS which grow down.

<3>romStart()栈sp赋值

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola'sMPC8260(PowerPC)》中的V100R001CPE\romMipsInit.s中将sp指针指向STACK_ADRS。

   /* Set stack to grow down from beginning of data and call init */

   la sp, STACK_ADRS-(4*_RTypeSize)  /* set stack to begin of data  */

--------------------------------------------------------------

在MIPS中,这个临时小栈(temporary stack)仅有64字节,是为跳转C函数入口romStart()准备的。对于VxWorks_rom*类型,该栈也被usrInit()使用,直到VxWorks内核启动(usrInit()->kernelInit())后,栈将重新分配。

romStack() stack is used until kernel is activated by kernelInit() which spawns a task (with its own stack) to complete system configuration and start user application (usually by spawning another task).

<4>Loadable VxWorks栈sp赋值

对于bootrom+VxWorks组合类型,bootstrap中的romStart()执行后,Loadable VxWorks被bootloader加载(bootload)到RAM_LOW_ADRS启动内核前,栈将在sysALib.s中重新分配为从VxWorks映像(代码段)向下生长。

Stack for usrInit() set up by sysInit() in sysALib.s grows away from VxWorks image to lower addresses in memory.

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola'sMPC8260(PowerPC)》中的V100R001CPE\sysALib.s中将sp指针指向sysInit()。

/* set stack to grow down from code, leave room for four parameters */
la sp, sysInit-(4*_RTypeSize)

--------------------------------------------------------------

对于bootrombootrom_uncmp,STACK_ADRS被定为_romInit。

bootrom中的bootstrap program将重定位到RAM_LOW_ADRS,此时STACK_ADRS=_romInit=RAM_LOW_ADRS;这里重新“la sp ”仍旧从RAM_LOW_ADRS向下生长,也即还是romStart()使用的那块堆栈。

对于bootrom_uncmp(bootrom_res),romStart()将整个bootrom(数据段)重定位到RAM_HIGH_ADRS处;此时STACK_ADRS=_romInit=RAM_HIGH_ADRS。因为VxWorks映像大小可能超过(RAM_HIGH_ADRS-RAM_LOW_ADRS),所以对于bootrom_uncmp(bootrom_res)型的bootloader,需要为VxWorks从汇编(sysInit() in sysALib.s)到C函数调用(usrInit())重新建立堆栈,以免破坏VxWorks映像。

<5>VxWorks多任务环境下的内存布局

vxWorks内核启动(usrInit()->kernelInit())后,内存将重新布局。因为SYS_MEM_BOTTOM到RAM_LOW_ADRS的空间可能不足以支撑VxWorks运行期的消耗。

VxWorks内核启动之后的内存布局大概是这样的:底部一般为加载的数据段和代码段;顶部的空闲内存区(MemPool)为系统运行期可分配空间,这些空间将用于Interrupt Stack、一些预留空间(leave room)、支持malloc动态分配内存的系统(FreeMemory Pool)和任务(Multi Task Stack)。(most user address spaces are only filled at the bottom (with code and data) and at the top(with a downward growing stack) with a huge gap in between.)

MIPS下_STACK_DIR=_STACK_GROWS_DOWN,kernelInit()的pMemPoolStart=FREE_RAM_ADRS,pMemPoolEnd=sysMemTop(),即MemPool从代码段结尾(end)到可用内存顶部。进入多任务环境后,任何函数调用(中断上下文除外)都使用所属任务的栈空间,即运行在线程上下文中。一旦函数局部变量过大或函数调用嵌套过深可能导致栈溢出。

关于VxWorks多任务环境的建立流程,可参考《vxworks_bsp_developers_guide_6.0》2.2.4 <Detailed Boot Sequence>。关于kernelInit()建立根任务tRootTask之后的内存布局和堆栈布局等细节,可参考《VxWorks Source Code》中提供的相关源代码。

<6>关于-4*_RTypeSize

(a)taskMipsLib.h中定义了:

--------------------------------------------------------------

#define _RTypeSize    4

--------------------------------------------------------------

(b)archMips.h中定义了:

--------------------------------------------------------------

#if   (CPU == MIPS32)

    #define _WRS_INT_REGISTER_SIZE    4

#elif (CPU == MIPS64)

    #define _WRS_INT_REGISTER_SIZE    8

#endif

--------------------------------------------------------------

asmMips.harchMips.h中定义了:

--------------------------------------------------------------

#define _RTypeSize_    WRS_INT_REGISTER_SIZE

--------------------------------------------------------------

综合(1)(2)可只_RTypeSize为CPU寄存器的尺寸,对于MIPS32为4字节。

那为何每次“la sp ”赋值时,都要减掉4个_RTypeSize呢?根据《MIPS体系结构透视》的11.2.3节指出:“前16个字节的参数通过寄存器a0-a3来传递,调用者保留参数结构中的前16字节,堆栈保留的结构必须预留。”11.2.9节指出:“传统MIPS函数调用约定为前4个函数参数保留空间,现在新调用约定只分配实际所需要的空间。”

这4个_RTypeSize即是按旧约定为a0~a3四个参数槽预留的空间(leave room for four parameters),可参考11.2.9节的FIGURE 11.8 - Stack frame for a non leaf function。


==============================================================

RAM

==============================================================

6.RAM_HIGH_ADRS/RAM_LOW_ADRS/FREE_RAM_ADRS

(1) RAM_HIGH_ADRS  - RAM load address for non-ROM-resident VxWorks boot images.

It is the load point for the boot program. It is also the start of the text segment for the boot program unless the boot image is ROM-resident, in which case it is the start of the data segment for the boot module.

 (2) RAM_LOW_ADRS- RAM load address for non-ROM-resident VxWorks application images.

It is the load point for VxWorks. It is also the start of the text segment of VxWorks.

此处安放的入口点对于下载型VxWorks为sysInit();对于引导型vxWorks_romCompress则为usrEntry()。

(3) FREE_RAM_ADRS - marks the end of the VxWorks image. Usually the system memory pool or the target server memory pool begins here.

/*configAll.h*/

#define FREE_RAM_ADRS    (end)  /* start right after bss of VxWorks */

 

7.RAM_DST_ADRS/RAM_DATA_ADRS

(1) Both the RAM_DST_ADRS and RAM_DATA_ADRS macros are link addressed defined by the Make system, which default to the BSP Makefile's RAM_LOW_ADRS and RAM_HIGH_ADRS respectively.

For information on how to change link addresses, refer to the file target/h/make/rules.bsp.

(2) RAM_DST_ADRS - Final relocation address for compressed image. Default value is RAM_HIGH_ADRS, redefined when necessary at compile time in rules.bsp.

(3) RAM_DATA_ADRS - Location in RAM to which the data segment is really linked. The RAM_DATA_ADRS macro is passed to us from the Make system. It represents the address to which the data segment is linked and defaults to the BSP Makefile's RAM_LOW_ADRS macro. For details on how to change the addresses to which VxWorks is linked, refer to the documentation in h/make/defs.vxWorks.

(4) 对于vxWorks_rom*类型,rules.vxWorks中根据映像类型是vxWorks_romCompress、vxWorks_rom或vxWorks_romResident,将ROM_FLAGS_EXTRA定义为CC_ROM_CMP_FLAGS、CC_ROM_CPY_FLAGS或CC_ROM_RES_FLAGS(defs.vxWorks中定义),其中分别定义了ROM_COMPRESS、ROM_COPYROM_RESIDENT宏。项目wpj文件在romInit.o和romStart.o的BUILDRULE中引入了ROM_FLAGS_EXTRA。

--------------------------------------------------------------

/*target\h\make\rules.vxWorks*/

ifeq($(basename $(DEFAULT_RULE)),vxWorks_romCompress)

    ROM_FLAGS_EXTRA = $(CC_ROM_CMP_FLAGS)

endif

ifeq($(basename $(DEFAULT_RULE)),vxWorks_romResident)

    ROM_FLAGS_EXTRA = $(CC_ROM_RES_FLAGS)

endif

ifeq($(basename $(DEFAULT_RULE)),vxWorks_rom)

    ROM_FLAGS_EXTRA = $(CC_ROM_CPY_FLAGS)

endif

 

/*target\h\make\defs.vxWorks*/

CC_ROM_RES_FLAGS=-DROM_RESIDENT -DRAM_DATA_ADRS=0x$(RAM_LOW_ADRS)\

                  -DRAM_DST_ADRS=0x$(RAM_LOW_ADRS)

CC_ROM_CPY_FLAGS=-DROM_COPY -DRAM_DATA_ADRS=0x$(RAM_HIGH_ADRS) \

                  -DRAM_DST_ADRS=0x$(RAM_LOW_ADRS)

CC_ROM_CMP_FLAGS=-DROM_COMPRESS -DRAM_DATA_ADRS=0x$(RAM_HIGH_ADRS)\

                  -DRAM_DST_ADRS=0x$(RAM_LOW_ADRS)

--------------------------------------------------------------

(5) 对于bootrom.bin类型,RAM_DST_ADRS被定义为RAM_HIGH_ADRS,用于存放bootrom.bin解压代码,入口点为compressedEntry()。

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》中的V100R001CPE\bootInit.c中定义了RAM_DST_ADRS的默认值:

--------------------------------------------------------------

#ifndef RAM_DST_ADRS                   /* default uncompress dest. */

#define RAM_DST_ADRS        RAM_HIGH_ADRS

#endif

--------------------------------------------------------------


图1 RAM Layout

RAM_DST_ADRS will be:

--------------------------------------------------------------

RAM_HIGH_ADRS for VxWorks bootimages(bootrom.bin压缩部分的解压目的地址)。

RAM_LOW_ADRS for applicationVxWorks images(vxWorks_romCompress.bin压缩部分的解压目的地址)。

--------------------------------------------------------------


==============================================================

ROM

==============================================================

8.ROM_SIZE/ROM_BASE_ADRS/ROM_TEXT_ADRS/ROM_DATA_ADRS

ROM_SIZE  - Size of ROM.

ROM_BASE_ADRS  - Start(Base address) of ROM.

ROM_TEXT_ADRS  - Boot ROM entry address.

    Start of text segment within ROM, typically a CPU-dependant offset from ROM_BASE_ADRS.

ROM_DATA_ADRS- Locationin ROM containing a copy of the data segment. This must eventually be copied  to the RAM address to which it is linked.

romStart() copies the data segment from ROM_DATA_ADRS to RAM_DATA_ADRS - the address to which it is really linked.

如果要build bootrom,则ROM_BASE_ADRS被定义为9fc00000(ROM/Flash的实际物理地址,ROM_PHY_ADDR=0xBFC00000);否则被定义为高端地址(比如RAM的最末尾20KB,足够容纳bootstrap代码)。

对于bootloader,bootstrap代码(romInit(),romStart())驻留在ROM中运行,romInit.s中通过RELOC定位romStart在ROM/Flash中的地址;romStart()中通过ROM_OFFSET定位其他辅助函数copyLongs在ROM/Flash中的地址。

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》中的V100R001CPE\config.h中定义了:

#define ROM_TEXT_ADRS    0xBFC00000  /* base address of ROM */

#define ROM_BASE_ADRS    ROM_TEXT_ADRS

#define ROM_SIZE      0x01000000  /* 16M ROM space */

--------------------------------------------------------------

对于第二种情形,注意ROM_BASE_ADRS/ROM_TEXT_ADRS/ROM_DATA_ADRS为基于RAM的linked address,在相应拷贝重定位时,需要加上(ROM_PHY_ADDR - ROM_TEXT_ADRS)这样一个偏移量。例如在定位vxWorks_romCompress(ROM_COMPRESS)中的subimage在ROM中的起始位置:ROM_DATA(binArrayStart)+(ROM_PHY_ADDR-ROM_TEXT_ADRS)。

 

9.binArrayStart/binArrayEnd

binArrayStart- Start of compressed binary image.

binArrayEnd- End of compressed binary image.

binToAsm将压缩bin文件作为一数据段,存放在汇编文件中(vxWorks.Z.s for vxWorks_romCompress,bootrom.Z.s for bootrom.bin),数据段起始于binArrayStart位置,在binArrayEnd处结尾。汇编文件中除了.data段外,无其他有效段。

--------------------------------------------------------------

   .data

 

   .p2align 2

binArrayStart:

_binArrayStart:

 

/*此处省略“.byte”若干行*/

 

   .p2align 2,0

binArrayEnd:

_binArrayEnd:

--------------------------------------------------------------

ccmips –c vxWorks.Z.s –o vxWorks.Z.o

ccmips –c bootrom.Z.s –o bootrom.Z.o

readelf –a”命令可以查看到vxWorks.Z.o或bootrom.Z.o中的.text和.bss段的Size均为0。

最后,ldmips将romInit.o、romStart.o(bootInit.o)、version.o和vxWorks.Z.o(bootrom.Z.o)链接生成vxWorks_romCompress(bootrom)。

在合并相似段时,如果romStart.o(bootInit.o)中有数据段,则[binArrayStart, binArrayEnd]紧随其后。Bootstrap中的压缩/解压缩等辅助函数代码的数据段紧随binArrayEnd之后存放。


图2 ROM Layout

 

10.ROM_OFFSET/ROM_DATA

Because romInit() is statically linked  into a VxWorks image, the address assigned to romInit() by the linker will be a ROM address for a ROM resident image and a RAM address for a non-ROM-resident ROM image.

ROM_OFFSET- Macro to re-compute absolute addresses which are not PIC compatible.

--------------------------------------------------------------

《VxWorks  BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》中的V100R001CPE\bootInit.c中定义了ROM_OFFSET:

#define ROM_OFFSET(adr)   (((UINT)adr -(UINT)romInit) + ROM_TEXT_ADRS)

#define ROM_DATA(adrs)    ((UINT)adrs + ((UINT)ROM_DATA_ADRS - RAM_DATA_ADRS))

--------------------------------------------------------------

对于bootloader(bootrom.bin),bootInit.c/romStart()仍然在ROM中执行,copyLongs()符号本身对应的是RAM中的链接地址,故需计算copyLongs()函数在ROM/Flash中的地址。ROM_OFFSET通过计算copyLongs与romInit的符号链接地址偏移,再加上romInit在ROM/Flash中的物理地址ROM_TEXT_ADRS,从而计算出copyLongs在ROM/Flash中的物理地址,实现正确调用。

ROM_OFFSET尽管可以实现指令代码的PIC调用,但对于指令中需要访问的数据段,一般在链接时已经都编址为基于RAM的linked address,则一定要拷贝到RAM中的VMA才能正确访问,否则程序可能跑飞。例如romStart中即将要用到的压缩/解压缩函数(inflate()/deflate())相关的数据段(初始化了的全局静态变量和局部静态变量)。所幸romStart一般都会调用copyLongs将ROM中的未压缩代码和数据段拷贝到RAM中,后续在RAM中更快地执行Stage2。


说明:

本文中涉及的target底下的代码和defs.vxWorks/rules.vxWorks等make脚本文件,源自《VxWorksBSPfor ixp425》以及《VxWorks BSP for AMD's AU1500(MIPS) and Motorola's MPC8260(PowerPC)》。

如无特殊说明,本文示例代码中涉及体系架构的分流均针对MIPS,即CPU_FAMILY==MIPS,具体来说是指MIPS32。


参考:

VxWorks架构

ROM_OFFSET的纳闷

romStart代码的小记

romInit.s文件分析

试论bootrom的拷贝地址

vxWorks bsp分析之bootInit.c

BSP映像分析和启动流程

romInit和romStart两个函数编译和链接后的地址

TornadoBSPTraining Workshop

    04_preKernelInit

    05_preKernelBoot

VxWorks启动流程

VxWorks创建任务中堆栈生长方向问题


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值