u-boot:env源码目录分析一

目的:探索env的读取和保存(qspi)

一.涉及的类型定义

 CONFIG_ENV_OFFSET_REDUND

ReDund:redundancy(冗余,即开启环境变量的备份).
官方解释:
config_env_offset_redundancy(可选)指定第二个存储区域,大小为CONFIG_ENV_SIZE,
用于保存环境数据的冗余副本。这提供了一个有效的备份副本,以防另一个副本损坏.
例如由于在"saveenv"操作期间电源故障。这个值也是以字节为单位,但也必须与MMC扇区边界对齐。

/*******************************************************************/
//解释:全局变量 struct hsearch_data env_htab的类型定义
typedef struct entry {
	const char *key;
	char *data;
	int (*callback)(const char *name, const char *value, enum env_op op,
		int flags);
	int flags;
} ENTRY;
typedef struct _ENTRY {
	int used;
	ENTRY entry;
} _ENTRY;

struct hsearch_data {
	struct _ENTRY *table;
	unsigned int size;
	unsigned int filled;
/*
 * Callback function which will check whether the given change for variable
 * "__item" to "newval" may be applied or not, and possibly apply such change.
 * When (flag & H_FORCE) is set, it shall not print out any error message and
 * shall force overwriting of write-once variables.
 * Must return 0 for approval, 1 for denial.
 */
	int (*change_ok)(const ENTRY *__item, const char *newval, enum env_op,
		int flag);
};

struct hsearch_data env_htab = {
	.change_ok = env_flags_validate,
};
/*************************************************************************/
//解释:env_t* env_out对应的类型定义

typedef struct environment_s {
	uint32_t	crc;		/* CRC32 over data bytes	*/
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
	unsigned char	flags;		/* active/obsolete flags	*/
#endif
	unsigned char	data[ENV_SIZE]; /* Environment data		*/
} env_t;

二.关键函数解释

/***********************env/env.c主要函数*****************************/
//解释:.config文件中的配置决定了驱动,以下三个函数均为调用对应存储设备驱动的实现(见注2)
//在zynq开发板环境下: env/sf.c
//初始化
int env_init(void)

/**************************************************************/
//从存储设备中加载环境变量
int env_load(void);

/**************************************************************/
//解释: 把环境变量保存到存储设备中
int env_save(void);
//注1:
//解释:定义一个环境变量驱动位置存放设置的宏,每一个存储环境变量的设备driver定义时都使用该宏

/* Declare a new environment location driver */
#define U_BOOT_ENV_LOCATION(__name)					\
	ll_entry_declare(struct env_driver, __name, env_driver)
//注2
U_BOOT_ENV_LOCATION(sf) = {
	.location	= ENVL_SPI_FLASH,
	ENV_NAME("SPI Flash")
	.load		= env_sf_load,
#ifdef CMD_SAVEENV
	.save		= env_save_ptr(env_sf_save),
#endif
#if defined(INITENV) && defined(CONFIG_ENV_ADDR)
	.init		= env_sf_init,
#endif
};
/***********************env/env.c 其他函数*****************************/


/***************************************************************/
//解释:从env_htab 中导出到env_out中,并计算env_out->crc

int env_export(env_t *env_out)
{
	char *res;
	ssize_t	len;

	res = (char *)env_out->data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		pr_err("Cannot export environment: errno = %d\n", errno);
		return 1;
	}

	env_out->crc = crc32(0, env_out->data, ENV_SIZE);

#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
	env_out->flags = ++env_flags; /* increase the serial */
#endif

	return 0;
}
/***************************************************************/
//解释:buf强制转换为env_t类型,然后导入到 全局变量env_htab
//(check:是否对比env_t的crc)
int env_import(const char *buf, int check)

三.zynq702 .config中的关键配置

CONFIG_ENV_SIZE=0x20000
CONFIG_ENV_OFFSET=0xE0000

#
# Environment commands
#
# CONFIG_CMD_ASKENV is not set
CONFIG_CMD_EXPORTENV=y
CONFIG_CMD_IMPORTENV=y
CONFIG_CMD_EDITENV=y
# CONFIG_CMD_GREPENV is not set
CONFIG_CMD_SAVEENV=y
CONFIG_CMD_ENV_EXISTS=y
# CONFIG_CMD_ENV_CALLBACK is not set
# CONFIG_CMD_ENV_FLAGS is not set

#
# Environment
#
# CONFIG_ENV_IS_IN_EEPROM is not set
# CONFIG_ENV_IS_IN_FAT is not set
# CONFIG_ENV_IS_IN_EXT4 is not set
# CONFIG_ENV_IS_IN_FLASH is not set
# CONFIG_ENV_IS_IN_MMC is not set
# CONFIG_ENV_IS_IN_NAND is not set
# CONFIG_ENV_IS_IN_NVRAM is not set
# CONFIG_ENV_IS_IN_ONENAND is not set
# CONFIG_ENV_IS_IN_REMOTE is not set
#!!!!!!确定使用env/sf.c中的驱动(见 注1)
CONFIG_ENV_IS_IN_SPI_FLASH=y      
# CONFIG_ENV_IS_IN_UBI is not set
CONFIG_ENV_SECT_SIZE=0x20000
# CONFIG_USE_DEFAULT_ENV_FILE is not set
# CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG is not set
CONFIG_NET=y
CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_NETCONSOLE is not set


注1:
static enum env_location env_locations[] = {
#ifdef CONFIG_ENV_IS_IN_EEPROM
	ENVL_EEPROM,
#endif
#ifdef CONFIG_ENV_IS_IN_EXT4
	ENVL_EXT4,
#endif
#ifdef CONFIG_ENV_IS_IN_FAT
	ENVL_FAT,
#endif
#ifdef CONFIG_ENV_IS_IN_FLASH
	ENVL_FLASH,
#endif
#ifdef CONFIG_ENV_IS_IN_MMC
	ENVL_MMC,
#endif
#ifdef CONFIG_ENV_IS_IN_NAND
	ENVL_NAND,
#endif
#ifdef CONFIG_ENV_IS_IN_NVRAM
	ENVL_NVRAM,
#endif
#ifdef CONFIG_ENV_IS_IN_REMOTE
	ENVL_REMOTE,
#endif
#ifdef CONFIG_ENV_IS_IN_SATA
	ENVL_ESATA,
#endif
#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
	ENVL_SPI_FLASH,
#endif
#ifdef CONFIG_ENV_IS_IN_UBI
	ENVL_UBI,
#endif
#ifdef CONFIG_ENV_IS_NOWHERE
	ENVL_NOWHERE,
#endif
};

你可能感兴趣的:(嵌入式,c语言)