加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

uboot环境变量

发布时间:2020-12-15 18:29:01 所属栏目:百科 来源:网络整理
导读:U-Boot环境变量的解释说明 环 境 变 量 解 释 说 明 bootdelay 定义执行自动启动的等候秒数 baudrate 定义串口控制台的波特率 netmask 定义以太网接口的掩码 ethaddr 定义以太网接口的MAC地址 bootfile 定义缺省的下载文件 bootargs 定义传递给Linux内核的命

U-Boot环境变量的解释说明
环 境 变 量
解 释 说 明
bootdelay
定义执行自动启动的等候秒数
baudrate
定义串口控制台的波特率
netmask
定义以太网接口的掩码
ethaddr
定义以太网接口的MAC地址
bootfile
定义缺省的下载文件
bootargs
定义传递给Linux内核的命令行参数
bootcmd
定义自动启动时执行的几条命令
serverip
定义tftp服务器端的IP地址
ipaddr
定义本地的IP地址
stdin
定义标准输入设备,一般是串口
stdout
定义标准输出设备,一般是串口
stderr
定义标准出错信息输出设备,一般是串口

Uboot相关命令介绍
printenv 查看环境变量
setenv 添加,修改,删除环境变量
例 setenv aaa 123 //添加环境变量aaa其值为123
setenv aaa 789 //在上行变量基础上把aaa的值修改(重设)为789
setenv aaa //把aaa变量删除

saveenv 保存环境变量
flinfo 查看flash信息
bdinfo 查看开发板信息
查看和修改内存值的指令(可以查看和修改SDRAM和寄存器值)
[.b,.w,.l]代表了查看和修改形式:bit、word、long
md 查看内存
参数 md.b [address] //按字节显示
md.w [address] //按字显示
md.l [address] //按长字显示

nm 修改内存值 (指定地址)
参数 nm.b [address] //按字节显示
nm.w [address] //按字显示
nm.l [address] //按长字显示

mm 内存修改,地址自动递增
参数 mm.b [address] //按字节显示
mm.w [address] //按字显示
mm.l [address] //按长字显示

mw 用指定的数据填充内存
参数 mw.b [address value ] //按字节显示
mw.w [address value ] //按字显示
mw.l [address value ] //按长字显示

cp 内存的拷贝(包括内存与Nor Flash间的数据拷贝)
参数 cp.b [source target count] //按字节显示
cp.w [source target count] //按字显示
cp.l [source target count] //按长字显示

例 cp source dest len

protect 扇区写保护(对Flash 写保护)

protect on all 保护全开
protect off all 保护解除

protect on start end //start end是照起始地址和结束地址定义范围,
protect off start end //start是保护块的起始地址;
//end 是保护末尾块的结束地址。
例如:保护Sector 2和Sector 3区域命令为protect 20000 3ffff

protect on start +size //start +size是照起始地址和操作字节数定义范围
protect off start +size //start是保护块的起始地址;
//size 是保护的字节数。
例如:保护Sector 2和Sector 3区域命令为protect 20000 +20000

protect on N:SF[-SL]
protect off N:SF[-SL]
//N:SF[-SL]是按照组和扇区,N 表示Flash 的Block号,
//SF 表示保护起始Sector号,SL 表示保护结束Sector号。
例如:保护Block1 的Sector 2和Sector 3区域命令为protect 1:2-3

protect on bank N //bank N是保护整个Block,
protect off bank N //保护Block号为N 的整个Flash

erase 擦除Flash的命令
erase all 擦除全部
erase start end //start end是照起始地址和结束地址定义范围,
//start是擦除块的起始地址;
//end 是擦除末尾块的结束地址。
例如:擦除Sector 2和Sector 3区域命令为erase 20000 3ffff

erase start +size //start +size是照起始地址和操作字节数定义范围
//start是擦除块的起始地址;
//size 是擦除的字节数。
例如:擦除Sector 2和Sector 3区域命令为erase 20000 +20000

erase N:SF[-SL]
//N:SF[-SL]是按照组和扇区,N 表示Flash 的Block号,
//SF 表示擦除起始Sector号,SL 表示擦除结束Sector号。
例如:保护Block1 的Sector 2和Sector 3区域命令为erase 1:2-3

erase bank N //bank N是擦除整个Block,
//擦除Block号为N 的整个Flash


从Nand flash中读数据
Nand read dest(sdram) src(Flash) size

对Nand flash擦除数据
Nand erase start size

向Nand flash中写数据
Nand write src(sdram) dest size


(基于smdk2410)?


1.相关文件?


common/env_common.c?


供u-boot 调用的通用函数接口,它们隐藏了env 的不同实现方式,比如dataflash,epprom,flash 等?


common/env_dataflash.c?


env 存储在dataflash 中的实现?


common/env_epprom.c?


env 存储在epprom 中的实现?


common/env_flash.c?


env 存储在flash 中的实现?


common/env_nand.c?


env 存储在nand 中的实现?


common/env_nvedit.c?


实现u-boot 对环境变量的操作命令?


environment.c?


环境变量以及一些宏定义?


env 如果存储在Flash 中还需要Flash 的支持。?


2.数据结构?


env 在 u-boot ?中通常有两种存在方式,在永久性存储介质中( Flash NVRAM 等 )在SDRAM,可以?


配置不使用 env ?的永久存储方式,但这不常用。u-boot 在启动的时候会将存储在永久性存储介质中的?


env ?重新定位到 RAM ?中,这样可以快速访问,同时可以通过saveenv 将 RAM ?中的 env ?保存到永久?


性存储介质中。?


在include/environment.h 中定义了表示env 的数据结构?


typedef struct environment_s?


{?


? ? ?unsigned long crc; /* CRC32 over data bytes */?


#ifdef CFG_REDUNDAND_ENVIRONMENT?

? ? ?unsigned char flags; /* active/obsolete flags */?


#endif?


? ? ?unsigned char data[ENV_SIZE]; /* Environment data */?


} env_t;?


关于以上结构的说明:?


crc 是u-boot 在保存env ?的时候加上去的校验头,在第一次启动时一般 crc 校验会出错,这很正常,因?


为这时 Flash 中的数据无效。?


data 字段保存实际的环境变量。u-boot ?的 env ?按 name=value””的方式存储,在所有env 的最后?


以””表示整个 env ?的结束。新的name=value 对总是被添加到 env ?数据块的末尾,当删除一个?


name=value 对时,后面的环境变量将前移,对一个已经存在的环境变量的修改实际上先删除再插入。?


env ?可以保存在 u-boot ?的 TEXT ?段中,这样 env ?就可以同 u-boot ?一同加载入RAM 中,这种方法?


没有测试过。?


? ? 上文提到 u-boot 会将 ?env ?从 ?flash ?等存储设备重定位到 ?RAM ?中,在 env ?的不同实现版本?


?( env_xxx.c ?)中定义了 env_ptr,它指向 env ?在RAM 中的位置。u-boot 在重定位 env 后对环境?


变量的操作都是针对 env_ptr。?


? ? ?env_t ?中除了数据之外还包含校验头,u-boot 把env_t ?的数据指针有保存在了另外一个地方,这就?


是 gd_t ?结构(不同平台有不同的 gd_t ?结构 ),这里以ARM 为例仅列出和 env ?相关的部分?


typedef struct global_data?


{?


? ? ?…?


? ? ?unsigned long env_off; ? ? ? ?/* Relocation Offset */?


? ? ?unsigned long env_addr; ? ? ? /* Address of Environment struct ??? */?


? ? ?unsigned long env_valid ? ? ? /* Checksum of Environment valid */?


? ? ?…?


} gd_t;?


<include/asm-arm/Global_data.h>?


gd_t.env_addr ?即指向 env_ptr->data。?


3.ENV ? ? ?的初始化?


start_armboot : ?( lib_arm/board.c ?)?


*env_init : env_xxx.c ( xxx = nand | flash | epprom … ?)?


env_relocate : env_common.c?


*env_relocate_spec : env_xxx.c ( xxx=nand | flash | eporom… ?)?


3.1env_init?


实现 env ?的第一次初始化,对于nand env ? ? ? ? ? ? ?(非embedded 方式):?


Env_nand.c : env_init?


gd->env_addr = (ulong)&default_environment[0]; //先使gd->env_addr 指向默认的环境变量?


gd->env_valid = 1;// env 有效位置1?


3.2 env_relocate?


#ifdefine ENV_IS_EMBEDDED?


… (略)?


#else?


env_ptr = (env_t *)malloc (CFG_ENV_SIZE);?


#endif?


if( gd->env_valid == 0) // 在 Env_annd.c : env_init ?中已经将 gd->env_valid ?置1?

{?


? ? ?…?


}?


else?


? ? ?env_relocate_spec ();// ?调用具体的 env_relocate_spec ?函数?


gd->env_addr = (ulong)&(env_ptr->data);// 最终完成将环境变量搬移到内存?


这里涉及到两个和环境变量有关的宏?


ENV_IS_EMBEDDED : env 是否存在于 u-boot TEXT ?段中?


CFG_ENV_SIZE : env 块的大小?


实际上还需要几个宏来控制u-boot 对环境变量的处理?


CFG_ENV_IS_IN_NAND : env 块是否存在于Nand Flash ?中?


CFG_ENV_OFFSET : env 块在 Flash ?中偏移地址?


3.3*env_relocate_spec?


这里仅分析 Nand Flash ?的 env_relocate_spec ?实现?


如果未设置 CFG_ENV_OFFSET_REDUND,env_relocate_spec 的实现如下 :?


void env_relocate_spec (void)?


{?


#if !defined(ENV_IS_EMBEDDED)?


? ? ?ulong total;?


? ? ?int ret;?


? ? ?total = CFG_ENV_SIZE;?


? ? ?ret = nand_read(&nand_info[0],CFG_ENV_OFFSET,&total,(u_char*)env_ptr);?


? ? if (ret || total != CFG_ENV_SIZE)?


? ? ? ? ?return use_default();?


? ? ?if (crc32(0,env_ptr->data,ENV_SIZE) != env_ptr->crc)?


? ? ? ? ?return use_default();?


#endif /* ! ENV_IS_EMBEDDED */?


}?


上面的代码很清楚的表明了 ?env_relocate_spec ? ? ? ? ? ? ? ? 的意图,调用 ?nand_read ? ? ? ? ?将环境变量从?


CFG_ENV_OFFSET ?处读出,环境变量的大小为 ?CFG_ENV_SIZE ?注意 ?CFG_ENV_OFFSET ?和?


CFG_ENV_SIZE 要和 Nand Flash ?的块/页边界对齐。读出数据后再调用crc32 对env_ptr->data 进?


行校验并与保存在 env_ptr->crc ?的校验码对比,看数据是否出错,从这里也可以看出在系统第一次启动?


时,Nand Flash 里面没有存储任何环境变量,crc 校验肯定回出错,当我们保存环境变量后,接下来再启?


动板子u-boot 就不会再报crc32 出错了。?


4. ENV ? ? ?的保存?


由上问的论述得知,env 将从永久性存储介质中搬到RAM里面,以后对env ?的操作,比如修改环境变量?

的值,删除环境变量的值都是对这个 env ?在RAM 中的拷贝进行操作,由于RAM 的特性,下次启动时所?


做的修改将全部消失,u-boot 提供了将env ?写回永久性存储介质的命令支持 : saveenv,不同版本的?


env ? ( ?nand ? flash,?flash ?… )实现方式不同,以 Nand ? ? ? ? ? ? ? ?Flash 的实现(未定义?


CFG_ENV_OFFSET_REDUND)为例?


Env_nand.c : saveenv?


int saveenv(void)?


{?


? ? ?ulong total;?


? ? ?int ret = 0;?


? ? ?puts ("Erasing Nand...");?


? ? ?if (nand_erase(&nand_info[0],CFG_ENV_SIZE))?


? ? ? ? ?return 1;?


? ? ?puts ("Writing to Nand... ");?


? ? ?total = CFG_ENV_SIZE;?


? ? ?ret = nand_write(&nand_info[0],(u_char*)env_ptr);?


? ? ?if (ret || total != CFG_ENV_SIZE)?


? ? ? ? ?return 1;?


? ? ?puts ("donen");?


? ? ?return ret;?


}?


Nand Flash ?的 saveenv ?命令实现很简单,调用nand_erase 和nand_write 进行 Nand Flash 的?


erase,write。nand_write/erase 使用的是u-boot ?的nand 驱动框架,我在做开发的过程中使用的是?


nand_legacy ?驱动,所以可以把 nand_erase ?和 nand_write ? ? ? ? ? ? 改成 nand_legacy_erase ?和?


nand_legacy_rw 就可实现nand_legacy 驱动的保存环境变量版本。?


========================================================?


================?


U-Boot 环境变量?


U-Boot通过环境变量(env)为用户提供一定程度的可配置性,这些环境变量包括串口终端所使用的波特?


率(baudrate)、启动操作系统内核的参数(bootargs)、本地IP 地址(ipaddr)、网卡MAC地址(ethaddr)?


等等。环境变量可以固化到非易失性存储介质中,使用printenv / saveenv 命令来查看和修改。本例中,?


环境变量固化到Flash 中(AM29LV160DB,2MB)。?


可配置性意味着环境变量中的项目是可以被添加、删除和修改的,即环境变量的内容可能会频繁变化。为?


了不让这种变化对U-Boot 的代码和数据造成破坏,通常的选择是在Flash 中准备一个专用的sector 来?


存储环境变量。简化的ROM 分配模型如下图所示,monitor 占用 Flash 前256KB,env 置于其后,Flash?


的最后一部分用来存放压缩的操作系统内核。?

由于U-Boot 代码通常达到100KB左右,且必须从地址0 处开始,按照这样的分配方式,我们将不得不?


为env 分配一块64KB 的sector,而实际中使用到的可能只是其中的几百字节!U-Boot 还会为env 在?


RAM 中保持一块同样大小的空间,这就造成ROM 和RAM 空间不必要的浪费。?


为了尽可能地减少资源浪费,同时保证系统的健壮性,我们可以把env 放置在Flash 中容量最小的sector?


里。这样,env 嵌入(embed)到U-Boot 的代码段。在common/environment.h 中会比较env 和?


monitor 的范围,如果确定env 位于monitor 内,则定义ENV_IS_EMBEDDED。?


# if (CFG_ENV_ADDR >= CFG_MONITOR_BASE) && ?


? ? ?(CFG_ENV_ADDR+CFG_ENV_SIZE) <= (CFG_MONITOR_BASE + CFG_MONITOR_LEN)?


# ? define ENV_IS_EMBEDDED ? ? ? 1?


# endif?


修改board/buf/EVB44B0/u-boot.lds:?


/*------------------------------------------------------------?


?* Environment Variable setup?


?*/?

#define CFG_ENV_IS_IN_FLASH ? ? ? ? ? ? ? ? 1 ?/* 使用Flash 存储env ? ? ? ? ? */? #define CFG_ENV_SIZE ? ? ? ? ? ? ? ? 0x2000 ? ? /* 容量8KB (SA1) ? ? ? ? ? */? #define CFG_ENV_OFFSET 0x4000 ? ? ? ? ? ? /* 偏移地址 (SA1) ? ? ? ? ? ? */? $(LD)将一系列的 obj ?文件连接成 elf 格式文件,其输出文件的内存布局由 linker script 决定。修改? board/buf/EVB44B0/u-boot.lds:? SECTIONS? {? ? ? ? . = 0x00000000;? ? ? ? . = ALIGN(4);? ? ? ? .text ? ? ?:? ? ? ? {? ? ? ? ?cpu/s3c44b0/start.o (.text)? ? ? ? ? board/buf/EVB44B0/lowlevel_init.o (.text)? ? ? ? ?lib_generic/string.o (.text)? ? ?lib_generic/zlib.o (.text)? ? ? ? ?. = env_offset;? ? ? ? ?common/environment.o (.text)? ? ? ? ?*(.text)? ? ? ? }? ? ? ? /* other sections ... */? }? 从u-boot.map 选择那些U-Boot 运行必须的,且不易受CFG_*宏影响的obj 文件,填充到start.o 后? 面。可以参考board/trab/u-boot.lds。? env_offset 定义在common/environment.c 中:? #define GEN_SYMNAME(str) SYM_CHAR #str? #define GEN_VALUE(str) #str? #define GEN_ABS(name,value) ? ? ? ? ? ? asm (".globl " GEN_SYMNAME(name)); ? ? ? ? ? ? asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))? GEN_ABS(env_offset,CFG_ENV_OFFSET);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读