



























UBOOT=>saveenv
Saving Environment to NAND... Erasing NAND...
Erasing at 0x400000 -- 100% complete.
Writing to NAND... OK
OK

env在uboot中的结构体如下,下面根据结构体来解析dump出来的内容
typedef struct environment_s {
uint32_t crc; /* CRC32 over data bytes */
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
unsigned char flags; /* active/obsolete flags ENVF_REDUND_ */
#endif
unsigned char data[ENV_SIZE]; /* Environment data */
} env_t;
dump出来的内容解析如下:
随便找了一个hex-》ascii的在线网站:https://www.rapidtables.com/convert/number/hex-to-ascii.html


uboot/u-boot-2020.04/tools/mkenvimage -s 0x20000 -r -p 0x00 -o env.bin env.txt
本小节参考如下两个链接,建议先看完这两个链接,再往下继续:
https://bootlin.com/blog/mkenvimage-uboot-binary-env-generator/
https://source.denx.de/u-boot/u-boot/-/commit/a6337e6ffdea211e70dd8d6c638f6a5ec2295400
2.2.1 我们使用的工具是mkenvimage,其源代码已经被包含中uboot的源代码当中,编译uboot的同时就会编译出这个工具mkenvimage。如果没有被编译,生成这个tool,检查下如下路径的makefile。

2.2.2 -s 后面的0x20000表示env分区的大小,由代码的defconfig文件的如下宏决定
CONFIG_ENV_SIZE=0x20000,表示env的大小是0x20000,即128 kB,这里要注意的是
128kB大小指的是 上述结构体的大小,并非mtd中env分区的大小
这里再赘述下上述的结构体,一看便知什么意思
CONFIG_ENV_SIZE=0x20000 128kB CONFIG_ENV_OFFSET=0x400000 CONFIG_ENV_OFFSET_REDUND=0x480000 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT # define ENV_HEADER_SIZE (sizeof(uint32_t) + 1) #else # define ENV_HEADER_SIZE (sizeof(uint32_t)) #endif #define ENV_SIZE (CONFIG_ENV_SIZE - ENV_HEADER_SIZE)
typedef struct environment_s {
uint32_t crc; /* CRC32 over data bytes */
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
unsigned char flags; /* active/obsolete flags ENVF_REDUND_ */
#endif
unsigned char data[ENV_SIZE]; /* Environment data */
} env_t;
data[ENV_SIZE]中ENV_SIZE的值是(CONFIG_ENV_SIZE - ENV_HEADER_SIZE),说明这个结构就是128kB。
对于本项目,env_a和env_b的分区的大小是512kB, 即如下两个offset相减。
CONFIG_ENV_OFFSET=0x400000
CONFIG_ENV_OFFSET_REDUND=0x480000
2.2.3 -r表示我使用的redundant env,即目前我有两个env,有两个env的话,生成的头是 crc32 + flags多了一个flags。
2.2.4 -p 0x00表示 data数组的后面用什么填充,因为这个结构体非常大,我们大概率是填不满的,此时用0x00填充而非0xff
在最后一个stdout环境变量之后我们开始用0x00来填充。

crc32值为 79 6c 88 58,和从nand flash的值是一样的
flag为01,具体值不用管,只要有这个byte就行
再看看altbootcmd和bautrate的值,也是对的,

CONFIG_ENV_OFFSET=0x400000
CONFIG_ENV_OFFSET_REDUND=0x480000
首先入口的函数调用顺序是initr_env -》 env_relocate -》env_load
注意下面开始最关键的代码分析
3.1 首先打印Loading Environment from,
3.2 调用函数指针drv->load(),这个值被填充的地方是在下图绿框里面结构定义,值为圆圈3,env_nand_load
3.3 进入env_nand_load以后,首先会从两个env_a, env_b的offset处开始读取
3.4 读取成功后进入env_import_redund(圆圈6),在这个函数里面会进行crc32值的计算(圆圈7)
3.5 如果失败,打印*** Warning - %s, " "using default environment (圆圈8和圆圈9)
3.6 如果成功,在返回后,会打印OK(圆圈10)
3.7 两种情况下crc错误 和 crc正确的串口打印log如下图



此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。