一、环境变量概述
1、环境变量的概念
可以理解为用户对软件的全局配置信息,这部分信息应该可以从永久性存储器上读取,能被查询,能被修改。
启动过程中,应该首先把环境变量读取到合适的内存区域,然后利用环境变量初始化硬件、启动操作系统等等。
2、启动过程中环境变量初始化过程涉及的问题
这里涉及到两个问题:
环境变量在哪个地方存着(从哪个地方取)
将环境变量存储到哪里(放到哪)
(1)环境变量位于存储器(norflash、nandflash )
“CFG_ENV_IS_IN_XXX”(CFG_ENV_IS_IN_FLASH、CFG_ENV_IS_IN_NAND等等)定义了则这种情况有效,以在flash上为例。
ENV_IS_EMBEDDED定义了
详细工作原理,见”ENV_IS_EMBEDDED“解惑以及相关的移植实验。这种情况的环境变量在flash上存着(但是占了flash一个扇区),并且随着代码段(因为环境变量区嵌在代码段内)在start.s重定位时一同载入内存。在环境变量初始化时候,如果这部分能通过校验,就不需要先在堆区开辟空间然后搬移的工作,而是直接使用这部分环境变量(省了搬移工作)。倘若不能通过校验,则使用默认环境变量放到重定位时环境变量所占的空间中。
ENV_IS_EMBEDDED没有定义
这种情况会在堆区为环境变量区开辟空间,如果flash上存储的是有效的(能通过校验)环境变量,则需要把flash上的数据搬运到堆区指定的位置;如果flash上的存储是错误的环境变量,那么使用默认的环境变量(default_environment)放到堆区。
(2)没有存储器上存储有环境变量
“CFG_ENV_IS_NOWHERE”定义了则选择这种模式,使用common/env_nowhere.c文件而不是用env_flash.c、env_nvram.c等等文件。
这种情况下,使用默认的环境变量(default_environment)。先在堆区为环境变量开辟空间,然后启动搬运工作。
二、环境变量初始化流程
以环境变量位于NorFlash上,并且没有使能“ENV_IS_EMBEDDED”功能为例,进行以下内容的分析。其他情况本文不讨论。
1、校验
直接在NorFlash上校验环境变量,实际上这一步是确定环境变量的源。如果NorFlash上存储的是有效的环境变量的话,那么就从NorFlash上读取数据。倘若NorFlash上存储的是无效的环境变量,那么使用默认的环境变量作为源。
2、重定位
将从存储环境变量的存储区加载到系统指定的位置。
3、涉及到的函数
(1)env_init
完成校验,并决定环境变量的源
此函数在start_armboot函数的开始阶段,会依次执行“init_sequence”中的每一个函数,其中一个就是env_init。
(2)env_relocate
首先,在堆区为环境变量开辟存储缓冲区。另外,当NorFlash上的环境变量区是无效的时候,选择默认的环境变量区进行定位。当NorFlash上的环境变量区是有效的时候,调用env_relocate_spec进行重定位。
此函数是在start_armboot函数的中途阶段,在NorFlash和NandFlash都初始化后,会调用这个函数。
(3)env_relocate_spec
此函数是被env_relocate所调用。
三、代码分析
1、相关全局变量
1> env_ptr(common/env_flash.c)
env_t *env_ptr = (env_t *)CFG_ENV_ADDR; // 定义flash中环境变量的地址 #ifdef CMD_SAVEENV static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
2> default_environment(common/env_common.c)
uchar default_environment[] = { #ifdef CONFIG_BOOTARGS "bootargs=" CONFIG_BOOTARGS "