https://www.cnblogs.com/biaohc/p/6398515.html

uboot 环境变量实现原理:

首先我们先要搞清楚uboot中环境变量的作用,uboot中环境变量的作用就是在不改变源码、不用重新编译的情况下,可以使我们通过

设置环境变量的值来改变uboot的一些设置,如bootdelay时间、机器码的值等等。

具体看一下uboot中环境变量如何实现

1、首先看一下环境变量的初始化函数:

 env_init定义在commen/env_movi.c中 函数中实际执行的就是把default_environment的地址赋值给全局变量gd中的env_addr 和env_valid两个值;

 int env_init(void)
{
#if defined(ENV_IS_EMBEDDED)
#else /* ENV_IS_EMBEDDED */
gd->env_addr = (ulong)&default_environment[];
gd->env_valid = ;
#endif /* ENV_IS_EMBEDDED */ return ();
}

来看一下default_environment数组

在来看一下env_relocate  这个函数

重点是一下两句代码

  • env_ptr = (env_t *)malloc (CFG_ENV_SIZE); 这句代码作用是给uboot环境变量开辟一块16k大小的内存
  • env_relocate_spec (); 这句代码的作用是把sd卡中的uboot环境变量整个分区复制到开辟的这个内存地址处;     
 void env_relocate (void)
{ #ifdef ENV_IS_EMBEDDED
#else
/*
* We must allocate a buffer for the environment
*/
env_ptr = (env_t *)malloc (CFG_ENV_SIZE);
DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#endif if (gd->env_valid == ) { }
else {
env_relocate_spec ();
}
gd->env_addr = (ulong)&(env_ptr->data); }

env_relocate_spec ()函数:

通过movi_read_env函数把sd卡中的环境变量复制到内存中

主要用到的是   movi_read_env(virt_to_phys((ulong)env_ptr)); 函数   

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

        use_default()

三个函数: movi_read_env把sd卡中的uboot的环境变量分区复制到env_ptr中;

     crc32 计算内存中环境变量的crc的值,如果不相等则执行

     use_default函数 

 void env_relocate_spec (void)
{
#if !defined(ENV_IS_EMBEDDED)
uint *magic = (uint*)(PHYS_SDRAM_1); if ((0x24564236 != magic[]) || (0x20764316 != magic[]))
movi_read_env(virt_to_phys((ulong)env_ptr)); if (crc32(, env_ptr->data, ENV_SIZE) != env_ptr->crc)
return use_default();
#endif /* ! ENV_IS_EMBEDDED */
}

下面看一下use_default函数的代码:

1:输出*** Warning - bad CRC or moviNAND, using default environment:

2:清0环境变量内存,把default_environment中的值复制到环境变量内存

3:计算crc,写入内存中的crc位

4:设置gd中的env_valid为1;

 static void use_default()
{
puts ("*** Warning - bad CRC or moviNAND, using default environment\n\n"); if (default_environment_size > CFG_ENV_SIZE){
puts ("*** Error - default environment is too large\n\n");
return;
} memset (env_ptr, , sizeof(env_t));
memcpy (env_ptr->data,
default_environment,
default_environment_size);
env_ptr->crc = crc32(, env_ptr->data, ENV_SIZE);
gd->env_valid = ;
}

这样环境变量初始化算是完成了;

我们在回顾一下环境变量初始化都做了哪些工作:

1:在uboot还没有初始化flash设备(nand movinand 等flash)的时候,先进行环境变量初级初始化,即把gd全局变量中的 env_valid = 1; env_addr 等于全局变量default_enviroment数组的首地址

2:初始化完flash设置以后就要进行环境变量的重定位工作了,即把环境变量从flash中copy到内存中,用一个全局变量env_ptr指向这段内存;复制工作时通过movi_read_env这个函数实现的,实际就是把sd卡中

环境变量分区全部复制到env_ptr指向的这段内存中,然后在对这段内存中的环境变量进行crc校验,如果失败的话,则把default_enviroment中的环境变量复制到这里;

(这里对代码分析env_relocate函数中用malloc设置了一段内存来存放环境变量,一直没有用free来释放这段内存,这里是否存在安全隐患?)

------------------------------------------------------------------------------------------------------------

接下来我们在看一下uboot中关于环境变量的一些命令

第一个 printenv 实现函数为do_printfenv

第二个命令:setenv命令对用的函数是do_setenv 命令,实际上调用的是_do_setenv函数

uboot的环境变量的更多相关文章

  1. U-boot的环境变量值得注意的有两个: bootcmd 和bootargs

    本文转载至:http://www.cnblogs.com/cornflower/archive/2010/03/27/1698279.html U-boot的环境变量值得注意的有两个: bootcmd ...

  2. (三)ubuntu学习前传—uboot常见环境变量

    1.环境变量如何参与程序运行(1)环境变量有2份,一份在Flash中,另一份在DDR中.uboot开机时一次性从Flash中读取全部环境变量到DDR中作为环境变量的初始化值,然后使用过程中都是用DDR ...

  3. U-boot的环境变量: bootcmd 和bootargs

    U-boot的环境变量: bootcmd 和bootargs   u-bootcmdbootcmd是uboot自动启动时默认执行的一些命令,因此你可以在当前环境中定义各种不同配置,不同环境的参数设置, ...

  4. u-boot中环境变量的实现

    转载:http://blog.chinaunix.net/uid-28236237-id-3867041.html U-boot中通过环境参数保存一些配置,这些配置可以通过修改环境参数.保存环境参数. ...

  5. u-boot的环境变量详解

    u-boot的环境变量      u-boot的环境变量是使用u-boot的关键,它可以由你自己定义的,但是其中有一些也是大家经常使用,约定熟成的,有一些是u-boot自己定义的,更改这些名字会出现错 ...

  6. 3、U-boot的环境变量: bootcmd 和bootargs

    u-bootcmdbootcmd是uboot自动启动时默认执行的一些命令,因此你可以在当前环境中定义各种不同配置,不同环境的参数设置,然后设置bootcmd为你经常使用的那种参数.   现在我的boo ...

  7. norflash移植及uboot 保存环境变量实验

    一.实验环境 实验板:TQ2440开发板 SDRAM:64M norflash:EN29LV160AB(2M) nandflash:(256M) 二.移植 本文不详谈从smdk2410移植到TQ244 ...

  8. uboot环境变量实现分析

    u-boot的环境变量用来存储一些经常使用的参数变量,uboot希望将环境变量存储在静态存储器中(如nand nor eeprom mmc). 其中有一些也是大家经常使用,有一些是使用人员自己定义的, ...

  9. uboot 环境变量

    从bootm 命令讲起 1 找到linux的内核入口 Bootm命令通过读取uImage的头部0×40字节的信息,将uImage定位到正确的地址,同时找到linux的内核入口地址. 这个地方就涉及到u ...

随机推荐

  1. SI架构设计与实践

    拆分数据表 水平拆分: 水平拆分 路由算法 pavarotti17 f(pavarotti17) 路由算法——扩容 路由算法——非均匀分布 拆分表的数据访问——SQL转发 si的策略 MySQL集群替 ...

  2. 吴裕雄--天生自然PythonDjangoWeb企业开发:解决使用相对路径名导入包中子模块问题

    问题 将代码组织成包,想用import语句从另一个包名没有硬编码过的包中导入子模块. 解决方案

  3. 二次代价函数、交叉熵(cross-entropy)、对数似然代价函数(log-likelihood cost)(04-1)

    二次代价函数 $C = \frac{1} {2n} \sum_{x_1,...x_n} \|y(x)-a^L(x) \|^2$ 其中,C表示代价函数,x表示样本,y表示实际值,a表示输出值,n表示样本 ...

  4. 02-10Android学习进度报告十

    今天我学习了有关ListView的基础知识,主要是学习了其中界面展示的基本方法. 首先看一个简单的列表实现代码: public class Animal { private String aName; ...

  5. 学习笔记(16)- InsuranceQA_zh

    仓库地址:https://github.com/l11x0m7/InsuranceQA_zh Convolutional Neural Network for Chinese InsuranceQA ...

  6. Linux命令:top命令

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法.top是一个动态显示过程,即可以通过用户按键来不断刷新 ...

  7. 使用eclipse创建一个简单的Java Web应用程序

    关于Java JDK/JRE.Tomcat的配置等等都没什么好说的,主要记录一下使用Eclipse创建web工程时的一些点以及说一说自己用IDEA的创建失败的过程(IDEA没运行成功...暂时不想弄了 ...

  8. 在PyCharm中自动添加文件头、时间日期等信息

    初次安装使用PyCharm,在新建.py文件时会发现文件头并没有什么信息,因此,使用模板会比较方便.方法如下: 1.打开PyCharm,选择File--Settings 2.依次选择Editor--- ...

  9. i.MX RT600之DMIC外设介绍及应用

    恩智浦的i.MX RT600是跨界处理器产品,同样也是i.MX RTxxx系列的开山之作.不同于i.MX RT1xxx系列单片机,i.MX RT600 采用了双核架构,将新一代Cortex-M33内核 ...

  10. 「luogu2633」Count on a tree

    「luogu2633」Count on a tree 传送门 树上主席树板子. 每个节点的根从其父节点更新得到,查询的时候差分一下就好了. 参考代码: #include <algorithm&g ...