vxworks的启动过程

Vxworks的启动和所有的嵌入式操作系统一样,首先要启动boot程序,然后由boot引导真正的内核印象和版本。不同的是,vxworksboot(也就是BSP)和大版本之间的代码有很多重入的地方,启动的过程也极其相似,这里就以MPC852为例,结合其BSP的源码分析一下整个启动的过程。

 

上图为BSP启动所要经历的几个文件中的几个函数,这个图相信大家已经看过很多次了,下面将以函数为单位一一介绍。

 

上电复位:

   

复位也是一种异常,向量号为0x100。异常向量表的基地址加上复位向量号即为复位向量,也就是CPU开始执行指令的地方。异常向量表在内存空间的可能位置有2个:0x000000000xFFF00000。具体是哪一个由MSR寄存器的IP位指定:若IP位为0,则异常向量表在0x0处,否则在0xFFF00000处。硬件复位时MSRIP位由硬件配置字的IIPInitial Interrupt Prefix)位决定,在本系统中IP1,所以上电后的第一条指令是在0xFFF00100处读取的。

 

MPC852内嵌的Memory Controller中,有系统的片选引脚,一般将片选引脚CS0连接到Boot Flash上,本系统中Boot Flash的大小为1M。决定该片选基地址和大小的是BR0OR0两个寄存器的BA[0:16]位和OA[0:16]位,这两个寄存器的这些位在上电后值为全零,也就是说,在上电后,从0x00000000开始4GB的空间都是Boot Flash,每1M都重复映射到该空间,所以第一条指令0xFFF00100肯定是在BOOT中。

 

Makefile文件的ROM_TEXT_ADRS    = FFF00100 # ROM entry address  ROM_TEXT_ADRS正是romInit函数在ROM中对应的位置(romInit标号在RAM中),所以可以得出上电后的第一句代码正是romInit()函数。

 

 

romInit()函数

该函数在romInit.s文件中,由PowerPC的汇编语言编写,主要完成最基本的CPU寄存器,初始化SDRAM,然后跳转到第一个C函数bootInit.c中的romstart()。下面为具体的代码:

 

 

_romInit:

romInit:

    bl    cold        /* jump to the cold boot initialization */

    bl    start        /* warm启动就直接跳到start*/

    .ascii 

    .align 2

/*cold启动*/

cold:

    li    r3, BOOT_COLD    /* BOOT_COLD将会作为启动类型被传送到romStart( )程序中去*/

 

/*下面这段所做的工作是计算标识startROM中的位置。为什么要计算呢,因为大多数的BSP的代码是在RAM中运行,所以连接器默认的标识都是处于RAM中,就像下面的标识startromInit,前面又说过了,ROM_TEXT_ADRSromInitROM中对应的位置以偏移的关系可以得出一些RAM中的标识在ROM中的位置,后面还会出现很多次。计算的公式为:ROM_ADRS(x) = (x) – romInit + ROM_TEXT_ARDS*/

    lis    r4, HIADJ(start)        /* load r4 with the address */

    addi    r4, r4, LO(start)        /* of start */

    lis    r5, HIADJ(romInit)        /* load r5 with the address */

    addi    r5, r5, LO(romInit)        /* of romInit() */

    lis    r6, HIADJ(ROM_TEXT_ADRS)    /* load r6 with the address */

    addi    r6, r6, LO(ROM_TEXT_ADRS)    /* of ROM_TEXT_ADRS */

    sub    r4, r4, r5

    add    r4, r4, r6

 

    mtspr    LR, r4      /* save destination address*/

                        /* into LR register */

    blr                    /* jump to flash mem address */

           

start:

    /*清除MSRDERICR寄存器*/

    xor    r4, r4, r4        /* clear register R4 */

    mtmsr     r4            /* cleat the MSR register */

    mtspr    DER, r4

    mtspr    ICR, r4

 

/*初始化ICTRL寄存器*/

    lis    r5, HIADJ(0x00000007)

    addi    r5, r5, LO(0x00000007)

    mtspr    ICTRL, r5

 

    /*禁止指令和数据CACHE */

   

    lis    r4, HIADJ ( CACHE_CMD_DISABLE)        /* load disable cmd */

    addi    r4, r4, LO (CACHE_CMD_DISABLE)

    mtspr    IC_CST, r4                /* disable I cache */

    mtspr    DC_CST, r4                /* disable D cache */

   

    lis    r4, HIADJ ( CACHE_CMD_UNLOCK_ALL)    /* load unlock cmd */

    addi    r4, r4, LO (CACHE_CMD_UNLOCK_ALL)

    mtspr    IC_CST, r4            /* unlock all I cache lines */

    mtspr    DC_CST, r4            /* unlock all D cache lines */

 

    lis    r4, HIADJ (CACHE_CMD_INVALIDATE)   /* load invalidate cmd*/

    addi    r4, r4, LO (CACHE_CMD_INVALIDATE)

    mtspr    IC_CST, r4        /* invalidate all I cache lines */

    mtspr    DC_CST, r4        /* invalidate all D cache lines */

 

/*

设置IMMR的值,IMMR寄存器的值很关键,知道了这个寄存器的值,再根据Memory Map中的偏移就可以知道所有的寄存器的值。

*/

    lis    r4, HIADJ( INTERNAL_MEM_MAP_ADDR)   

    addi    r4, r4, LO(INTERNAL_MEM_MAP_ADDR)

    mtspr    IMMR, r4        /* initialize the IMMR register */

    mfspr    r4, IMMR        /* read it back, to be sure */

    rlwinm  r4, r4, 0, 0, 15    /* only high 16 bits count */

 

    /* 设置SYPCR 寄存器,关闭 system protection stuff */

   

    xor    r5, r5, r5

    oris   r5, r5, 0xFFFF

    addi   r5, r5, LO(SYPCR_VAL)

    stw    r5, SYPCR(0)(r4)

 

    /* 下面是设置片选寄存器,MPC8524GB存储空间可以由8组寄存器BRxOrx决定,这里设置了CS0CS1的值 */

    lis    r5, HIADJ(BR0_VAL)                /* BR0, OR0 */

    addi    r5, r5, LO(BR0_VAL)

    stw    r5, BR0(0)(r4)

 

    lis    r5, HIADJ(OR0_VAL)

    addi    r5, r5, LO(OR0_VAL)

    stw    r5, OR0(0)(r4)

 

    /* For Flash */

    lis    r5, HIADJ(BR1_VAL)                /* BR1, OR1 */

    addi    r5, r5, LO(BR1_VAL)

    stw    r5, BR1(0)(r4)

 

    lis    r5, HIADJ(OR1_VAL)

    addi    r5, r5, LO(OR1_VAL)

    stw    r5, OR1(0)(r4)

 

代码太多了,估计要写个3,4天,今天就写到这,明天继续。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值