本节的代码都是在Mini440之uboot移植之实践NAND启动(四) 代码基础上修改的。
一、修改默认环境变量
不知道你有没有留意到,uboot在启动时,串口输出信息有下面一行:
U-Boot 2016.05 (Jan 14 2022 - 22:22:01 +0800) CPUID: 32440001 FCLK: 400 MHz HCLK: 100 MHz PCLK: 50 MHz DRAM: 64 MiB WARNING: Caches not enabled Flash: 2 MiB NAND: 256 MiB *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: dm9000 ### main_loop: bootcmd="<UNDEFINED>" SMDK2440 #
可以看出,读出的是坏的CRC,使用默认的环境变量,我们分析一下输出这个的原因。
1.1 分析环境变量初始化
在Mini440之uboot移植之源码分析board_init_r(四)我们介绍到board_init_r()函数会进行环境变量的的初始化。
具体在initr_env()函数执行过程中,该函数位于common/board_r.c文件,去掉无用代码如下:
static int initr_env(void) { /* initialize environment */ if (should_load_env()) env_relocate(); else set_default_env(NULL); /* Initialize from environment */ load_addr = getenv_ulong("loadaddr", 16, load_addr); return 0; }
其中should_load_env去除无用代码,定义如下:
static int should_load_env(void) { return 1; }
然后执行env_relocate();
1.2 env_relocate
env_relocate函数定义在common/env_common.c文件,去除无用代码:
void env_relocate(void) { if (gd->env_valid == 0) { bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM); set_default_env("!bad CRC"); } else { env_relocate_spec(); } }
会去根据gd->env_valid 前面有没有被初始化,是否为1,而决定,是直接调用默认环境变量,还是去调用env_relocate_spec ()去重新装载你之前存储在外部介质(例如NAND、NOR FLASH)中的环境变量。这里由于我们并没有将环境变量写入外部存储介质。
而我这里,按照上面说明,gd->env_valid=0,所以执行set_default_env("!bad CRC");
1.3 set_default_env
set_default_env函数定义在common/env_common.c文件:
void set_default_env(const char *s) { int flags = 0; if (sizeof(default_environment) > ENV_SIZE) { puts("*** Error - default environment is too largenn"); return; } if (s) { if (*s == '!') { printf("*** Warning - %s, " "using default environmentnn", s + 1); } else { flags = H_INTERACTIVE; puts(s); } } else { puts("Using default environmentnn"); } if (himport_r(&env_htab, (char *)default_environment, sizeof(default_environment), '