由于不同的主板,芯片配置的不一样,因此参数也不一样,那么就要保存一些参数在
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
地址,由于全世界都是唯一的地址,如果不幸有刚好跟你的网卡地址一样,就需要改变它的值了。