在u-boot命令行中输入print会得到所以的环境变量,这些环境变量都是在哪里定义的呢??
先看看print命令在哪里实现
U_BOOT_CMD(
printenv, CONFIG_SYS_MAXARGS, 1, do_env_print,
"print environment variables",
"\n - print values of all environment variables\n"
"printenv name ...\n"
" - print value of environment variable 'name'"
);
文件common/Cmd_nvedit.c 定义了printenv命令,我们来看看它是从哪里打印的
int do_env_print (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int i;
int rcode = 0;
if (argc == 1) {
/* print all env vars */
rcode = env_print(NULL);
if (!rcode)
return 1;
printf("\nEnvironment size: %d/%ld bytes\n",
rcode, (ulong)ENV_SIZE);
return 0;
}
/* print selected env vars */
for (i = 1; i < argc; ++i) {
int rc = env_print(argv[i]);
if (!rc) {
printf("## Error: \"%s\" not defined\n", argv[i]);
++rcode;
}
}
return rcode;
}
env_print中
char *res = NULL;
size_t len;
/* print whole list */
len = hexport('\n', &res, 0);
if (len > 0) {
puts(res);
free(res);
return len;
}
再看hexport
ssize_t hexport(const char sep, char **resp, size_t size)
{
return hexport_r(&htab, sep, resp, size);
}
最终在函数hexport_r中找到这么一段
for (i = 1, n = 0, totlen = 0; i <= htab->size; ++i) {
if (htab->table[i].used) {
ENTRY *ep = &htab->table[i].entry;
list[n++] = ep;
totlen += strlen(ep->key) + 2;
if (sep == '\0') {
totlen += strlen(ep->data);
} else { /* check if escapes are needed */
char *s = ep->data;
while (*s) {
++totlen;
/* add room for needed escape chars */
if ((*s == sep) || (*s == '\\'))
++totlen;
++s;
}
}
totlen += 2; /* for '=' and 'sep' char */
}
}
将结构体htab中的table结构体中的entry项的地址给ep
然后把ep的地址给数组list,在下文打印出list数组
for (i = 0, p = res; i < n; ++i) {
char *s;
s = list[i]->key;
while (*s)
*p++ = *s++;
*p++ = '=';
s = list[i]->data;
while (*s) {
if ((*s == sep) || (*s == '\\'))
*p++ = '\\'; /* escape */
*p++ = *s++;
}
*p++ = sep;
}
我们来搜索一下看看谁定义并填充了htab结构体
在同一个文件中找到htab的定义
static struct hsearch_data htab;
那么猜测填充这个htab的函数也在这个文件中
果然在同文件中找到函数hcreate
int hcreate(size_t nel)
{
return hcreate_r(nel, &htab);
}
int hcreate_r(size_t nel, struct hsearch_data *htab)
{
/* Test for correct arguments. */
if (htab == NULL) {
__set_errno(EINVAL);
return 0;
}
/* There is still another table active. Return with error. */
if (htab->table != NULL)
return 0;
/* Change nel to the first prime number not smaller as nel. */
nel |= 1; /* make odd */
while (!isprime(nel))
nel += 2;
htab->size = nel;
htab->filled = 0;
/* allocate memory and zero out */
htab->table = (_ENTRY *) calloc(htab->size + 1, sizeof(_ENTRY));
if (htab->table == NULL)
return 0;
/* everything went alright */
return 1;
}
搜索一下看看谁调用hcreate
竟然没有人调用hcreate??这什么情况?不按套路出牌啊!
记得board_init_r函数中调用了一个环境变量初始化函数
/* initialize environment */
env_relocate();
env_relocate中有
</pre><pre name="code" class="cpp"> env_relocate_spec ();
结果弄了一堆env_relocate_spec ()不知道u-boot用的哪个,郁闷
最后根据编译u-boot时候的输出信息,common目录下包含了env_auto.o知道env_relocate_spec ()是在env_auto.c中定义
env_relocate_spec ()中
use_default();
找到use_default()
static void use_default()
{
char boot_cmd[100];
puts("*** Warning - using default environment\n\n");
if (default_environment_size > CONFIG_ENV_SIZE) {
puts("*** Error - default environment is too large\n\n");
return;
}
memset (env_ptr, 0, sizeof(env_t));
memcpy (env_ptr->data,
default_environment,
default_environment_size);
env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE);
gd->env_valid = 1;
env_import((const char *)env_ptr, 1);
}
在这里用的缺省环境变量设置
我们来看看default_environment
uchar default_environment[] = {
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS "\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND "\0"
#endif
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
"bootdelay=" MK_STR(CONFIG_BOOTDELAY) "\0"
#endif
#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
"baudrate=" MK_STR(CONFIG_BAUDRATE) "\0"
#endif
#ifdef CONFIG_ETHADDR
"ethaddr=" MK_STR(CONFIG_ETHADDR) "\0"
#endif
#ifdef CONFIG_IPADDR
"ipaddr=" MK_STR(CONFIG_IPADDR) "\0"
#endif
#ifdef CONFIG_SERVERIP
"serverip=" MK_STR(CONFIG_SERVERIP) "\0"
#endif
#ifdef CONFIG_GATEWAYIP
"gatewayip=" MK_STR(CONFIG_GATEWAYIP) "\0"
#endif
#ifdef CONFIG_NETMASK
"netmask=" MK_STR(CONFIG_NETMASK) "\0"
#endif
"\0"
};
再看看配置文件
#define CONFIG_ETHADDR 00:40:5c:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.0.20
#define CONFIG_SERVERIP 192.168.0.10
#define CONFIG_GATEWAYIP 192.168.0.1
#define CONFIG_BOOTDELAY 3
/* Default boot commands for Android booting. */
#define CONFIG_BOOTCOMMAND "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootm 40008000 41000000"
#define CONFIG_BOOTARGS ""
默认的环境变量为
bootargs=
bootcmd= movi read kernel 0 40008000;
movi read rootfs 0 41000000 100000;
bootm 40008000 41000000
bootdelay= 3
baudrate= 115200
ethaddr= 00:40:5c:26:0a:5b
ipaddr= 192.168.0.20
serverip= 192.168.0.10
gatewayip= 192.168.0.1
netmask= 255.255.255.0