仅对x4412从emmc引导的环境变量执行处理过程进行分析,从uboot的print命令打印环境变量开始逆向分析源码到板级初始化函数board_init_r的环境变量初始化函数。
我们在u-boot命令行中输入print会得到所有的环境变量,接下来我们来分析这些环境变量都是在哪里实现的。
先看看common/cmd_nvedit.c文件中定义的print命令:
U_BOOT_CMD(
printenv,CONFIG_SYS_MAXARGS, 1, do_env_print,
"print environmentvariables",
"\n - print values of all environmentvariables\n"
"printenv name ...\n"
" - print value of environment variable 'name'"
);
宏中定义print打印执行的函数do_env_print:
int do_env_print (cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
{
int i;
int rcode = 0;
if (argc == 1){
/* print all env vars */
rcode = env_print(NULL);
if(!rcode)
return 1;
printf("\nEnvironmentsize: %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;
}
打印一个或所有环境变量的命令接口:
static int env_print(char *name)
{
char*res = NULL;
size_tlen;
if(name) { /* print a single name */
ENTRYe, *ep;
e.key= name;
e.data= NULL;
ep= hsearch (e, FIND);
if(ep == NULL)
return0;
len= printf ("%s=%s\n", ep->key, ep->data);
return len;
}
/*print whole list */
len= hexport('\n', &res, 0);
if(len > 0) {
puts(res);
free(res);
return len;
}
/*should never happen */
return0;
}
其中函数env_print导出存储在哈希表中的线性形式的数据,在lib/hashtable.c中实现
ssize_th export(const char sep, char **resp, size_t size)
{
return hexport_r(&htab, sep, resp, size);
}
ssize_th export_r(struct hsearch_data *htab, const char sep, char **resp,size_t size)
{
ENTRY*list[htab->size];
char *res, *p;
size_t totlen;
inti, n;
/*Test for correct arguments. */
if ((resp == NULL) || (htab ==NULL)) {
__set_errno(EINVAL);
return (-1);
}
debug("EXPORT table = %p, htab.size = %d, htab.filled = %d, size = %d\n",
htab,htab->size, htab->filled, size);
/*
* Pass 1:
* search used entries,
* save addresses andcompute total length
*/
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 escapech