博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
How to modify the uboot environment from userspace
阅读量:2022 次
发布时间:2019-04-28

本文共 10758 字,大约阅读时间需要 35 分钟。

Overview

This How-To is meant to be a starting point for people to learn how access to the uboot environment from userspace.

This is my first wiki page so please be benevolent with the formatting :-)

Tools needed

In order to modify the uboot environment variables from userspace we will need a program called fw_setenv, we can compile this program ourselves from the u-boot sources, follow the instructions in this wiki page and then proceed to compile with (don't modify the .h file as it says in the tools/env/README file):

make env

This will give us fw_printenv, in order to get fw_setenv we just have to change the name of the file. Magic!!

cp fw_printenv fw_setenv

The next thing we will need is the fw_env.config file with the appropiate settings for our board. Here comes the confusion :-)

In this file you have to specify:

  1. MTD device name
  2. Device Offset
  3. Environment Size
  4. Flash sector size
  5. Number of sectors (ignored in NOR)

Finding out the correct values for fw_env.config

Ok, so in order to get all this information the easyest thing is to read it from dmesg or from /proc/mtd

cat /proc/mtd

All my initial confusion comes from using an incorrect kernel, my first tries where with 2.6.28.10 and the driver used to read mtd was NAND, in the kernel configuration file I only had :

CONFIG_MTD_NAND=y

being the output of /proc/mtd:

dev:    size   erasesize  name mtd0: 00080000 00040000 "X-Loader"mtd1: 001e0000 00040000 "U-Boot"mtd2: 00020000 00040000 "U-Boot Env"mtd3: 00500000 00040000 "Kernel"mtd4: 1f880000 00040000 "File System"

through "dmesg" I could see this line indicating something was wrong:

[ 1174.517120] Creating 5 MTD partitions on "omap2-onenand":[ 1174.522552] 0x00000000-0x00080000 : "X-Loader"[ 1174.528381] 0x00080000-0x00260000 : "U-Boot"[ 1174.533508] 0x00260000-0x00280000 : "U-Boot Env"[ 1174.538177] mtd: partition "U-Boot Env" doesn't start on an erase block boundary -- force read-only[ 1174.548126] 0x00280000-0x00780000 : "Kernel"[ 1174.553192] 0x00780000-0x20000000 : "File System"

But if we use the aproppiate kernel, in my case 2.6.33.7-0 with the onenand driver instead of the nand driver:

CONFIG_MTD_ONENAND=y

The output of /proc/mtd is different:

dev:    size   erasesize  namemtd0: 00080000 00040000 "X-Loader"mtd1: 00180000 00040000 "U-Boot"mtd2: 00080000 00040000 "Environment"mtd3: 00300000 00040000 "Kernel"mtd4: 1fa80000 00040000 "File System"

Now we can fill in all the values we needed (that's what I thought)

  1. MTD device name ---> /dev/mtd2 ("u-boot environment")
  2. Device Offset ----> 80.000 + 18.000
  3. Environment Size ---> 80.000
  4. Flash sector size ---> 40.000
  5. Number of sectors (ignored in NOR)----> nothing

Pretty easy right? wrong!!! The right values are:

  1. MTD device name ----> /dev/mtd2
  2. Device Offset -----> 0x0000
  3. Environment Size -----> 0x01000
  4. Flash sector size ------> 0x020000
  5. Number of sectors (ignored in NOR) -----> nothing

I figured these out by reading different posts and by trial and error, but I still don't understand the environment size value or the flash sector size, I can imagine the device offset is 0 if you specify /dev/mtd2 but I'd be great if someone could edit this page and point out why are this the correct values.

Giving it a try

In order to give it a try is better to poke with fw_printenv than with fw_setenv, because the first one just tries to read, so go ahead and try it:

fw_printenv

this should output something like:

ethact=smc911x-0distro=pokyproject=poky-image-satoipaddr=192.168.254.254netmask=255.255.255.0gatewayip=192.168.254.10serverip=192.168.254.10addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}::eth0:mmc-boot=mmc init 0; if fatload mmc 0 80000000 boot.ini; then source; else if fatload mmc 0 80000000 uImage; then run mmc-bootargs; bootm; fi; fionenand-bootargs=setenv bootargs ${bootargs-base} root=/dev/mtdblock4 rootfstype=jffs2 ; run addiponenand-boot=run onenand-bootargs; onenand read 80000000 280000 400000 ; bootm 80000000nfs-bootargs=setenv bootargs ${bootargs-base} root=/dev/nfs nfsroot=${serverip}:/srv/nfs/${distro}/${project}/${machine} ; run addipnfs-boot=if ping ${serverip}; then run nfs-bootargs; tftp 0x80000000 ${distro}/${project}/${machine}/uImage; bootm; fi;machine=igep0020mmc-bootargs=setenv bootargs ${bootargs-base} root=/dev/mmcblk0p2 rw rootwait dieid=${dieid#}dieid#=638a00040000000004036abc07016018mpurate=110stdin=serialstdout=serialstderr=serialbootargs-base=mem=512M console=ttyS2,115200n8 console=tty0 omapfb.mode=dvi:1024x768MR-16@60 mpurate=110bootcmd=run onenand-boot; run mmc-boot;

if you get something like:

Warning: Bad CRC, using default environmentbootcmd=bootp; setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; bootmbootdelay=5baudrate=115200

it means the values in /etc/fw_env.config are not correct, so don't even try fw_setenv

Using fw_setenv

Now that we found out the correct values for /etc/fw_env.config you can just use fw_setenv with the same syntax as if you were in u-boot command line, to assing a value don't use "=" but a space.

./fw_setenv test 1234

then fw_printenv should output

test=1234

notice we didn't need to use saveenv as we would do in u-boot command line.

That's it!!

Feedback and Contributing

Creating articles in the wiki is a collaborative process, at any point, if you see a mistake you can contribute to this article.

Please, use the discussion tab for user comments. This is useful to separate page content and the discussion thereof and also, if you don't want to give normal users the right to edit the page but still want user contributed notes.

Editing permissions are restricted to registered users.  and you will have single sign-on.

Consult the  for information on using the wiki software.

There is a set of .

References

Question:
I would like to access U-Boot's environment variables from my Linux application. Is this possible?

Answer:
Yes, you can. The environment variables must be stored in flash memory, and your Linux kernel must support flash access through the  layer. In the U-Boot source tree you can find the environment tools in the directory 
tools/env, which can be built with command:

make env

For building against older versions of the  headers (meaning before v2.6.8-rc1) it is required to pass the argument "MTD_VERSION=old" to make:

make MTD_VERSION=old env

The resulting binary is called fw_printenv, but actually includes support for setting environment variables too. To achieve this, the binary behaves according to the name it is invoked as, so you will have to create a link called fw_setenv to fw_printenv.

These tools work exactly like the U-Boot commands printenv resp. setenv You can either build these tools with a fixed configuration selected at compile time, or you can configure the tools using the /etc/fw_env.config configuration file in your target root filesystem. Here is an example configuration file:

# Configuration file for fw_(printenv/saveenv) utility.# Up to two entries are valid, in this case the redundand# environment sector is assumed present.########################################################################## For TQM8xxL modules:########################################################################## MTD device name       Device offset   Env. size       Flash sector size/dev/mtd0            0x8000          0x4000          0x4000/dev/mtd0            0xC000          0x4000          0x4000########################################################################## For NSCU:########################################################################## MTD device name       Device offset   Env. size       Flash sector size#/dev/mtd1              0x0000          0x8000          0x20000#/dev/mtd2              0x0000          0x8000          0x20000########################################################################## For LWMON########################################################################## MTD device name       Device offset   Env. size       Flash sector size#/dev/mtd1               0x0000          0x2000          0x40000

代码分析:

README:

This is a demo implementation of a Linux command line tool to access

the U-Boot's environment variables.

For the run-time utiltity configuration uncomment the line

#define CONFIG_FILE  "/etc/fw_env.config"
in fw_env.h.

这个有误,应该是用配置文件时,不要注释掉这个宏

See comments in the fw_env.config file for definitions for the

particular board.

Configuration can also be done via #defines in the fw_env.h file. The

following lines are relevant:

#define HAVE_REDUND    /* For systems with 2 env sectors */

#define DEVICE1_NAME    "/dev/mtd1"
#define DEVICE2_NAME    "/dev/mtd2"
#define DEVICE1_OFFSET    0x0000
#define ENV1_SIZE         0x4000
#define DEVICE1_ESIZE     0x4000
#define DEVICE2_OFFSET    0x0000
#define ENV2_SIZE         0x4000
#define DEVICE2_ESIZE     0x4000

Current configuration matches the environment layout of the TRAB

board.

HAVE_REDUND是用来环境变量备份用的

Un-define HAVE_REDUND, if you want to use the utlities on a system

that does not have support for redundant environment enabled.
If HAVE_REDUND is undefined, DEVICE2_NAME is ignored,
as is ENV2_SIZE and DEVICE2_ESIZE.

The DEVICEx_NAME constants define which MTD character devices are to

be used to access the environment.

The DEVICEx_OFFSET constants define the environment offset within the

MTD character device.

ENVx_SIZE defines the size in bytes taken by the environment, which

may be less then flash sector size, if the environment takes less
then 1 sector.

DEVICEx_ESIZE defines the size of the first sector in the flash

partition where the environment resides.

 

DEVICEx_NAME设备名

DEVICEx_OFFSET设备中环境变量的偏移

ENVx_SIZE 环境变量大小,可能比1sector小

 

查看环境变量大小:

pri查看

Environment size: 1560/4092 bytes

include/configs/mv_kv.h

#define CFG_ENV_SIZE        0x1000

所以大小是0x1000

查看环境变量偏移:

#define CFG_MONITOR_LEN            (512 << 10)    /* Reserve 512 kB for Monitor */   uboot镜像长度 0x80000 =512k

//uboot的基址和环境变量的基址

#define CFG_MONITOR_BASE        (CFG_FLASH_BASE)
#define CFG_ENV_ADDR            (CFG_MONITOR_BASE + CFG_MONITOR_LEN)     环境变量开始位置

#define CFG_ENV_SIZE        0x1000   //4k

环境变量从0x80000开始 到0x80000+0x1000

 

根据CFG_ENV_ADDR 知道环境变量偏移是0x80000

 

查看erasesize

/opt/qtmarvell/mvqt/tools # cat /proc/mtd 

dev:    size   erasesize  name
mtd0: 00100000 00010000 "uboot"
mtd1: 00700000 00010000 "linux-root"

 

编译fw_printenv:

下载u-boot-2011.03.tar.bz2

根目录下:

make env HOSTCC=arm-mv5sft-linux-gnueabi-gcc

ln -s fw_printenv fw_setenv

 

修改fw_env.config ,根据上面的信息:

/opt/qtmarvell/mvqt/tools # cat fw_env.config 

# Configuration file for fw_(printenv/saveenv) utility.
# Up to two entries are valid, in this case the redundant
# environment sector is assumed present.
# Notice, that the "Number of sectors" is ignored on NOR.

# MTD device name       Device offset   Env. size       Flash sector size       Number of sectors

/dev/mtd0               0x80000         0x1000          0x10000

转载地址:http://qsgxf.baihongyu.com/

你可能感兴趣的文章
bash 函数
查看>>
bash 算术运算符优先级
查看>>
bash 条件表达式
查看>>
bash简单命令扩展
查看>>
bash命令执行
查看>>
禅与摩托车维修艺术语录摘抄(1)
查看>>
bash 命令执行环境
查看>>
bash 环境
查看>>
bash 作业控制
查看>>
物理内存的管理
查看>>
高效能人士的七个习惯——由内而外全面造就自己
查看>>
为什么精英都是清单控(笔记)——工作清单
查看>>
怦然心动的人生整理魔法(笔记)——物品类别整理
查看>>
让人生发生戏剧性变化的整理魔法(笔记)
查看>>
怦然心动的人生整理魔法(笔记)
查看>>
什么是“怦然心动的感觉”
查看>>
按物品类别整理的心动收纳法(笔记)
查看>>
沟通的艺术(笔记)——前言
查看>>
有效沟通的基本原则(笔记)
查看>>
演讲、演讲人、听众
查看>>