需求
系统起来之后,很多时候需要读取或者设置Uboot下的环境变量

实现
不同平台读取uboot环境变量略微有差异,思路都大同小异。Uboot底层有读取环境变量的实现,可参考实现。
这里以Amlogic 平台给出一个示例代码:

Coding

## read/write environment
## Copyright (c) 2019 www.fun.tv
## Author chenhai@fun.tv
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := envtool
LOCAL_MODULE_TAGS := optional
ifeq ($(TARGET_BOARD_PLATFORM), meson8)LOCAL_CFLAGS += -DMESON8_ENVSIZE
endif
ifeq ($(TARGET_BOARD_PLATFORM), gxbaby)LOCAL_CFLAGS += -DGXBABY_ENVSIZE
endif
ifeq ($(TARGET_BOARD_PLATFORM), gxtvbb)LOCAL_CFLAGS += -DGXTVBB_ENVSIZE
endif
ifeq ($(TARGET_BOARD_PLATFORM), gxl)LOCAL_CFLAGS += -DGXL_ENVSIZE
endif
LOCAL_CFLAGS    += -Wno-unused-parameter
LOCAL_SRC_FILES := main.cpp
LOCAL_SRC_FILES += ubootenv.c
LOCAL_C_INCLUDES := \external/zlib \external/libcxx/include
LOCAL_SHARED_LIBRARIES := \libcutils \libutils \liblog
LOCAL_STATIC_LIBRARIES := \libzinclude $(BUILD_EXECUTABLE)
envtool/main.cpp
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>#include "ubootenv.h"static int s_bootloaderEnvInited = -1;static int bootloader_env_init(void)
{int ret = bootenv_init();printf("ubootenv init %s.(%d)\n",(ret < 0) ? "failed" : "successful", ret);return ret;
}/** * bootloader environment variable init* * 0: success, <0: fail*/
static int ensure_bootloader_env_init(void)
{if (!s_bootloaderEnvInited)return 0;s_bootloaderEnvInited = bootenv_init();printf("ubootenv init %s.(%d)\n",(s_bootloaderEnvInited < 0) ? "failed" : "successful", s_bootloaderEnvInited);return s_bootloaderEnvInited;
}static int set_bootloader_env(const char* name, const char* value)
{int ret = ensure_bootloader_env_init();if (ret < 0) {return ret;}char ubootenv_name[128] = {0};const char *ubootenv_var = "ubootenv.var.";sprintf(ubootenv_name, "%s%s", ubootenv_var, name);return bootenv_update(ubootenv_name, value);
}static char *get_bootloader_env(const char * name)
{int ret = ensure_bootloader_env_init();if (ret < 0) {return NULL;}char ubootenv_name[128] = {0};const char *ubootenv_var = "ubootenv.var.";sprintf(ubootenv_name, "%s%s", ubootenv_var, name);return (char *)bootenv_get(ubootenv_name);
}int main(int argc, char *argv[])
{if((argc < 2) || (argc > 4)){printf("argc num = %d \r\n", argc);printf("useage: envtool r [name] \r\n");printf("        envtool w [name] [value]\r\n");usleep(1000);return -1;}bootloader_env_init();if (!strcmp(argv[1], "r")){printf("%s\r\n", get_bootloader_env(argv[2]));return 0;}else if(!strcmp(argv[1], "w")){set_bootloader_env(argv[2], argv[3]);return 0;}return -1;
}
envtool/ubootenv.c
#define LOG_TAG "envtool"#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <zlib.h>#include <cutils/properties.h>
#include <cutils/threads.h>
#include <cutils/klog.h>#ifdef MTD_OLD
# include <linux/mtd/mtd.h>
#else
# define  __user    /* nothing */
# include <mtd/mtd-user.h>
#endif#include "ubootenv.h"#define ERROR(x...)     KLOG_ERROR(LOG_TAG, x)
#define NOTICE(x...)    KLOG_DEBUG(LOG_TAG, x)
#define INFO(x...)      KLOG_INFO(LOG_TAG, x)
static mutex_t  env_lock = MUTEX_INITIALIZER;char BootenvPartitionName[32]={0};
char PROFIX_UBOOTENV_VAR[32]={0};static unsigned int ENV_PARTITIONS_SIZE = 0;
static unsigned int ENV_EASER_SIZE = 0 ;
static unsigned int ENV_SIZE = 0;static int ENT_INIT_DONE = 0;static struct environment env_data;
static struct env_attribute env_attribute_header;
//static char env_arg_buf[ENV_PARTITIONS_SIZE+sizeof(uint32_t)];/*************************for demo uboot arg areas write uboot args read and write*********************//* Parse a session attribute */
static env_attribute * env_parse_attribute(void) {char *value,*key;char *line;char *proc = env_data.data;char *next_proc;env_attribute *attr = &env_attribute_header;int n_char,n_char_end;memset(attr, 0, sizeof(env_attribute));do {next_proc = proc+strlen(proc)+sizeof(char);//NOTICE("process %s\n",proc);key = strchr(proc, (int)'=');if (key != NULL) {*key=0;strcpy(attr->key, proc);strcpy(attr->value, key+sizeof(char));} else {ERROR("[ubootenv] error need '=' skip this value\n");}if (!(*next_proc)) {//NOTICE("process end \n");break;}proc = next_proc;attr->next =(env_attribute *)malloc(sizeof(env_attribute));if (attr->next == NULL) {ERROR("[ubootenv] exit malloc error \n");break;}memset(attr->next, 0, sizeof(env_attribute));attr = attr->next;}while(1);//NOTICE("*********key: [%s]\n",env_attribute_header.next->key);return &env_attribute_header;
}/*  attribute revert to sava data*/
static int env_revert_attribute(void) {int len;env_attribute *attr = &env_attribute_header;char *data = env_data.data;memset(env_data.data,0,ENV_SIZE);do {len = sprintf(data, "%s=%s", attr->key, attr->value);if (len < (int)(sizeof(char)*3)) {ERROR("[ubootenv] Invalid data\n");}elsedata += len+sizeof(char);attr=attr->next;}while(attr);return 0;
}env_attribute *bootenv_get_attr(void) {return &env_attribute_header;
}void bootenv_print(void) {env_attribute *attr=&env_attribute_header;while (attr != NULL) {INFO("[ubootenv] key: [%s]\n", attr->key);INFO("[ubootenv] value: [%s]\n\n", attr->value);attr = attr->next;}
}int read_bootenv() {int fd;int ret;uint32_t crc_calc;env_attribute *attr;struct mtd_info_user info;struct env_image *image;char *addr;if ((fd = open(BootenvPartitionName,O_RDONLY)) < 0) {ERROR("[ubootenv] open devices error: %s\n" ,strerror(errno));return -1;}addr = malloc(ENV_PARTITIONS_SIZE);if (addr == NULL) {ERROR("[ubootenv] Not enough memory for environment (%u bytes)\n",ENV_PARTITIONS_SIZE);close(fd);return -2;}memset(addr,0,ENV_PARTITIONS_SIZE);env_data.image = addr;image = (struct env_image *)addr;env_data.crc = &(image->crc);env_data.data = image->data;ret = read(fd ,env_data.image, ENV_PARTITIONS_SIZE);if (ret == (int)ENV_PARTITIONS_SIZE) {crc_calc = crc32(0,(uint8_t *)env_data.data, ENV_SIZE);if (crc_calc != *(env_data.crc)) {ERROR("[ubootenv] CRC Check ERROR save_crc=%08x,calc_crc = %08x \n",*env_data.crc, crc_calc);close(fd);return -3;}attr = env_parse_attribute();if (attr == NULL) {close(fd);return -4;}//bootenv_print();} else {NOTICE("[ubootenv] read error 0x%x \n",ret);close(fd);return -5;}close(fd);return 0;
}const char * bootenv_get_value(const char * key) {if (!ENT_INIT_DONE) {return NULL;}env_attribute *attr = &env_attribute_header;while (attr) {if (!strcmp(key,attr->key)) {return attr->value;}attr = attr->next;}return NULL;
}/*
creat_args_flag : if true , if envvalue don't exists Creat it .if false , if envvalue don't exists just exit .
*/
int bootenv_set_value(const char * key,  const char * value,int creat_args_flag) {env_attribute *attr = &env_attribute_header;env_attribute *last = attr;while (attr) {if (!strcmp(key,attr->key)) {strcpy(attr->value,value);return 2;}last = attr;attr = attr->next;}if (creat_args_flag) {NOTICE("[ubootenv] ubootenv.var.%s not found, create it.\n", key);/*******Creat a New args*********************/attr =(env_attribute *)malloc(sizeof(env_attribute));last->next = attr;memset(attr, 0, sizeof(env_attribute));strcpy(attr->key,key);strcpy(attr->value,value);return 1;}else {return 0;}
}int save_bootenv() {int fd;int err;struct erase_info_user erase;struct mtd_info_user info;unsigned char *data = NULL;env_revert_attribute();*(env_data.crc) = crc32(0, (uint8_t *)env_data.data, ENV_SIZE);if ((fd = open (BootenvPartitionName, O_RDWR)) < 0) {ERROR("[ubootenv] open devices error\n");return -1;}if (strstr (BootenvPartitionName, "mtd")) {memset(&info, 0, sizeof(info));err = ioctl(fd, MEMGETINFO, &info);if (err < 0) {ERROR("[ubootenv] Get MTD info error\n");close(fd);return -4;}erase.start = 0;if (info.erasesize > ENV_PARTITIONS_SIZE) {data = (unsigned char*)malloc(info.erasesize);if (data == NULL) {ERROR("[ubootenv] Out of memory!!!\n");close(fd);return -5;}memset(data, 0, info.erasesize);err = read(fd, (void*)data, info.erasesize);if (err != (int)info.erasesize) {ERROR("[ubootenv] Read access failed !!!\n");free(data);close(fd);return -6;}memcpy(data, env_data.image, ENV_PARTITIONS_SIZE);erase.length = info.erasesize;}else {erase.length = ENV_PARTITIONS_SIZE;}err = ioctl (fd,MEMERASE,&erase);if (err < 0) {ERROR ("[ubootenv] MEMERASE ERROR %d\n",err);close(fd);return  -2;}if (info.erasesize > ENV_PARTITIONS_SIZE) {lseek(fd, 0L, SEEK_SET);err = write(fd , data, info.erasesize);free(data);}elseerr = write(fd ,env_data.image, ENV_PARTITIONS_SIZE);} else {//emmc and nand needn't eraseerr = write(fd ,env_data.image, ENV_PARTITIONS_SIZE);}FILE *fp = NULL;fp = fdopen(fd, "r+");if (fp == NULL) {ERROR("fdopen failed!\n");close(fd);return -3;}fflush(fp);fsync(fd);fclose(fp);if (err < 0) {ERROR ("[ubootenv] ERROR write, size %d \n", ENV_PARTITIONS_SIZE);return -3;}return 0;
}static int is_bootenv_varible(const char* prop_name) {if (!prop_name || !(*prop_name))return 0;if (!(*PROFIX_UBOOTENV_VAR))return 0;if (strncmp(prop_name, PROFIX_UBOOTENV_VAR, strlen(PROFIX_UBOOTENV_VAR)) == 0&& strlen(prop_name) > strlen(PROFIX_UBOOTENV_VAR) )return 1;return 0;
}static void bootenv_prop_init(const char *key, const char *value, void *cookie) {if (is_bootenv_varible(key)) {const char* varible_name = key + strlen(PROFIX_UBOOTENV_VAR);const char *varible_value = bootenv_get_value(varible_name);if (!varible_value)varible_value = "";if (strcmp(varible_value, value)) {property_set(key, varible_value);(*((int*)cookie))++;}}
}int bootenv_property_list(void (*propfn)(const char *key, const char *value, void *cookie),void *cookie) {char name[PROP_NAME_MAX];char value[PROP_VALUE_MAX];const prop_info *pi;unsigned n;for(n = 0; (pi = __system_property_find_nth(n)); n++) {__system_property_read(pi, name, value);propfn(name, value, cookie);}return 0;
}void bootenv_props_load() {int count = 0;bootenv_property_list(bootenv_prop_init, (void*)&count);char bootcmd[32];char val[PROP_VALUE_MAX]={0};sprintf(bootcmd, "%sbootcmd", PROFIX_UBOOTENV_VAR);property_get(bootcmd, val, "");if (val[0] == 0) {const char* value = bootenv_get_value("bootcmd");INFO("[ubootenv] key: [%s] value: [%s]\n", bootcmd, value);if (value) {property_set(bootcmd, value);count++;}}INFO("[ubootenv] set property count: %d\n", count);ENT_INIT_DONE = 1;
}int bootenv_init(void) {struct stat st;struct mtd_info_user info;int err;int fd;int ret = -1;int i = 0;int count = 0;/*int id = mtd_name_to_number("ubootenv");if (id >= 0) {sprintf(BootenvPartitionName, "/dev/mtd/mtd%d", id);if ((fd = open (BootenvPartitionName, O_RDWR)) < 0) {ERROR("open device(%s) error : %s \n",BootenvPartitionName,strerror(errno) );return -2;}memset(&info, 0, sizeof(info));err = ioctl(fd, MEMGETINFO, &info);if (err < 0) {ERROR("get MTD info error\n");close(fd);return -3;}ENV_EASER_SIZE = info.erasesize;ENV_PARTITIONS_SIZE = info.size;ENV_SIZE = ENV_PARTITIONS_SIZE - sizeof(long);} else */if (!stat("/dev/nand_env", &st)) {sprintf (BootenvPartitionName, "/dev/nand_env");ENV_PARTITIONS_SIZE = 0x10000;
#if defined(MESON8_ENVSIZE) || defined(GXBABY_ENVSIZE) || defined(GXTVBB_ENVSIZE) || defined(GXL_ENVSIZE)ENV_PARTITIONS_SIZE = 0x10000;
#endifENV_SIZE = ENV_PARTITIONS_SIZE - sizeof(uint32_t);INFO("[ubootenv] using /dev/nand_env with size(%d)(%d)", ENV_PARTITIONS_SIZE,ENV_SIZE);} else if (!stat("/dev/block/env", &st)) {INFO("[ubootenv] stat /dev/block/env OK\n");sprintf (BootenvPartitionName, "/dev/block/env");ENV_PARTITIONS_SIZE = 0x10000;
#if defined(MESON8_ENVSIZE) || defined(GXBABY_ENVSIZE) || defined(GXTVBB_ENVSIZE) || defined(GXL_ENVSIZE)ENV_PARTITIONS_SIZE = 0x10000;
#endifENV_SIZE = ENV_PARTITIONS_SIZE - sizeof(uint32_t);INFO("[ubootenv] using /dev/block/env with size(%d)(%d)", ENV_PARTITIONS_SIZE,ENV_SIZE);} else if (!stat("/dev/block/ubootenv", &st)) {sprintf(BootenvPartitionName, "/dev/block/ubootenv");if ((fd = open(BootenvPartitionName, O_RDWR)) < 0) {ERROR("[ubootenv] open device(%s) error\n",BootenvPartitionName );return -2;}memset(&info, 0, sizeof(info));err = ioctl(fd, MEMGETINFO, &info);if (err < 0) {fprintf (stderr,"get MTD info error\n");close(fd);return -3;}ENV_EASER_SIZE  = info.erasesize;//0x20000;//128KENV_PARTITIONS_SIZE = info.size;//0x8000;ENV_SIZE = ENV_PARTITIONS_SIZE - sizeof(long);}while (i < MAX_UBOOT_RWRETRY && ret < 0) {i ++;ret = read_bootenv();if (ret < 0)ERROR("[ubootenv] Cannot read %s: %d.\n", BootenvPartitionName, ret);if (ret < -2)free(env_data.image);}if (i >= MAX_UBOOT_RWRETRY) {ERROR("[ubootenv] read %s failed \n", BootenvPartitionName);return -2;}char prefix[PROP_VALUE_MAX] = {0};property_get("ro.ubootenv.varible.prefix", prefix, "");if (prefix[0] == 0) {strcpy(prefix , "ubootenv.var");INFO("[ubootenv] set property ro.ubootenv.varible.prefix: %s\n", prefix);property_set("ro.ubootenv.varible.prefix", prefix);}if (strlen(prefix) > 16) {ERROR("[ubootenv] Cannot r/w ubootenv varibles - prefix length > 16.\n");return -4;}sprintf(PROFIX_UBOOTENV_VAR, "%s.", prefix);INFO("[ubootenv] ubootenv varible prefix is: %s\n", prefix);#if 0property_list(init_bootenv_prop, (void*)&count);char bootcmd[32];char val[PROP_VALUE_MAX]={0};sprintf(bootcmd, "%s.bootcmd", prefix);property_get(bootcmd, val);if (val[0] == 0) {const char* value = bootenv_get_value("bootcmd");INFO("value: %s\n", value);if (value) {property_set(bootcmd, value);count ++;}}INFO("Get %d varibles from %s succeed!\n", count, BootenvPartitionName);
#endifbootenv_props_load();return 0;
}int bootenv_reinit(void) {mutex_lock(&env_lock);if (env_data.image) {free(env_data.image);env_data.image = NULL;env_data.crc = NULL;env_data.data = NULL;}env_attribute * pAttr = env_attribute_header.next;memset(&env_attribute_header, 0, sizeof(env_attribute));env_attribute * pTmp = NULL;while (pAttr) {pTmp = pAttr;pAttr = pAttr->next;free(pTmp);}bootenv_init();mutex_unlock(&env_lock);return 0;
}int bootenv_update(const char* name, const char* value) {if (!ENT_INIT_DONE) {ERROR("[ubootenv] bootenv do not init\n");return -1;}INFO("[ubootenv] update_bootenv_varible name [%s]: value [%s] \n",name,value);const char* varible_name = 0;if (strcmp(name, "ubootenv.var.bootcmd") == 0) {varible_name = "bootcmd";} else {if (!is_bootenv_varible(name)) {//should assert here.ERROR("[ubootenv] %s is not a ubootenv varible.\n", name);return -2;}varible_name = name + strlen(PROFIX_UBOOTENV_VAR);}const char *varible_value = bootenv_get_value(varible_name);if (!varible_value)varible_value = "";if (!strcmp(value, varible_value))return 0;bootenv_set_value(varible_name, value, 1);int i = 0;int ret = -1;while (i < MAX_UBOOT_RWRETRY && ret < 0) {i ++;ret = save_bootenv();if (ret < 0)ERROR("[ubootenv] Cannot write %s: %d.\n", BootenvPartitionName, ret);}if (i < MAX_UBOOT_RWRETRY) {INFO("[ubootenv] Save ubootenv to %s succeed!\n",  BootenvPartitionName);}#if BOOT_ARGS_CHECKNOTICE( "[ubootenv] E03LOG ----update_bootenv_varible %s = %s \n" , name , value );if (strcmp(name, ARGS_ETHADDR_WHOLE) == 0 ||strcmp(name, ARGS_LICENCE_WHOLE) == 0 ||strcmp(name, ARGS_DEVICE_ID_HOLE) == 0 ){char * p_ethaddr = bootenv_get_value(ARGS_ETHADDR) ;char * p_licence = bootenv_get_value(ARGS_LICENCE);char * p_device_id = bootenv_get_value(ARGS_DEVICE_ID) ;NOTICE( "[ubootenv] E03LOG ----update_bootenv_varible write_args_to_file   \n");if ( NULL != p_ethaddr && NULL != p_licence && NULL != p_device_id )write_args_to_file();}
#endifreturn ret;
}const char * bootenv_get(const char * key) {if (!is_bootenv_varible(key)) {//should assert here.ERROR("[ubootenv] %s is not a ubootenv varible.\n", key);return NULL;}const char* varible_name = key + strlen(PROFIX_UBOOTENV_VAR);return bootenv_get_value(varible_name);
}#if BOOT_ARGS_CHECKchar mac_address[20] = {0};
char licence[36] = {0};
char device_id[42] = {0};
#define BURN_ARGS_SIZE  128
#define BURN_ARGS_FILENAME "/param/burn_args.arg"
#define ARGS_ETHADDR "ethaddr"
#define ARGS_ETHADDR_WHOLE "ubootenv.var.ethaddr"
#define ARGS_LICENCE "igrsid"
#define ARGS_LICENCE_WHOLE "ubootenv.var.igrsid"
#define ARGS_DEVICE_ID "huanid"
#define ARGS_DEVICE_ID_HOLE "ubootenv.var.huanid"typedef struct burn_args {uint32_t crc; /* CRC32 over data bytes */unsigned char data[BURN_ARGS_SIZE]; /* Environment data */
} burn_t;static struct burn_args  burn_args_data ;int read_args_from_file() {char *data ;uint32_t crc_calc;char * write_buff = mac_address ;int file_size = 0 , read_pos = 0 , write_pos = 0 ;data = read_file( BURN_ARGS_FILENAME , &file_size);if (!data) {NOTICE( "[ubootenv] E03LOG %s failed!\n" , BURN_ARGS_FILENAME );return -1;}else {NOTICE( "[ubootenv] E03LOG read_default_boot_args success size: [%d]  burn_args_data size : [%d] ;  %s \n" , file_size , sizeof(burn_args_data) , data );if ( file_size > sizeof(burn_args_data) ) {NOTICE( "[ubootenv] E03LOG file size :[%d] > burn_args_data size: [%d] \n" , file_size , sizeof(burn_args_data) );//return -3 ;}memset((void*)&burn_args_data,0,sizeof(burn_args_data));memcpy( (void *)&burn_args_data , data , sizeof(burn_args_data) );crc_calc = crc32 (0,burn_args_data.data, BURN_ARGS_SIZE);if (crc_calc != burn_args_data.crc) {NOTICE( "[ubootenv] E03LOG check args failed! file crs32:[%d]  ,  real crs32:[%d]\n" , burn_args_data.crc , crc_calc );return -2 ;}else {NOTICE( "[ubootenv] E03LOG check args accordant ! file crs32:[%d]  ,  real crs32:[%d]\n" , burn_args_data.crc , crc_calc );}}for ( read_pos = 0 ; read_pos < file_size ; read_pos++ ) {if ( 0x0A == burn_args_data.data[read_pos] ) {if ( write_buff == mac_address ) {NOTICE( "[ubootenv] E03LOG mac of file %s \n" , write_buff  );write_buff = licence ;}else if ( write_buff == licence ) {NOTICE( "[ubootenv] E03LOG licence of file %s \n" , write_buff  );write_buff = device_id ;}else {NOTICE( "[ubootenv] E03LOG device_id of file %s \n" , write_buff  );break;}write_pos = 0 ;continue ;}write_buff[write_pos] = burn_args_data.data[read_pos] ;write_pos++ ;}return 0;
}int write_args_to_file() {int fd;int err;if ((fd = open (BURN_ARGS_FILENAME, O_RDWR| O_CREAT )) < 0) {NOTICE( "[ubootenv] E03LOG ----open devices error\n");return -1;}if (lseek(fd, 0, SEEK_SET) != 0) {NOTICE( "[ubootenv] E03LOG lseek ERROR %d\n",err);}memset((void*)&burn_args_data,0,sizeof(burn_args_data));sprintf( burn_args_data.data , "%s\n%s\n%s\n", bootenv_get_value(ARGS_ETHADDR),bootenv_get_value(ARGS_LICENCE),bootenv_get_value(ARGS_DEVICE_ID)) ;burn_args_data.crc = crc32 (0,burn_args_data.data, BURN_ARGS_SIZE);NOTICE( "[ubootenv] E03LOG  write args crc: [%d]   \n %s \n " , burn_args_data.crc , burn_args_data.data ) ;err = write(fd ,(void *)&burn_args_data, sizeof(burn_args_data));close(fd);if (err < 0) {NOTICE( "[ubootenv] E03LOG write args----ERROR  write, size %d \n",err);return -3;}else {NOTICE( "[ubootenv] E03LOG write args----success , size %d \n",err);}return 0 ;
}void check_boot_args() {int ret = read_args_from_file();char * p_ethaddr = bootenv_get_value(ARGS_ETHADDR) ;char * p_licence = bootenv_get_value(ARGS_LICENCE);char * p_device_id = bootenv_get_value(ARGS_DEVICE_ID) ;if ( 0 != ret ) {if ( NULL != p_ethaddr && NULL != p_licence && NULL != p_device_id )write_args_to_file();NOTICE( "[ubootenv] E03LOG read args from file failed . write boot args to file \n" ) ;return ;}if ( NULL == p_ethaddr || 0 != strcmp( mac_address ,  p_ethaddr )) {NOTICE( "[ubootenv] E03LOG check mac address failed . file: %s  boot: %s \n" , mac_address ,  bootenv_get_value(ARGS_ETHADDR)  ) ;update_bootenv_varible( ARGS_ETHADDR_WHOLE, mac_address );}else {NOTICE( "[ubootenv] E03LOG check mac address accordant . file: %s  boot: %s \n" , mac_address ,  bootenv_get_value(ARGS_ETHADDR)  ) ;}if ( NULL == p_licence || 0 != strcmp( licence,  p_licence )) {NOTICE( "[ubootenv] E03LOG check licence failed . file: %s  boot: %s \n" , licence ,  bootenv_get_value(ARGS_LICENCE)  ) ;update_bootenv_varible( ARGS_LICENCE_WHOLE, licence );}else {NOTICE( "[ubootenv] E03LOG check licence accordant . file: %s  boot: %s \n" , licence ,  bootenv_get_value(ARGS_LICENCE)  ) ;}if ( NULL == p_device_id || 0 != strcmp( device_id,  p_device_id  ) ) {NOTICE( "[ubootenv] E03LOG check device_id failed . file: %s  boot: %s \n" , device_id ,  bootenv_get_value(ARGS_DEVICE_ID)  ) ;update_bootenv_varible( ARGS_DEVICE_ID_HOLE, device_id );}else {NOTICE( "[ubootenv] E03LOG check device_id accordant . file: %s  boot: %s \n" , device_id ,  bootenv_get_value(ARGS_DEVICE_ID)  ) ;}
}#endif
#ifndef _INIT_BOOTENV_H
#define _INIT_BOOTENV_H#ifdef __cplusplus
extern "C" {#endif#define MAX_UBOOT_RWRETRY       5typedef  struct env_image {uint32_t  crc;            /* CRC32 over data bytes    */char data[];              /* Environment data     */
} env_image_t;typedef struct environment {void          *image;uint32_t     *crc;char           *data;
}environment_t;typedef struct env_attribute {struct env_attribute *next;char key[256];char value[1024];
}env_attribute;int bootenv_init();
int bootenv_reinit();
const char * bootenv_get(const char * key);
int bootenv_update(const char* name, const char* value);
void bootenv_print(void);env_attribute *bootenv_get_attr(void);#if BOOT_ARGS_CHECK
void    check_boot_args();
#endif#ifdef __cplusplus
}
#endif
#endif

使用

# envtool
argc num = 1
useage: envtool r [name] envtool w [name] [value]
envtool w factory_test on
ubootenv init successful.(0)
ubootenv init successful.(0)
envtool r factory_test
ubootenv init successful.(0)
ubootenv init successful.(0)
on

实战-Android 系统读取Uboot环境变量实现相关推荐

  1. uboot环境变量实现分析

    u-boot的环境变量用来存储一些经常使用的参数变量,uboot希望将环境变量存储在静态存储器中(如nand nor eeprom mmc). 其中有一些也是大家经常使用,有一些是使用人员自己定义的, ...

  2. linux怎么查看系统环境变量路径,Linux系统中的环境变量该如何设置与查看

    今天小编要跟大家分享的文章是关于Linux系统中的环境变量该如何设置与查看.大家都知道,在 Linux 系统中,有环境变量和 Shell 变量这两种变量. 环境变量是在程序及其子程序中全局可用的,常常 ...

  3. xp java配置_WinXP系统Java配置环境变量的方法

    谈起Java环境变量我想大多数编程人员都知道,因为我们想要进行编程就必须先配置它,不过不少用户不知道WinXP系统Java怎么配置环境变量,为此小编赶紧整理了一篇WinXP系统Java配置环境变量的方 ...

  4. linux系统中变量,Linux系统中的环境变量知识详解

    对于没有使用过linux系统的用户来说,有很多术语和功能都很陌生.本文就介绍了linux系统中的环境变量的相关知识,具体内容如下所述. linux是一个多用户的操作系统.每个用户登录系统后,都会有一个 ...

  5. 苹果电脑上使用linux环境变量,mac系统下修改环境变量

    苹果电脑使用率越来越高,在mac系统下研发,性能要比在windows下快不少,既然要开发,免不了要配置环境变量.下面是学习啦小编收集整理的mac系统下修改环境变量,希望对大家有帮助~~ mac系统下修 ...

  6. uboot环境变量及常用命令

    U-Boot环境变量的解释说明 环 境 变 量 解 释 说 明 bootdelay 定义执行自动启动的等候秒数 baudrate 定义串口控制台的波特率 netmask 定义以太网接口的掩码 etha ...

  7. Android 系统(112)---Android系统读取 CPU温度(MTK平台)

    Android系统读取 CPU温度(MTK平台) 一.[MTK 平台]读取温度命令 1.查看类型是否是 CPU adb shell "cat /sys/class/thermal/therm ...

  8. Java系统属性和环境变量

    1 什么是环境变量 境变量分为系统环境变量和用户环境变量. 所说的环境变量是指系统环境变量,对所有用户起作用,而用户环境变量只对当前用户起作用. 例如要用java,那么把java的bin目录加入到pa ...

  9. uboot 修改linux密码,Linux下设置u-boot环境变量----fw_setenv

    打印uboot环境变量: fw_printenv [[ -n name ] | [ name ... ]] # ./fw_printenv -n baudrate 如果不指定name,fw_print ...

最新文章

  1. 评价对象检测模型的数字度量:F1分数以及它们如何帮助评估模型的表现
  2. VMware中安装CentOS7网络配置静态IP地址,常用配置和工具安装
  3. http协议、cookie及session
  4. C#的循环语句(一)
  5. AngularJS select中ngOptions用法详解
  6. html中超链接使用_HTML实例源码
  7. 香辣弹簧:自动接线的不同方法
  8. Lucas定理及组合数取模
  9. 测视力距离5米还是3米_视力表只能看到0.3,相当于近视度数200度?
  10. java 无符号整数_如何在java 8中使用无符号整数?
  11. 2021年API攻击数量激增600%+
  12. 写一个模拟彩票中奖的程序及彩票分析
  13. inventor牙距_滚子链计算基础知识 | Inventor 2018 | Autodesk Knowledge Network
  14. 这一篇彻底说清楚了!乐高,编程,机器人到底要不要学?
  15. 记一次https的免费ssl证书安装及配置过程--window系统
  16. 如何用一根网线连接两台电脑,传输大文件
  17. matlab绿色 不伤眼,什么颜色的灯光最伤眼睛不看后悔啊
  18. Latest for Mac 0.7.3 应用更新管理器
  19. 四大名著红楼梦第一回 甄士隐梦幻识通灵 贾雨村风尘怀闺秀
  20. 海德也离开了,祝你一路顺风。

热门文章

  1. Acer宏基笔记本电脑捕食者Predator PH317-55原装出厂Windows10系统恢复原厂OEM系统
  2. 经过离散点画平滑曲线(贝塞尔3次)
  3. UEFI标准应用程序模块--SMBIOS的读写
  4. 水面渲染-浮力的一种实现
  5. ECharts: 绘制立体柱状图【圆柱体】
  6. http POST请求键值对参数以及json参数
  7. 人工神经网络课后题答案,人工神经网络原理答案
  8. DFS——组合与排列
  9. HHDBCS及HHDESK的资源加密功能
  10. matlab 开4次方根,matlab中计算四次方方程a*x^4+b*x+c=0的实数根.