一、疑问
环境变量也是全局变量,为何不能像其他的全局变量放在data段呢?为什么要放在堆中或者使用ENV_IS_EMBEDDED定义的CFG_ENV_SIZE的空间大小,又为什么需要这么大的空间呢?
二、认识
1、尝试放在data段
由于环境变量区不像其他的全局变量,环境变量可以被删除,可以被更改,可以添加,这就要求存储环境变量的空间是足够大的。
也许可以用结构体数组来实现,分别存放环境变量的名字,及相应的值。这样就可以将环境变量放在data段,我们希望在经过start.s重定位后,环境变量已经处于指定的位置了。
struct environment{ struct environment * ptrfoward; struct environment * ptrbackward; char name[20] char value[20] }; struct environment tab[200];
problem
这种情况,环境变量区在flash上是编译器分配的空间。但是,受限于保存环境变量时,flash写是以块为单位的,如果把环境变量保存到之前编译器产生的地址上极有可能破坏其他的数据。也就是说放在data区很难实现。
如果想实现“在经过start.s重定位后,环境变量已经处于指定的位置了”这个目标,使用u-boot提供的ENV_IS_EMBEDED方法最好不过了,似乎也是唯一的办法了。
2、推理
保存环境变量要写flash=>> 环境变量在flash上,必须以整块存储 =>>在RAM中就必须有对应大小的空间 = >>可以在堆区分配,要不然就在编译器编译的时候分配(ENV_IS_EMBEDED的方法)
三、结论
1、环境变量由于大小不确定,必须给其分配足够大的空间,在内存中可以在堆区分配(但需要搬运两次,一次start.s重定位,一次环境变量重定位)。
2、由于还需要将其保存(存储)在flash上,所以要给其单独分一个分区。
3、利用2的特点可以使用ENV_IS_EMBEDED方法(只需要start.s重定位一次)。
四、其他
uboot的环境变量区是以字符串保存的,即使数字也是这样。字符串是接近人的高级表达形式,而非低级的机器二进制码。所以,在处理环境变量时(读、设置、保存),都是字符处理的。