UBOOT之源码分析——初始化环境变量

本文详细分析了UBOOT中环境变量的处理,从printenv命令到board_init_r的环境变量初始化。讲解了如何从环境变量打印到哈希表中的数据结构,涉及cmd_nvedit.c、lib/hashtable.c等文件的关键函数,如do_env_print、env_print、hcreate_r等。最后介绍了针对EMMC引导的env_relocate_spec_movinand函数在环境变量初始化中的作用。
摘要由CSDN通过智能技术生成

    仅对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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值