Chinaunix首页 | 论坛 | 博客
  • 博客访问: 227801
  • 博文数量: 49
  • 博客积分: 2101
  • 博客等级: 大尉
  • 技术积分: 525
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-07 10:38
文章分类

全部博文(49)

文章存档

2010年(49)

我的朋友

分类: 嵌入式

2010-09-07 11:02:59

1 startType

1)系统的启动类型定义在sysLib.h中。

/* system restart types */

#define  BOOT_NORMAL                         0x00      /* normal reboot with countdown */

#define        BOOT_NO_AUTOBOOT             0x01      /* no autoboot if set */

#define        BOOT_CLEAR                       0x02      /* clear memory if set */

#define  BOOT_QUICK_AUTOBOOT      0x04      /* fast autoboot if set */

 

/* for backward compatibility */

#define        BOOT_WARM_AUTOBOOT                    BOOT_NORMAL

#define        BOOT_WARM_NO_AUTOBOOT            BOOT_NO_AUTOBOOT

#define        BOOT_WARM_QUICK_AUTOBOOT            BOOT_QUICK_AUTOBOOT

#define        BOOT_COLD                                              BOOT_CLEAR

2rominit.s

rominit.s开始部分,根据启动类型的不同有不同的动作。如果是冷启动那么将BOOT_COLD写入R3寄存器,否则保持R3寄存器的默认值即热启动。查找BOOT_COLD的值,没有找到,不过我估计是非0值,R3寄存器在复位时应该被清零的。

3romstart()

rominit.s跳转到bootinit.cromstart()函数时需要向romstart()函数传递一个实参即启动类型startType。根据PPC的汇编知识,PPC使用R3-R108GPR来传递常规的函数实参,那么R3中的值就会作为romstart()的第一个实参。这样启动类型得以传递。

然后,在romstart()函数里会根据启动类型来确定是否清空内存。如果是冷启动,那么将清空内存,如果是热启动,那么不清空。

4usrinit()

       romstart()函数跳转到bootconfig.c中的usrinit()函数时,把startTape作为usrinit()的实参传递过去。

Usrinit()函数用将该实参赋给全局变量sysStartType

5usrroot()

       未使用sysStartType

6bootCmdLoop()

       多次使用了sysStartType,但是有的使用涉及sysFlags参数,而sysFlags参数是来源于config.h中的DEFAULT_BOOT_LINE,所以在介绍了BOOT_LINE后再详细的阐释bootCmdLoop()函数。

 

2 BOOT_LINE

1)在config.h中定义

引导参数BOOT_LINE是在config.h文件的宏定义DEFAULT_BOOT_LINE中定义的。该宏定义定义的是一个字符串,它包括了引导系统时所需要的参数。

       以下代码摘自mpc859_giga11.10config.h。首先是对DEFAULT_BOOT_LINE格式的注解:

/*Format: Launch point, file path/name, host IP, own IP, gateway IP, user name, user password */

/*dev(0,procnum)host:/file h= # e= # b= # g= # u=usr [pw=passwd] f= # tn=targetname s=script o=other */

       然后是我写的网络引导和TFFS引导两种不同引导方式对应的BOOT_LINE

#define DEFAULT_BOOT_LINE \

       "motfec(0,0)cumt-hhy:vxWorks h=192.168.0.12 e=192.168.0.123 g=192.168.0.1 u=dh pw=dh"

#define DEFAULT_BOOT_LINE \

       "tffs=0,0(0,0)cumt-hhy:/tffs0/vxWorks h=192.168.0.12 e=192.168.0.123 o=motfec g=192.168.0.1 u=dh pw=dh"

2bootCmdLoop()

       bootCmdLoop()中对DEFAULT_BOOT_LINE进行解析并使用,详见下面对bootCmdLoop()函数的分析。

 

3 bootCmdLoop()

1)打印Logo

       如果是冷启动类型,那么打印Logo

if (sysStartType & BOOT_CLEAR)

              printBootLogo ();

2)获取引导行参数

usrBootLineInit (sysStartType);

调用usrBootLineInit (sysStartType)函数来获得默认引导行参数DEFAULT_BOOT_LINE

VxWorks操作系统中,宏BOOT_LINE_ADRS是一个指针,它指向操作系统保存引导行参数的位置。如果是冷启动,那么将config.h中定义的DEFAULT_BOOT_LINE的值拷贝到BOOT_LINE_ADRS指向的地方。

LOCAL void usrBootLineInit (int startType)

    {

    if (startType & BOOT_CLEAR)

       {

       /* this is a cold boot so get the default boot line */

       if ((sysNvRamGet (BOOT_LINE_ADRS, BOOT_LINE_SIZE, 0) == ERROR) ||

           (*BOOT_LINE_ADRS == EOS) || (*BOOT_LINE_ADRS == (char) -1))

           {

           /* either no non-volatile RAM or empty boot line */

           strcpy (BOOT_LINE_ADRS, DEFAULT_BOOT_LINE);

           }

              }

    }

3)引导参数(字符串)转换到结构类型中

bootStringToStruct (BOOT_LINE_ADRS, ¶ms);

bootStringToStructbootLib.h中声明,params的类型是BOOT_PARAMS,该结构类型同样在bootLib.h中声明,声明如下。

typedef struct                           /* BOOT_PARAMS */

    {

    char bootDev [BOOT_DEV_LEN];    /* boot device code */

    char hostName [BOOT_HOST_LEN];       /* name of host */

    char targetName [BOOT_HOST_LEN];     /* name of target */

    char ead [BOOT_TARGET_ADDR_LEN];      /* ethernet internet addr */

    char bad [BOOT_TARGET_ADDR_LEN];      /* backplane internet addr */

    char had [BOOT_ADDR_LEN];         /* host internet addr */

    char gad [BOOT_ADDR_LEN];         /* gateway internet addr */

    char bootFile [BOOT_FILE_LEN];     /* name of boot file */

    char startupScript [BOOT_FILE_LEN];     /* name of startup script file */

    char usr [BOOT_USR_LEN];              /* user name */

    char passwd [BOOT_PASSWORD_LEN];       /* password */

    char other [BOOT_OTHER_LEN];     /* available for applications */

    int  procNum;                 /* processor number */

    int  flags;                        /* configuration flags */

    int  unitNum;                       /* network device unit number */

    } BOOT_PARAMS;

4)给全局变量sysFlags赋值

       sysFlags = params.flags;

       params结构变量中的flags值应该来自于DEFAULT_BOOT_LINE中的“f”参数。

       sysFlags可选的值定义在sysLib.h头文件中:

       #define SYSFLG_NO_SYS_CONTROLLER 0x01

/* System debug option:

      * load kernel symbol table with all symbols (not just globals)

*/

#define SYSFLG_DEBUG             0x02

#define SYSFLG_NO_AUTOBOOT  0x04    /* Don't start autoboot sequence */

#define SYSFLG_QUICK_AUTOBOOT  0x08    /* Immediate autoboot (no countdown) */

#define SYSFLG_NO_STARTUP_SCRIPT 0x10    /* Don't read startup script */

#define SYSFLG_NO_SECURITY     0x20 /* Don't ask passwd on network login */

#define SYSFLG_AUTOCONFIG      0x40   /* Use bootp or DHCP to get boot */

#define SYSFLG_TFTP          0x80   /* Use tftp to get boot image */

#define SYSFLG_PROXY            0x100  /* Use proxy arp */

#define SYSFLG_WDB         0x200  /* Use WDB agent */

#define SYSFLG_VENDOR_0           0x1000       /* vendor defined flag 0 */

#define SYSFLG_VENDOR_1           0x2000       /* vendor defined flag 1 */

#define SYSFLG_VENDOR_2           0x4000       /* vendor defined flag 2 */

#define SYSFLG_VENDOR_3           0x8000       /* vendor defined flag 3 */

5)判断是否直接引导

       是否直接引导是由传入atuoboottimeout)的实参timeout来确定的。如果timeout1,即等待的时间是1second基本上就是立即启动bootLoad开启引导,不给用户打断启动的机会;如果timeout7的话,那么等待的时间是7second而用户就有机会打断启动。

              if (!(sysStartType & BOOT_NO_AUTOBOOT) &&

                     !(sysFlags & SYSFLG_NO_AUTOBOOT))

                     {

                     int timeout = TIMEOUT;

 

                     if ((sysStartType & BOOT_QUICK_AUTOBOOT) ||

                   (sysFlags & SYSFLG_QUICK_AUTOBOOT))

                 {

                        timeout = 1;

                 }

 

                     key = autoboot (timeout); /* doesn't return if successful */

                     }

              根据atuoboot函数的代码,如果用户在等待的过程中按下任意键,那么autobootreturn用户按下的键值。

6)进入引导行配置循环

       如果atuoboot返回的值是‘@’,那么在这个循环里将会直接调用bootLoad启动引导,如果是其它的键值,那么将打印[VxWorks Boot]:并等待用户输入。

       输入‘?’将会有详细的解释J

键值

含义

d

display

e

exception

f

fill

t

transpose(?) (running out of letters!)

m

modify

s

system controller

p

print boot params

c

change boot params

g

Go

n

netifAdrsPrint

N

ETHERNET_ADR_SET

? h

help

@$

load and go with internal params

l

load with internal params

v

print version & logo

 

4 bootLoad

       bootLoad函数是最终的加载函数,它的函数原型如下:

LOCAL STATUS bootLoad  (char * bootString, FUNCPTR *pEntry )

1)获取引导参数

/* copy bootString to low mem address, if specified */

    if ((bootString != NULL) && (*bootString != EOS))

              strcpy (BOOT_LINE_ADRS, bootString);

BOOT_LINE_ADRS处获取引导参数。当然引导行配置循环中用户改变的都已经保存到了BOOT_LINE_ADRS处。

2)再次分解引导行参数到params结构 

/* interpret boot command */

 

    if (usrBootLineCrack (BOOT_LINE_ADRS, ¶ms) != OK)

              return (ERROR);

3)根据不同的引导设备开启不同的引导

根据params.bootDev的值来确定引导方式。

阅读(2114) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~