启动参数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之怎么实现分区的更多相关文章

  1. ubuntu-14.04中/boot分区不足的解决办法

    环境:ubuntu-kylin 或者 ubuntu-14.04,/boot单独分区工具:ubuntu的liveCD. 问题: 由于当初安装的时候,看网上说/boot很小,100M足以,于是单独分区,分 ...

  2. 【解决方法】安装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盘),然后 ...

  3. \boot 空间不足解决方法

    ubuntu系统总是更新,有时是内核,有时是软件,最近的一次更新download中,提示\boot目录空间不足,我是将\boot单独划分在一个分区中的,当该目录空间不足时,可以利用命令删除没有用的镜像 ...

  4. Linux文件系统的主要目录结构说明及分区方案

    Linux操作系统有一些固定的目录.各种Linux发行版的目录结构虽然不会一模一样,但是不会有很大差异.知道了这些目录的作用,不仅对你进行磁盘分区规划很有帮助,而且会让你以后的日常维护工作变得轻松.只 ...

  5. 各种分区类型对应的partition_Id

    ID Name Note == ==== ==== 00h empty [空] 01h DOS 12-bit FAT [MS DOS FAT12] 02h XENIX root file system ...

  6. Ubuntu Linux 分区简易教程

    关于Linux系统下的“分区”问题,对于新手来说一直是很头疼的.我来简单写一下,它的“分区”方法,规则. 声明:我为了让没有接触过Linux系统的人,理解更加简单.所以在言语表述上不是很规范,专业.我 ...

  7. u-boot中分区和内核MTD分区关系

    一.u-boot中环境变量与uImage中MTD的分区关系 分区只是内核的概念,就是说A-B地址放内核,C-D地址放文件系统,(也就是规定哪个地址区间放内核或者文件系统)等等. 一般我们只需要分3-4 ...

  8. U盘安装Ubuntu14.4时遇到分区问题记录

    1.在安装Ubuntu14.4时,遇到如果先分出 / 跟挂载的主分区时,后面只能再分一个swap,或者挂载一个/home,或者一个/ boot 时不能继续分区,当然想安装也是不能不能成功的. 解决办法 ...

  9. Centos 6修复/boot目录及fstab等系统文件

    author:JevonWei 版权声明:原创作品 错误界面 系统修复过程中,若需要修复fatab挂载文件,磁盘分区为lvm逻辑卷格式,则默认在修复模式下处于不可活动状态,需使用vgchage -ay ...

  10. ubuntu安装时系统分区设置

    1. 创建主分区:主分区,用于存放系统 20G    主分区    空间起始位置    Ext4日志文件系统    / 2. 创建swap分区:逻辑分区.大小设置为电脑内存大小,2G: 2048MB  ...

随机推荐

  1. How to remove live visual tree?

    How to remove live visual tree? How to不显示实时可视化树 Remove the "Go to live visual tree" / &quo ...

  2. elasticsearch 测试

    https://www.yiibai.com/elasticsearch/elasticsearch-getting-start.html # curl -XPUT "http://loca ...

  3. js获取url传值的方法

    这篇文章主要介绍了js获取url传值的方法,实例分析了字符串分割与正则分析两种方法,并补充了一个基于正则匹配实现的js获取url的get传值函数,需要的朋友可以参考下 js获取url参数值: inde ...

  4. java分解质因数,具体程序分析和代码

    题目:将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. 将一个正整数分解质因数分析:对n进行分解质因数,找到最小的质数k如果这个质数恰好等于n则说明分解质因数过程已经结束,打印输出 ...

  5. Light Probe Proxy Volume

    [Light Probe Proxy Volume] The Light Probe Proxy Volume (LPPV) component allows you to use more ligh ...

  6. C#单例和Unity单例

    单例是一种设计模式 单例:不管在项目中的任何模块,当需要使用某个对象的时候,获取到的始终是同一个对象 在C#中 public class InstanceDemo{ private static In ...

  7. 性能测试工具---jmeter

    一.jmeter:简介  Apache jmeter是Apache组织的开发的源代码项目,是一个纯的Java应用,用于压力测试和性能测试,他最初的测试使用于web端的测试,但是后来也被扩展到其他的测试 ...

  8. Android笔记:Button

    示例代码摘自<第一行代码> ButtonDemo.java的代码: public class ButtonDemo extends Activity { @Override protect ...

  9. 六:python 对象类型详解二:字符串(下)

    一:字符串方法: 方法就是与特定对象相关联在一起的函数.从技术的角度来讲,它们是附属于对象的属性,而这些属性不过是些可调用的函数罢了.Python 首先读取对象方法,然后调用它,传递参数.如果一个方法 ...

  10. 二:python 对象类型概述

    1,为什么使用内置类型: a)内置对象使程序更容易编写 b)内置对象是扩展的组件 c)内置对象往往比定制的数据结构更加高效 d)内置对象是语言的标准的一部分 2,python  的主要内置对象 对象类 ...