uboot环境变量

1 uboot变量保存位置

uboot环境变量会根据存储介质不同,保存的方式、位置可能不一样。使用emmc的板子会将uboot环境变量保存到emmc特定地址。具体代码env_mmc.c u-boot\common
  相关宏定义在s5p6818_drone.h u-boot\include\configs

	#if defined(CONFIG_ENV_IS_IN_MMC)
	#define	CONFIG_ENV_OFFSET			512*1024				/* 0x00080000 */
	#define CONFIG_ENV_SIZE           	32*1024					/* N block size (512Byte Per Block)  */
	#define CONFIG_ENV_RANGE			CONFIG_ENV_SIZE * 2 	/* avoid bad block */
	#define CONFIG_SYS_MMC_ENV_DEV  	CONFIG_SYS_MMC_BOOT_DEV
	#endif

CONFIG_ENV_OFFSET(512k=0x80000)就是emmc中保存环境变量的地址,大小是CONFIG_ENV_SIZE,为保证环境变量数据的安全,将环境变量保存两次,在不同的位置上,所以需要空间大小等于 32k * 2 = 64k。系统中可以有多个emmc,CONFIG_SYS_MMC_ENV_DEV 指定保存环境变量的emmc。

2 分区

分区文件内容

flash=mmc,2:2ndboot:2nd:0x200,0x7e00,2ndboot.bin;
flash=mmc,2:bootloader:boot:0x8000,0x77000,u-boot.bin;
flash=mmc,2:boot:ext4:0x000100000,0x004000000,boot.img;
flash=mmc,2:system:ext4:0x004100000,0x02F200000,system.img;
flash=mmc,2:cache:ext4:0x33300000,0x1AC00000,cache.img;
flash=mmc,2:misc:emmc:0x4E000000,0x00800000,misc.img;
flash=mmc,2:recovery:emmc:0x4E900000,0x01600000,recovery.img;
flash=mmc,2:userdata:ext4:0x50000000,0x0,userdata.img;

uboot的起始坡地址为0x8000,大小为0x77000,结束地址 = 0x8000 + 0x77000 = 0x7F000。boot.img的起始地址为0x100000,uboot结束到boot.img开始有0x100000 - 0x7F000 = 0x81000空间大小。环境变量地址从0x80000开始,需要64k = 0x10000空间大小,未用空间大小足够保存环境变量。

3 环境变量的保存、读取

具体代码实现在env_mmc.c u-boot\common
  环境变量保存,uboot命令行执行saveenv时会调用这个函数

int saveenv(void)
{
	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);/* 找到启动emmc,也是保存环境变量的emmc,之前的宏定义 */
	u32	offset;
	int	ret, copy = 0;
	if (init_mmc_for_env(mmc)) /* emmc 初始化 */
		return 1;
	ret = env_export(env_new); /* 从hash表中导出环境变量,并生成一个CRC较验码,用来保证环境变量的正确性 */
	if (ret)
		goto fini; /* 获取环境变量的地址,如果已经定义了CONFIG_ENV_OFFSET,那么就是这个地址 */
	if (mmc_get_env_addr(mmc, copy, &offset)) {
		ret = 1;
		goto fini;
	}
	printf("Writing to %sMMC(%d)... ", copy ? "redundant " : "", CONFIG_SYS_MMC_ENV_DEV);
	/* 将env_new保存的环境变量,写到offset开始的地址,实际调用mmc写函数 */
	if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) {
		puts("failed\n");
		ret = 1;
		goto fini;
	}
	puts("done\n");
	ret = 0;
fini:
	fini_mmc_for_env(mmc);
	return ret;
}

环境变量读取,uboot命令行下经常需要使用printf来查看环境变量,实现在cmd_nvedit.c u-boot\common

char *getenv(const char *name)
{
	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, 0); /* 从hash表中读取name的环境变量 */
		
		return ep ? ep->data : NULL;
	}
	/* restricted capabilities before import */
	if (getenv_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0)

	return NULL;
}

4 环境变量中数据结构

struct environment在u-boot/tools/env/fw_env.c中定义

struct environment {
	void			*image;
	uint32_t		*crc; /* 用来保存saveenv时生成的CRC较验码 */
	unsigned char		*flags;
	char			*data; /* 环境变量 */
	enum flag_scheme	flag_scheme;
};
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值