龙芯软件开发(22)-- 初始化环境参数

由于不同的主板,芯片配置的不一样,因此参数也不一样,那么就要保存一些参数在 Flash 里面,以便配置硬件。现在就看关于这方面的代码,如下:
void
envinit ()
{
    int i;
 
    SBD_DISPLAY ("MAPV", CHKPNT_MAPV);
 
    /* extract nvram variables into local copy */
    bzero (envvar, sizeof(envvar));
    tgt_mapenv (_setenv);
    envinited = 1;
 
    SBD_DISPLAY ("STDV", CHKPNT_STDV);
    /* set defaults (only if not set at all) */
    for (i = 0; stdenvtab[i].name; i++) {
       if (!getenv (stdenvtab[i].name)) {
           setenv (stdenvtab[i].name, stdenvtab[i].init);
       }
    }
}
 
上面代码,先显示正在初始化环境配置参数,然后清空 envvar 变量保存数组 ,接着调用函数 tgt_mapenv (_setenv) 设置环境变量参数,设置环境变量已经初始化,最后初始化标准的 stdenvtab 环境变量。
 
在函数 tgt_mapenv 里进行如下初始化:
/*
 * Read in environment from NV-ram and set.
 */
void
tgt_mapenv (int (*func) __P((char *, char *)))
{
    char *ep;
    char env[512];
    char *nvram;
    int i;
 
    /*
    * Check integrity of the NVRAM env area. If not in order
    * initialize it to empty.
    */
    printf("in envinit/n");
#ifdef NVRAM_IN_FLASH
    nvram = (char *)((tgt_flashmap())->fl_map_base + FLASH_OFFS);
    printf("nvram=%08x/n",(unsigned int)nvram);
    if(fl_devident(nvram, NULL) == 0 ||
       cksum(nvram + NVRAM_OFFS, NVRAM_SIZE, 0) != 0) {
#else
    nvram = (char *)malloc(512);
    nvram_get(nvram);
上面分配内存,然后从时钟芯片上读取那些参数出来,由于时钟芯片在 CPU 断电后,还会继续保存数据。接着在下面检校验数据是否有效。
 
    if(cksum(nvram, NVRAM_SIZE, 0) != 0) {
#endif
       printf("NVRAM is invalid!/n");
       nvram_invalid = 1;
上面是数据无效处理。
 
    }
    else {
 
下面就处理读取出来的参数。
 
       nvram += NVRAM_OFFS;
       ep = nvram+2;;
 
       while(*ep != 0) {
           char *val = 0, *p = env;
           i = 0;
           while((*p++ = *ep++) && (ep <= nvram + NVRAM_SIZE - 1) && i++ < 255) {
              if((*(p - 1) == '=') && (val == NULL)) {
                  *(p - 1) = '/0';
                  val = p;
              }
           }
           if(ep <= nvram + NVRAM_SIZE - 1 && i < 255) {
              (*func)(env, val);
           }
           else {
              nvram_invalid = 2;
              break;
           }
       }
    }
 
    printf("NVRAM@%x/n",(u_int32_t)nvram);
 
    /*
    * Ethernet address for Galileo ethernet is stored in the last
    * six bytes of nvram storage. Set environment to it.
    */
    bcopy(&nvram[ETHER_OFFS], hwethadr, 6);
    sprintf(env, "%02x:%02x:%02x:%02x:%02x:%02x", hwethadr[0], hwethadr[1],
       hwethadr[2], hwethadr[3], hwethadr[4], hwethadr[5]);
    (*func)("ethaddr", env);
上面读取网卡的 MAC 地址,总共有6个字节,并设置到环境变量里。
 
 
#ifndef NVRAM_IN_FLASH
    free(nvram);
#endif
 
#ifdef no_thank_you
    (*func)("vxWorks", env);
#endif
 
 
    sprintf(env, "%d", memorysize / (1024 * 1024));
    (*func)("memsize", env);
上面设置低端内存大小的变量。
 
    sprintf(env, "%d", memorysize_high / (1024 * 1024));
    (*func)("highmemsize", env);
上面设置高端内存大小的变量。
 
 
    sprintf(env, "%d", md_pipefreq);
    (*func)("cpuclock", env);
上面设置 CPU 总线运行频率。
 
 
    sprintf(env, "%d", md_cpufreq);
    (*func)("busclock", env);
上面设置 CPU 运行频率。
 
 
    (*func)("systype", SYSTYPE);
上面设置系统北桥类型。
 
}
 
上面函数读取时钟里保存的参数,并设置了一些标准的变量。接着来看标准环境变量的设置,主要从下面的数据结构 stdenvtab 里读取,并初始化。就来分析这个结构如下:
 
static struct stdenv {
    char           *name;
    char           *init;
    char           *values;
    int          (*chgfunc) __P((char *, char *));
} stdenvtab[] = {
    {"brkcmd", "l -r @cpc 1", 0},
#ifdef HAVE_QUAD
    {"datasize", "-b", "-b -h -w -d"},
#else
    {"datasize", "-b", "-b -h -w"},
#endif
    {"dlecho", "off", "off on lfeed"},
    {"dlproto", "none", "none XonXoff EtxAck"},
#ifdef INET
    {"bootp", "no", "no sec pri save"},
#endif
    {"hostport", "tty0", 0},
    {"inalpha", "hex", "hex symbol"},
    {"inbase", INBASE_DEFAULT, INBASE_STRING},
#if NCMD_MORE > 0
    {"moresz", "10", 0, chg_moresz},
#endif
    {"prompt", "PMON> ", 0},
    {"regstyle", "sw", "hw sw"},
#ifdef HAVE_QUAD
    {"regsize", "32", "32 64"},
#endif
    {"rptcmd", "trace", "off on trace"},
    {"trabort", "^K", 0},
    {"ulcr", "cr", "cr lf crlf"},
    {"uleof", "%", 0},
#ifdef PMON_DEBUGGER /* XXX: Patrik temp */
    {"validpc", "_ftext etext", 0, chg_validpc},
#endif
    {"heaptop", SETCLIENTPC, 0, chg_heaptop},
    {"showsym", "yes", "no yes"},
    {"fpfmt", "both", "both double single none"},
    {"fpdis", "yes", "no yes"},
#if defined(TGT_DEFENV)
    TGT_DEFENV,
#endif
    {0}
};
 
后面就调用函数 setenv 来分析这些变量的设置。到这里,就把环境变量初始化完成了,后面就根据这些变量来作不同的功能选择。比如网卡里要使用的 MAC 地址,由于全世界都是唯一的地址,如果不幸有刚好跟你的网卡地址一样,就需要改变它的值了。
 

你可能感兴趣的:(软件开发)