u-boot之怎么实现分区
启动参数bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0中kernel在哪定义,为什么可以直接引用?针对这个问题展开思考最终定位到了MTD分区的实现。 在u-boot之start_armboot函数分析中提到过实现nand flash的分区。执行run_command("mtdparts default", 0)可以实现分区功能,run_command函数在u-boot之内核是怎么启动的已经详细介绍过,现在只是说明mtdparts命令的执行函数do_jffs2_mtdparts,它位于Cmd_jffs2.c (common)文件下。
1、环境变量的初始化
2、mtdparts default命令分析(实现分区)
3、nand read.jffs2 0x30007FC0 kernel命令中kernel的值
1、环境变量的初始化
环境变量的初始化在u-boot之start_armboot函数分析的时候已经粗略的提及过,但是没有具体分析,现在接着详细分析下,首先是在初始化数组中初始化的环境变量:
env_init, /* initialize environment *///初始化环境变量,采用默认环境变量 by andy
具体的函数为:
int env_init(void)
{
#if defined(ENV_IS_EMBEDDED)//ENV_IS_EMBEDDED表示环境变量存放在ram中,不存储在flash上
/****此处省略******/
#else /* ENV_IS_EMBEDDED */
gd->env_addr = (ulong)&default_environment[];//取得默认的环境变量地址
gd->env_valid = ; //环境变量已经存在标志
#endif /* ENV_IS_EMBEDDED */ return ();
}
接着继续重新定位环境变量,函数如下
/* initialize environment */
env_relocate ();//初始化环境变量,crc有效的话从nand中读取存储的环境变量,否则采用默认的环境变量
对env_relocate分析
void env_relocate (void)
{
DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__,
gd->reloc_off); #ifdef ENV_IS_EMBEDDED
/*******省略*********/
#else
/*
* We must allocate a buffer for the environment
*/
env_ptr = (env_t *)malloc (CFG_ENV_SIZE);//在RAM中为环境变量的存放分配一个堆区
DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#endif /*
* After relocation to RAM, we can always use the "memory" functions
*/
env_get_char = env_get_char_memory;//得到环境变量的地址的函数 if (gd->env_valid == ) {//如果环境变量在一开始初始化的时候无效,重新定位默认环境变量
#if defined(CONFIG_GTH) || defined(CFG_ENV_IS_NOWHERE) /* Environment not changable */
puts ("Using default environment\n\n");
#else
puts ("*** Warning - bad CRC, using default environment\n\n");
SHOW_BOOT_PROGRESS (-);
#endif if (sizeof(default_environment) > ENV_SIZE)
{
puts ("*** Error - default environment is too large\n\n");
return;
} memset (env_ptr, , sizeof(env_t));
memcpy (env_ptr->data,
default_environment,
sizeof(default_environment));
#ifdef CFG_REDUNDAND_ENVIRONMENT
env_ptr->flags = 0xFF;
#endif
env_crc_update ();
gd->env_valid = ;
}
else {
env_relocate_spec ();//从nand中取出有效的数据,如果无效,还是使用默认的环境变量
}
gd->env_addr = (ulong)&(env_ptr->data);//取得首个环境变量的地址env_ptr为一个结构体,包含了crc、flags、以及data指针
}
2、mtdparts default命令分析(实现分区)
跟着do_jffs2_mtdparts函数往里看,setenv为设置环境变量函数。
if (argc == ) {//如果参数个数为2个
if (strcmp(argv[], "default") == ) { //默认参数
setenv("mtdids", (char *)mtdids_default); //设置mtdids环境变量
setenv("mtdparts", (char *)mtdparts_default);//设置mtdparts环境变量
setenv("partition", NULL); //设置partition环境变量 mtdparts_init();//分区初始化 by andy
return ;
} else if (strcmp(argv[], "delall") == ) {//删除所有分区
/* this may be the first run, initialize lists if needed */
mtdparts_init(); setenv("mtdparts", NULL); /* devices_init() calls current_save() */
return devices_init();
}
}
继续往里看mtdparts_init函数,这函数比较复杂,先看一下它的调用层次。
mtdparts_init();//分区初始化 by andy
parse_mtdids(ids); //添加mtdids到mtdids链表 nand0=nandflash0
parse_mtdparts(parts);//添加分区parts
devices_init();//0初始化成功,主要是做了删除所有分区设备的工作
device_parse(p, &p, &dev);//添加分区设备,返回的设备为dev,p为从环境变量取得的字符串
id_find_by_mtd_id(mtd_id, mtd_id_len - );//找到parse_mtdids(ids);中添加的mtdids以及名称nandflash0
while (p && (*p != '\0') && (*p != ';')) {
{
part_parse(p, &p, &part);//分区解析,填充part,添加解析过后的part的链表。这个函数解析MTDPARTS_DEFAULT然后分区
}
总的来说就是根据MTDIDS_DEFAULT 与MTDPARTS_DEFAULT解析它们然后进行分区
#define MTDIDS_DEFAULT "nand0=nandflash0"//分区设备为nand
#define MTDPARTS_DEFAULT "mtdparts=nandflash0:256k@0(bootloader)," \//bootloader分区
"128k(params)," \ //参数分区
"2m(kernel)," \ //内核分区
"-(root)" //用户分区
3、nand read.jffs2 0x30007FC0 kernel中kernel的值
实现了分区之后就可以调用分区的名称了,kernel就是其中一个分区的名称。同样的切换到nand命令的运行函数do_nand。同样对它进行层次分析,找到kernel。
do_nand
arg_off_size(argc - , argv + , nand, &off, &size)//5个参数分别代表参数个数、参数位于的地址、分区设备结构地址、返回的偏移值、返回的大小
find_dev_and_part(argv[], &dev, &pnum, &part)//查找有哪个设备存在argv[0]分区,即kernel分区,找到分区信息存放在part中
*off = part->offset;//找到了nand设备,取得偏移值
*size = part->size; //取得大小
u-boot之怎么实现分区的更多相关文章
- ubuntu-14.04中/boot分区不足的解决办法
环境:ubuntu-kylin 或者 ubuntu-14.04,/boot单独分区工具:ubuntu的liveCD. 问题: 由于当初安装的时候,看网上说/boot很小,100M足以,于是单独分区,分 ...
- 【解决方法】安装Win7和linux双系统后,linux报错“无法分配所提交的分区 not enough free space on disks”问题,以及win7无法启动“BootMGR image is corrupt....”问题
近日,在笔记本上重装了Win7 企业版(64位)后,想装个linux双系统,于是开始安装 centOS 6.2(光盘安装) 硬盘分了一个主分区(c盘),一个扩展分区(3个逻辑分区:d,e,f盘),然后 ...
- \boot 空间不足解决方法
ubuntu系统总是更新,有时是内核,有时是软件,最近的一次更新download中,提示\boot目录空间不足,我是将\boot单独划分在一个分区中的,当该目录空间不足时,可以利用命令删除没有用的镜像 ...
- Linux文件系统的主要目录结构说明及分区方案
Linux操作系统有一些固定的目录.各种Linux发行版的目录结构虽然不会一模一样,但是不会有很大差异.知道了这些目录的作用,不仅对你进行磁盘分区规划很有帮助,而且会让你以后的日常维护工作变得轻松.只 ...
- 各种分区类型对应的partition_Id
ID Name Note == ==== ==== 00h empty [空] 01h DOS 12-bit FAT [MS DOS FAT12] 02h XENIX root file system ...
- Ubuntu Linux 分区简易教程
关于Linux系统下的“分区”问题,对于新手来说一直是很头疼的.我来简单写一下,它的“分区”方法,规则. 声明:我为了让没有接触过Linux系统的人,理解更加简单.所以在言语表述上不是很规范,专业.我 ...
- u-boot中分区和内核MTD分区关系
一.u-boot中环境变量与uImage中MTD的分区关系 分区只是内核的概念,就是说A-B地址放内核,C-D地址放文件系统,(也就是规定哪个地址区间放内核或者文件系统)等等. 一般我们只需要分3-4 ...
- U盘安装Ubuntu14.4时遇到分区问题记录
1.在安装Ubuntu14.4时,遇到如果先分出 / 跟挂载的主分区时,后面只能再分一个swap,或者挂载一个/home,或者一个/ boot 时不能继续分区,当然想安装也是不能不能成功的. 解决办法 ...
- Centos 6修复/boot目录及fstab等系统文件
author:JevonWei 版权声明:原创作品 错误界面 系统修复过程中,若需要修复fatab挂载文件,磁盘分区为lvm逻辑卷格式,则默认在修复模式下处于不可活动状态,需使用vgchage -ay ...
- ubuntu安装时系统分区设置
1. 创建主分区:主分区,用于存放系统 20G 主分区 空间起始位置 Ext4日志文件系统 / 2. 创建swap分区:逻辑分区.大小设置为电脑内存大小,2G: 2048MB ...
随机推荐
- C语言函数入参压栈顺序为什么是从右向左?
看到有人提问到,在处理printf/cout时,压栈顺序是什么样的?大家都知道是从右往左,也就是说从右往左的计算,但是,这里的计算不等于输出. a++和++a的压栈的区别:在计算时,遇到a++会记录此 ...
- 23.week4
调通了 剩下的就是核心的部分
- 吴裕雄 06-MySQL选择数据库
实例以下实例选取了数据库 RUNOOB:use RUNOOB;注意:所有的数据库名,表名,表字段都是区分大小写的.所以你在使用SQL命令时需要输入正确的名称. 使用PHP脚本选择MySQL数据库PHP ...
- vs2017中char* str = "1234asd56";会报错,——const char*类型的值不能用于初始化char*类型的实体
原因: "1234asd56"是常量 ,正确的写法本身就是:const char* str = "1234asd56"; 之所以之前的vs版本可以写成char* ...
- c3 新特性
渐变 线性渐变 .line { height: 100px; /*线性渐变语法*/ background-image: linear-gradient( to right,/* ...
- 根据获取的窗口句柄遍历窗口Edit控件
网上说遍历窗口控件有两种方法: 1),使用EnumChildWindows,没有深究, 学习网址如下:http://blog.sina.com.cn/s/blog_60ac1c4b010116 ...
- target=_blank攻击
[target=_blank攻击] 在<a>标签中加入 rel="noopener noreferrer" 来避免. 参考:https://mathiasbynens. ...
- Java拦截器+注解搭配使用
拦截器加注解可以实现登录权限验证等操作,我的应用场景也是为了验证这个,下面是简单的实现步骤 一.什么是拦截器? 拦截器是对action的一种拦截,可以在请求前后进行一些处理 可拦截controll ...
- 关于OPEN_MAX宏undeclared的问题
最近在看unp时,I/O复用-poll一章的代码使用到了OPEN_MAX.据书中描述,这一宏定义在limits.h头文件中,指代一个进程在任意时刻能打开的最大描述符数目.但在代码编译时遇到了错误,提示 ...
- Vue之组件
Vue之全局组件 全局组件可以被任何局部组件调用 <div id="app"> <!--这里是组件的使用--> <global-component&g ...