在Linux里读取UBOOT环境变量


在Linux里读取UBOOT环境变量

转载:http://falloutmx.blog.163.com/blog/static/39236020201211145010154/

 

可以通过mtd方式读取,也可以用ioremap方式。不过这些都比较麻烦,简单的方法有两种,一种是mtd_debug,另一种是fw_printenv。前者是一个软件包,需要单独下载安装。后一个就是我目前使用的方式,是Uboot带的一个工具,使用方法如下:

1、编译fw_printenv工具
在你uboot目录下用以下编译指令:
make env
成功后在tools/env下会生成fw_printenv,如果提示缺少mtd-user.h文件,从系统中拷贝过来即可:
cp /usr/include/mtd/ ./include/mtd -a

2、修改配置文件
根据mtd分区、UBOOT环境变量的位置、大小等内容修改tools/env下的fw_env.config文件,可参见/tools/env/README文件。
这 个工具还需要一个配置文件,以获取uboot的ENV区域的位置信息。默认状态下,请将fw_env.config文件拷贝到目标机的文件系统的/etc 目录下。然后结合uboot配置中定义的ENV区和Linux下mtd分区的情况修改配置文件。具体的修改方法见fw_env.config文件中的说明 及/tools/env/README文件。

3、使用fw_printenv工具

将编译好的fw_printenv拷贝到目标机的文件系统中,并将fw_env.config文件拷贝到目标机的文件系统的/etc 目录下。执行fw_printenv即可打印Uboot环境变量信息,如果没打印出来或者打印乱码,请检查配置文件是否正确

 
转载:http://labs.isee.biz/index.php/How_to_modify_the_uboot_environment_from_userspace
 

How to modify the uboot environment from userspace

Contents

[hide]

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  name
mtd0: 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-0
distro=poky
project=poky-image-sato
ipaddr=192.168.254.254
netmask=255.255.255.0
gatewayip=192.168.254.10
serverip=192.168.254.10
addip=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; fi
onenand-bootargs=setenv bootargs ${bootargs-base} root=/dev/mtdblock4 rootfstype=jffs2 ; run addip
onenand-boot=run onenand-bootargs; onenand read 80000000 280000 400000 ; bootm 80000000
nfs-bootargs=setenv bootargs ${bootargs-base} root=/dev/nfs nfsroot=${serverip}:/srv/nfs/${distro}/${project}/${machine} ; run addip
nfs-boot=if ping ${serverip}; then run nfs-bootargs; tftp 0x80000000 ${distro}/${project}/${machine}/uImage; bootm; fi;
machine=igep0020
mmc-bootargs=setenv bootargs ${bootargs-base} root=/dev/mmcblk0p2 rw rootwait dieid=${dieid#}
dieid#=638a00040000000004036abc07016018
mpurate=110
stdin=serial
stdout=serial
stderr=serial
bootargs-base=mem=512M console=ttyS2,115200n8 console=tty0 omapfb.mode=dvi:1024x768MR-16@60 mpurate=110
bootcmd=run onenand-boot; run mmc-boot;

if you get something like:

Warning: Bad CRC, using default environment
bootcmd=bootp; setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; bootm
bootdelay=5
baudrate=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!!


 

转载:http://www.denx.de/wiki/DULG/HowCanIAccessUBootEnvironmentVariablesInLinux

 

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 MTD 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 MTD 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/setenv) utility.
# Up to two entries are valid, in this case the redundant
# 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




转载:http://blog.csdn.net/hangbing0203/article/details/4314576

 

u-boot在线更新

需编译mtd-utils,编译fw_printenv、fw_setenv, 和修改内核



1.编译mtd-utils

将编译的flash_eraseall、flashcp拷贝到/nfsroot/cq8401/sbin中



然后用命令

flash_eraseall /dev/mtd1 刷bootloader分区

用命令

flashcp /bootloader/u-boot.bin.336new  /dev/mtd1  将新的u-boot写入u-boot分区



2.编译fw_printenv和fw_setenv

进入u-boot-1.1.3/

vi tools/env/Makefile

加入

CROSS_COMPILE = mipsel-linux-

make -C tools/env all

cp  tools/env/fw_printenv  /nfsroot/cq8401/sbin

cd /nfsroot/cq8401/sbin

ln -sf fw_printenv fw_setenv

cp -av u-boot-1.1.3/tools/env/fw_env.config /nfsroot/cq8401/etc



问题汇总:

问题1: 

fw_env.c:34:27: 错误:linux/mtd/mtd.h:没有那个文件或目录

fw_env.c: 在函数‘fw_printenv’中:

fw_env.c:244: 警告:初始化指针时目标与指针符号不一致

fw_env.c:259: 警告:传递‘fputs’的参数 1 给指针时,目标与指针符号不一致

fw_env.c:262: 警告:传递‘puts’的参数 1 给指针时,目标与指针符号不一致

fw_env.c: 在函数‘fw_setenv’中:

fw_env.c:293: 警告:对指针赋值时目标与指针符号不一致

fw_env.c:317: 警告:传递‘strcmp’的参数 1 给指针时,目标与指针符号不一致

fw_env.c:318: 警告:传递‘strcmp’的参数 1 给指针时,目标与指针符号不一致

fw_env.c:350: 警告:传递‘strlen’的参数 1 给指针时,目标与指针符号不一致

fw_env.c:364: 警告:初始化指针时目标与指针符号不一致

fw_env.c: 在函数‘flash_io’中:

fw_env.c:390: 错误:‘erase_info_t’未声明(在此函数内第一次使用)

fw_env.c:390: 错误:(即使在一个函数内多次出现,每个未声明的标识符在其

fw_env.c:390: 错误:所在的函数内也只报告一次。)

fw_env.c:390: 错误:expected ‘;’ before ‘erase’

fw_env.c:393: 警告:传递‘open’的参数 1 给指针时,目标与指针符号不一致

fw_env.c:409: 警告:传递‘open’的参数 1 给指针时,目标与指针符号不一致

fw_env.c:421: 错误:‘erase’未声明(在此函数内第一次使用)

fw_env.c:423: 错误:‘MEMUNLOCK’未声明(在此函数内第一次使用)

fw_env.c:462: 错误:‘MEMERASE’未声明(在此函数内第一次使用)

fw_env.c:519: 错误:‘MEMLOCK’未声明(在此函数内第一次使用)

fw_env.c: 在函数‘parse_config’中:

fw_env.c:719: 警告:传递‘stat’的参数 1 给指针时,目标与指针符号不一致

fw_env.c:726: 警告:传递‘stat’的参数 1 给指针时,目标与指针符号不一致

make: *** [fw_printenv] 错误 1



解决办法:

在tools/env/Makefile

加入CROSS_COMPILE = mipsel-linux-



问题2:

Cannot parse config file: No such file or directory

解决办法:

在/etc下创建fw_env.config文件



问题3:

Cannot parse config file: Invalid argument

解决办法:

修改文件权限

问题4:

Bus error

解决办法:

echo "/dev/mtd2       0x0000      0x20000      0x20000" > /etc/fw_env.config



问题5:

Warning: Bad CRC, using default environment

问题6:

Error: can't write fw_env to flash

5和6解决办法:

将Env. size 和 Flash sector size改为arch/mips/cq8401/com/setup.c中

所设定的值。



fw_env.config文件的内容

# Configuration file for fw_(printenv/saveenv) utility.

# Up to two entries are valid, in this case the redundand

# environment sector is assumed present.



# MTD device name   Device offset   Env. size   Flash sector size

/dev/mtd2       0x0000      0x20000     0x20000





3.内核的修改

设置分区:

将arch/mips/cq8401/com/setup.c修改为以下,可以直接刷bootloader分区而不会将u-boot的配置空间擦除掉

static struct mtd_partition cq8401_mtd_parts[] = {

    {

            .name =     "ROOTFS",

            .size =     0xC00000,

            .offset =   0,

            .mask_flags =   0,

    },

    {

            .name =     "BOOTLOADER",

            .size =     0x40000,

            .offset =   MTDPART_OFS_APPEND,

            //.mask_flags =   MTD_WRITEABLE,  /* force read-only */

            .mask_flags =  0,

    },

    {

            .name =     "uboot_env",

            .size =     0x20000,

            .offset =   MTDPART_OFS_APPEND,

            .mask_flags =  0,

    },



    {

            .name =     "KERNEL",

            .size =     MTDPART_SIZ_FULL,

            .offset =   MTDPART_OFS_APPEND,

            .mask_flags =   0,

    }





进入系统可用

cat /proc/mtd   

查看分区设置

根据uboot的配置空间的设备节点设置/etc/fw_env.config中的第一项MTD device name,根据其偏移地址设值Device offset,根据空间大小设置Env. size ,根据闪存扇区大小设置Flash sector size









如果需要保存和恢复uboot的配置空间,用以下命令:

dd if=/dev/mtd2 of=env.bin 将配置空间的内容保存为文件env.bin

dd if=env.bin of=/dev/mtd2 将配置文件env.bin写回配置空间

如果需要读出配置空间的内容,使用以下命令:

fw_printenv

如果需要单独修改uboot的参数,使用以下命令:

fw_setenv bootdelay 5



u-boot更新脚本

#! /bin/sh

echo "##########################################"

echo "Save uboot_env  space"

dd if=/dev/mtd2 of=env.bin

echo "Erasure bootloader"

flash_eraseall /dev/mtd1

echo "Erasure uboot_env space"

flash_eraseall /dev/mtd2

echo "Ersure kernel "

flash_eraseall /dev/mtd3

echo "##########################################"

echo "Write new bootloader"

flashcp /bootloader/u-boot.bin.336new  /dev/mtd1

echo "Update u-boot completed"

echo "Write new kernel"

flashcp /bootloader/uImage /dev/mtd3

echo "Update kernel completed"

echo "Write uboot coonfig"

dd if=env.bin of=/dev/mtd2 

echo "UPDATE completed"

echo "##########################################"
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PetaLinux是一个基于Yocto Project的嵌入式Linux开发工具,可用于构建自定义Linux发行版。在PetaLinux中,uboot是用于启动Linux内核的引导加载程序。在uboot中,环境变量是一些可以配置uboot行为的参数。 要将uboot环境变量保存到SD卡中,可以按照以下步骤进行: 1. 在PetaLinux项目中的uboot代码目录下,找到`include/configs`文件夹,其中包含了与硬件平台相关的uboot配置文件。 2. 打开对应的配置文件,例如`zynq_common.h`。 3. 在配置文件中,找到`#define CONFIG_ENV_IS_IN`宏定义。该宏定义指定了uboot环境变量的存储位置,默认为“nand”或“nor”等闪存设备。 4. 修改`#define CONFIG_ENV_IS_IN`宏定义为`"sd"`,指定uboot环境变量存储在SD卡中。 5. 在配置文件中,找到`#define CONFIG_ENV_OFFSET`宏定义。该宏定义指定了uboot环境变量在存储设备中的偏移地址。 6. 修改`#define CONFIG_ENV_OFFSET`宏定义为SD卡中的偏移地址,例如`0x100000`。 7. 保存并关闭配置文件。 8. 在uboot代码目录下执行`make clean`命令来清理之前的编译结果。 9. 执行`make`命令重新编译uboot。 10. 将生成的uboot二进制文件烧录到SD卡的启动区域。 11. 将SD卡插入目标设备中,启动设备。 12. 在uboot启动时,可以使用命令`printenv`来验证uboot环境变量是否成功保存在SD卡中。 通过以上步骤,你可以将uboot环境变量保存到SD卡中。这样,在使用SD卡启动设备时,uboot可以从SD卡读取环境变量并进行相应的配置。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值