uboot中环境变量的加载、写入过程详解
1、uboot启动中环境变量的加载
1.1、uboot加载环境变量流程分析
(1)首先使用默认的环境变量default_environment[];
(2)然后加载SD卡中env分区的环境变量,校验读出来的环境变量分区是否正确;
(3)如果CRC校验通过则使用SD中读出来的环境变量,校验不通过则使用默认的环境变量;
补充:对环境变量不熟悉的建议阅读博客:《uboot中环境变量的实现》;
1.2、函数调用关系
start_armboot()env_init()--init_sequence[]env_relocate()env_relocate_spec ()env_relocate_spec_movinand()movi_read_env()use_default()mmc_bread()
1.3、源码分析
//uboot中存放环境变量的结构体
typedef struct environment_s {ulong crc; /* CRC校验和 */unsigned char flags; /* active or obsolete */char *data; /* 环境变量的值 */
} env_t;//先使用默认环境变量
int env_init(void)
{gd->env_addr = (ulong)&default_environment[0];gd->env_valid = 1;return (0);
}//加载外存中的环境变量
void env_relocate (void)
{env_ptr = (env_t *)malloc (CFG_ENV_SIZE);DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);if (gd->env_valid == 0) {puts ("*** Warning - bad CRC, using default environment\n\n");show_boot_progress (-60);set_default_env();}else {env_relocate_spec (); //从SD卡中加载环境变量}//最终gd->env_addr都是指向的env_ptr->datagd->env_addr = (ulong)&(env_ptr->data);}//路径:./common/env_auto.c
void env_relocate_spec(void)
{//判断开发板的启动介质,去相应的启动介质读取环境变量if (INF_REG3_REG == 1)env_relocate_spec_onenand();else if (INF_REG3_REG == 2)env_relocate_spec_nand();else if (INF_REG3_REG == 3)env_relocate_spec_movinand();else if (INF_REG3_REG == 4)env_relocate_spec_nor();elseuse_default();
}//从iNand/SD卡读取环境变量
void env_relocate_spec_movinand(void)
{uint *magic = (uint*)(PHYS_SDRAM_1);//magic[0]和magic[1]是存放的魔术,在其他地方会设置这个值if ((0x24564236 != magic[0]) || (0x20764316 != magic[1])) {movi_read_env(virt_to_phys((ulong)env_ptr));}//校验读出来的环境变量,如果不成功就用默认的环境变量if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)return use_default();
}//根据分区表读取env分区,存放到env_ptr变量中
void movi_read_env(ulong addr)
{movi_read(raw_area_control.image[2].start_blk,raw_area_control.image[2].used_blk, addr);
}//从SD卡通道0读取环境变量,就是内接的iNand,这里代码写死了环境变量是放在iNand中的
ulong movi_read(ulong start, lbaint_t blkcnt, void *dst)
{return mmc_bread(0, start, blkcnt, dst);
}//当从env分区读出来的环境变量CRC校验失败时,就是用默认的环境变量default_environment[]
static void use_default()
{puts("*** Warning - 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, 0, sizeof(env_t));memcpy (env_ptr->data,default_environment,default_environment_size);env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE);gd->env_valid = 1;
}
(1)环境变量的地址存放在变量gd->env_addr中,gd全局变量参见博客:《uboot中重要的全局变量——gd》;
(2)实际上gd->env_addr == (ulong)&(env_ptr->data),但是env_ptr->data可以指向默认环境变量default_environment[]或者从SD卡读取的环境变量;
(3)raw_area_control.image[2]里保存的是环境变量分区的信息,具体参见博客:《X210开发板(S5PV210芯片)uboot中SD卡分区分析(init_raw_area_table函数)》;
(4)将[INF_REG_BASE+INF_REG3_OFFSET]地址处的值取出来放在INF_REG3_REG变量中,然后判断当前的启动方式,这个地址的值是在_star汇编函数中根据启动方式写入的。参加博客:《嵌入式开发(S5PV210)——u-boot中如何确定启动方式》;
2、saveenv命令的代码调用关系
do_saveenvsaveenvsaveenv_movinandmovi_write_envmovi_writemmc_bwrite
2.1、源码分析
#define __REG(x) (*(vu_long *)(x))
#define INF_REG3_REG __REG(INF_REG_BASE+INF_REG3_OFFSET)//路径:./common/env_auto.c
int saveenv(void)
{if (INF_REG3_REG == 2)saveenv_nand();else if (INF_REG3_REG == 3) //开发板接的iNand/SD卡,所以INF_REG3_REG == 3saveenv_movinand();else if (INF_REG3_REG == 1)saveenv_onenand();else if (INF_REG3_REG == 4)saveenv_nor();elseprintf("Unknown boot device\n");return 0;
}//从外存中读取环境变量保存到env_ptr变量中
int saveenv_movinand(void)
{movi_write_env(virt_to_phys((ulong)env_ptr));puts("done\n");return 1;
}void movi_write_env(ulong addr)
{movi_write(raw_area_control.image[2].start_blk,raw_area_control.image[2].used_blk, addr);
}ulong movi_write(ulong start, lbaint_t blkcnt, void *src)
{//第一个参数是0,说明从SD卡通道0去读环境变量,这在代码里写死了//start:开始读取的扇区数//blkcnt:要写入的扇区个数//src:将从SD卡读取到的数据加载到该地址处return mmc_bwrite(0, start, blkcnt, src);
}
(1)saveenv命令的实现参见博客:嵌入式开发——uboot中命令体系详解;
(2)raw_area_control.image[2]里保存的是环境变量分区的信息,具体参见博客:《X210开发板(S5PV210芯片)uboot中SD卡分区分析(init_raw_area_table函数)》;
(3)将[INF_REG_BASE+INF_REG3_OFFSET]地址处的值取出来放在INF_REG3_REG变量中,然后判断当前的启动方式,这个地址的值是在_star汇编函数中根据启动方式写入的。参加博客:《嵌入式开发(S5PV210)——u-boot中如何确定启动方式》;
uboot中环境变量的加载、写入过程详解相关推荐
- nodejs 获取系统环境变量_Node.js中环境变量process.env的一些事详解
前言 最近这两天在和运维GG搞部署项目的事儿.碰到一个问题就是,咱们的dev,uat,product环境的问题. 因为是前后端分离,所以在开发和部署的过程中会有对后端接口的域名的切换问题.折腾了一下午 ...
- zsh关于.zprofile .zlogin .zshrc .zshenv文件中环境变量的加载
zsh下的用户环境配置文件包括.zlogin..zprofile..zshrc..zshenv和.zlogout.刚开始使用zsh,我被弄迷糊了.把这些文件使用场景记录下,以防忘记.
- uboot中环境变量的实现
1.环境变量介绍 uboot中环境变量的作用类似于全局变量,需要某个环境变量的值时调用getenv函数就可以得到.环境变量会指导程序的运行,不必修改代码重新编译,通过修改环境变量就可以改变uboot的 ...
- Linux环境变量及其加载顺序
Linux环境变量及其加载顺序 系统级 用户级 /etc/profile.d/*.sh >/etc/profile -> (~/.bash_profile | ~/.bash_login ...
- (转)web.xml 中的listener、 filter、servlet 加载顺序及其详解
转: https://www.cnblogs.com/Jeely/p/10762152.html web.xml 中的listener. filter.servlet 加载顺序及其详解 一.概述 1. ...
- [tensorflow] 模型保存、加载与转换详解
TensorFlow模型加载与转换详解 本次讲解主要涉及到TensorFlow框架训练时候模型文件的管理以及转换. 首先我们需要明确TensorFlow模型文件的存储格式以及文件个数: model_f ...
- 3种Javascript图片预加载的方法详解
3种Javascript图片预加载的方法详解 预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度. 这对图片画廊及图片占据很大比例 ...
- python导入模块的变量_python 环境变量和import模块导入方法(详解)
1.定义 模块:本质就是.py结尾的文件(逻辑上组织python代码)模块的本质就是实现一个功能 文件名就是模块名称 包: 一个有__init__.py的文件夹:用来存放模块文件 2.导入模块 for ...
- 【Linux】19.Linux环境变量名LD_LIBRARY_PATH 和 ldd命令详解
Linux环境变量名LD_LIBRARY_PATH 和 ldd命令详解 参考链接: https://www.jianshu.com/p/a62e1d327023 LD_LIBRARY_PATH中的LD ...
最新文章
- Docker 入门系列(6)- Docker 互联
- PHP严重致命错误处理:php Fatal error: Cannot redeclare clas
- 如何获取mongodb中的最后N条记录?
- LeetCode 1271. 十六进制魔术数字(进制转换)
- python语言的单行注释以井号开头_【学习】Python语言入门
- jquery系列教程8-jquery插件大全
- ipad连接电脑显示不在充电_笔记本电脑和投影仪连接后为什么投影仪不能显示电脑内容?...
- python大数据和java大数据的区别-做大数据工程师,语言选Java还是Python?
- Word,Excel联动结合邮件合并功能实现批量打印员工个人信息表桌牌奖状出试卷
- nodejs tinypng 压缩
- CentOS 设置chrome浏览器桌面图标
- 条形码图像生成库barcodelib使用介绍
- 在哪下拼多多上传助手?拼多多软件方法介绍
- 谈谈Gameplay,以及UE4的Gameplay框架
- bom成本分析模型_如何计算一台汽车的BOM成本?
- java 微信自动回复功能开发
- 列表,元组,集合总结
- PDApp.log占用C盘几十G空间,原因及解决方案
- Typora 小技巧:Markdown 表格建立新行
- 2020年全国建筑资质企业目录(带完整企业目录)
热门文章
- vue项目中清除定时器(清除定时器不成功)
- 大学英语计算机四级考试内容,大学英语考试四级中常见的词汇考察题型.doc
- IOS 获取摄像头/麦克风/相册 权限
- 微信小程序——主页无法访问globalData中数据
- C++ getline函数用法
- QVGA/HVGA/WVGA/FWVGA分辨率屏含义及大小//Android虚拟机分辨率
- 新福华无纺布周利民之十二生肖(羊)
- 初中毕业学计算机去哪里,初中毕业能学计算机应用技术去哪好
- 【荣耀笔试8.30】1.六位数最大时间。2.流水线组装产品所需时间。3.数字字符串组合倒序。
- 脑与认知神经科学Matlab Psytoolbox认知科学实验设计——实验设计四