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;
};
<think>好的,用户想了解U-Boot环境变量的配置和使用示例。首先,我需要回忆一下U-Boot的基本知识,环境变量在U-Boot中的作用,以及如何操作它们。根据用户提供的引用内容,环境变量存储在flash中,默认值来自源代码,用户可以通过命令进行设置和保存。 首先,我应该解释什么是U-Boot环境变量,它们的作用是什么。然后,详细说明如何查看、设置、保存环境变量,并提供一些常见的使用示例,比如设置网络参数或启动命令。需要确保步骤清晰,命令正确,并且符合用户的实际操作需求。 用户可能想知道具体的命令语法,比如printenv、setenv、saveenv的使用方法。还要注意环境变量的优先级,当变量为空时使用默认值,否则使用用户设置的值。可能需要提到一些常见变量,如serverip、ipaddr、ethaddr、bootcmd和bootargs,这些在引用中都有涉及。 另外,用户可能需要示例来更好地理解,比如设置serverip的步骤,或者配置启动参数。需要确保示例准确,并且命令格式正确。同时,要注意用户可能的错误,比如忘记保存环境变量,导致重启后配置丢失,所以需要强调saveenv的重要性。 还要考虑用户可能遇到的问题,比如如何恢复默认设置,或者处理环境变量存储损坏的情况。可以简要提到这些情况,但主要焦点还是放在配置和使用示例上。 最后,根据用户的要求生成相关问题,这些问题应该与U-Boot环境变量的高级配置、存储位置、调试方法等相关,帮助用户进一步学习。</think>### U-Boot 环境变量的配置与使用详解 U-Boot 环境变量是嵌入式系统启动过程中用于存储配置参数的关键机制,其优先级规则为:若变量值为空则使用代码默认值,若已设置则优先使用用户定义值[^1]。以下从基础操作到典型场景逐步说明: #### 一、环境变量基础操作 1. **查看所有环境变量** ```bash => printenv baudrate=115200 bootcmd=run distro_bootcmd serverip=192.168.1.100 # 未设置时使用默认值 ``` 通过该命令可验证当前生效的变量值[^3]。 2. **设置/修改变量** ```bash => setenv serverip 192.168.1.100 => setenv bootdelay 3 # 修改启动等待时间 ``` 变量修改后仅在内存中生效,需执行保存操作才能持久化[^1]。 3. **保存到存储设备** ```bash => saveenv Saving Environment to SPI Flash... OK ``` 该操作将当前环境变量写入NOR Flash或eMMC等存储介质。 #### 二、典型配置场景示例 1. **网络参数配置** ```bash => setenv ipaddr 192.168.1.50 # 设备IP => setenv serverip 192.168.1.100 # TFTP服务器IP => setenv netmask 255.255.255.0 => saveenv ``` 这些参数直接影响`tftp`命令下载内核镜像等网络操作[^2]。 2. **MAC地址设置** ```bash => setenv ethaddr 00:0a:35:12:34:56 => saveenv ``` 注意:MAC地址首次设置后不可修改,需清除环境变量分区才能重置[^2]。 3. **自定义启动流程** ```bash => setenv bootcmd 'tftp 0x82000000 zImage; bootm 0x82000000' => setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 => saveenv ``` `bootcmd`定义自动执行的启动命令,`bootargs`向内核传递参数[^2]。 #### 三、高级操作技巧 1. **多环境备份机制** 修改`envsize`和`envnumber`实现多份环境备份: ```bash => setenv envsize 0x20000 # 单个环境区大小 => setenv envnumber 2 # 双备份配置 => saveenv ``` 2. **环境变量恢复** ```bash => env default -f # 恢复所有默认值 => saveenv # 清除自定义设置 ``` 3. **脚本化配置** 通过`;`分隔多个命令实现批量配置: ```bash => setenv init_cmd 'setenv ipaddr 192.168.1.10; setenv serverip 192.168.1.100; saveenv' => run init_cmd ``` #### 四、调试与验证 1. **变量值有效性检查** ```bash => env info env_valid = valid env_ready = true env_use_default = false ``` 该命令显示环境变量存储状态[^3]。 2. **Android系统读取验证** 通过`envtool`工具验证变量是否传递到系统层: ```bash # envtool r factory_test ubootenv init successful.(0) on ``` 这确认了U-Boot环境变量与Android系统的集成效果[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值