openwrt读写uboot_env

嵌入式系统,常常需要保存一些私有数据到设备,并且保证系统升级、重启不丢失。
常用做法
1、外挂eeprom,flash
2、现有存储介质,开辟新的mtd分区,进行操作。
等等
本节,透过uboot_envtools 操作uboot_env分区

uboot_envtools , 其实就是uboot源码一部分。具体实现在uboot/tools/env/目录下,通过在u-boot根目录下执行make env,就可生成fw_printenv应用程序,并将该应用程序拷贝到根文件系统中,就可以查看到uboot的相应的环境变量了。

1. 查看系统分区

root@OpenWrt:/usr# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00030000 00010000 "u-boot"
mtd1: 00010000 00010000 "u-boot-env"
mtd2: 00010000 00010000 "factory"
mtd3: 00fa0000 00010000 "firmware"
mtd4: 0016c8dc 00010000 "kernel"
mtd5: 00e33724 00010000 "rootfs"
mtd6: 00750000 00010000 "rootfs_data"

2. menuconfig添加uboot_envtools模块

 .config - OpenWrt Configuration
 > Utilities > Boot Loaders ─────────────────────────────────────────────────────────────────
  ┌──────────────────────────────────── Boot Loaders ─────────────────────────────────────┐
  │  Arrow keys navigate the menu.  <Enter> selects submenus ---> (or empty submenus      │  
  │  ----).  Highlighted letters are hotkeys.  Pressing <Y> includes, <N> excludes, <M>   │  
  │  modularizes features.  Press <Esc><Esc> to exit, <?> for Help, </> for Search.       │  
  │  Legend: [*] built-in  [ ] excluded  <M> module  < > module capable                   │  
  │ ┌───────────────────────────────────────────────────────────────────────────────────┐ │  
  │ │      < > fconfig..................................... RedBoot configuration editor│ │  
  │ │      <*> uboot-envtools................. read/modify U-Boot bootloader environment│ │  
  │ │                                                                                   │ │  
  │ │                                                                                   │ │  
  │ └───────────────────────────────────────────────────────────────────────────────────┘ │  
  ├───────────────────────────────────────────────────────────────────────────────────────┤  
  │               <Select>    < Exit >    < Help >    < Save >    < Load >                │  
  └───────────────────────────────────────────────────────────────────────────────────────┘  

3. 编译后,进入系统,测试

  • 查看env
root@OpenWrt:/# fw_printenv
bootcmd=bootp; setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; bootm
bootdelay=5
baudrate=115200
ssid=12345678
  • 添加env,uuid=1234567890
root@OpenWrt:/# fw_setenv uuid 1234567890
root@OpenWrt:/# fw_printenv
bootcmd=bootp; setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; bootm
bootdelay=5
baudrate=115200
ssid=12345678
uuid=1234567890
  • 删除env
root@OpenWrt:/# fw_setenv uuid
root@OpenWrt:/# fw_printenv
bootcmd=bootp; setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; bootm
bootdelay=5
baudrate=115200
ssid=12345678
root@OpenWrt:/#

4. 透过system、popen 管道,在c代码中读写操作


int fw_env_del(char *key)
{
	char buffer[256];
	sprintf(buffer,"fw_setenv %s",key);
	
	return system(buffer);
}

int fw_env_set(char *key,char *val)
{
	char buffer[256];
	sprintf(buffer,"fw_setenv %s %s",key,val);
	
	return system(buffer);
}

int fw_env_get(char *key,char *val)
{
	FILE * fp;
	char buffer[256];
	char read_key[32];
	char read_val[128];

	fp=popen("fw_printenv","r");
	if (fp<0){
		return -1;
	}

	while(fgets(buffer,sizeof(buffer),fp)){
		sscanf(buffer,"%[^=]=%s",read_key,read_val);

		if(!strcmp(key,read_key)){
			strcpy(val,read_val);

			pclose(fp);
			return 0;
		}
	}
		
	pclose(fp);
	return -404;
}

5. 脚本读取env

#!/bin/sh

# 加载ubootenv中的数据,抓取uuid的值,赋给变量data
data="$(fw_printenv | grep uuid | cut -d= -f2)"

echo data=$uuid

exit 0

6. 修改fw_env分区

  • 查看当前fw_env分区
root@OpenWrt:/# cat /etc/fw_env.config
/dev/mtd1 0x0 0x10000 0x1000
  • fw_env.config由脚本生成,路径package/boot/uboot-envtools/files/ramips
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x10000"
  • 参数定义在文件package/boot/uboot-envtools/files/uboot-envtools.sh中
ubootenv_add_uci_config() {
	local dev=$1
	local offset=$2
	local envsize=$3
	local secsize=$4
	local numsec=$5
	uci batch <<EOF
add ubootenv ubootenv
set ubootenv.@ubootenv[-1].dev='$dev'
set ubootenv.@ubootenv[-1].offset='$offset'
set ubootenv.@ubootenv[-1].envsize='$envsize'
set ubootenv.@ubootenv[-1].secsize='$secsize'
set ubootenv.@ubootenv[-1].numsec='$numsec'
EOF
	uci commit ubootenv
}
参数含义
/dev/mtd1指定boot_env所在flash上的分区
0x0指定boot_env所在分区上的偏移量(应该么有实际意义,mtd分区已经指定了偏移)
0x1000指定uboot的环境变量存储空间大小与package/boot/uboot-${boardname}/Makefile中定义的ENV_SIZE大小一致,否则会报CRC校验出错,比如mtd1分区的大小为1MiB,uboot指定的大小为0x40000,那么应该使用0x40000
0x10000指定flash的sector大小
  • 修改package/boot/uboot-envtools/files/ramips,就可以将数据保存到其他mtd分区
    例如:
ubootenv_add_uci_config "/dev/mtd7" "0x0" "0x10000" "0x1000"

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值