1.初始化:初始化env_htab,默认从nand flash中读取env分区中的结构体environment_s;如果没有saveenv,使用默认的default_environment board_init_f//board.c for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0)//遍历执行init_sequence数组中的函数,在这些函数中给gd的成员赋值 { env_init, /* initialize environment */ //env_nand.c { gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 1; } } } board_init_r//board.c { env_relocate(); { env_relocate_spec ();//env_nand.c { ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf);//从nand flash中读环境变量到buf(结构体environment_s) if (ret) {//读数据失败,使用默认的环境变量 set_default_env("!readenv() failed"); return; } //读数据成功 env_import(buf, 1); { if (crc32(0, ep->data, ENV_SIZE) != crc) { set_default_env("!bad CRC");//crc校验失败,因为没有saveenv,nand中没有该数据结构environment_s,使用默认的环境变量 { //从default_environment中读到env_htab,使用默认环境变量初始化hash table中的成员 (himport_r(&env_htab, (char *)default_environment,sizeof(default_environment), '\0', 0); gd->flags |= GD_FLG_ENV_READY;//初始化环境变量成功 } return 0; } //从ep->data中读到env_htab,初始化hash table中的成员 himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0) gd->flags |= GD_FLG_ENV_READY;//初始化环境变量成功 } } } } 2.saveenv do_env_save { saveenv()//env_nand.c { len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);//从env_htab中读到env_new.data env_new.crc = crc32(0, env_new.data, ENV_SIZE); nand_erase_opts writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new)//将结构体environment_s写到nand flash } } 3.printenv do_env_print { rcode = env_print(NULL); len = hexport_r(&env_htab, '\n', &res, 0); } 4.setenv //env的增删改操作 do_env_set { _do_env_set { e.key = name; e.data = NULL; hsearch_r(e, FIND, &ep, &env_htab);//搜索 if ((argc < 3) || argv[2] == NULL) { int rc = hdelete_r(name, &env_htab);//两个参数,删除 return !rc; } e.key = name; e.data = value; hsearch_r(e, ENTER, &ep, &env_htab);//添加/替换 } } 5.getenv { if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */ ENTRY e, *ep; WATCHDOG_RESET(); e.key = name; e.data = NULL; hsearch_r(e, FIND, &ep, &env_htab); return ep ? ep->data : NULL; } }