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# 图像处理: 获取当前活动窗口句柄,获取窗口大小及位置
需调用API函数 需在开头引入命名空间 using System.Runtime.InteropServices; 获取当前窗口句柄:GetForegroundWindow() [DllImport( ...
- oracle创建数据库步骤
1.oracle安装成功后, cmd sqlplus,然后system/orcl as sysdba 2.更改scott的密码,scott的默认密码是tiger SQL> alter user ...
- 上任com的发布流程
参考:https://blog.csdn.net/qq_19674905/article/details/80268815 首先把本地代码提交到远程自己的git分支,然后merge request到m ...
- SAP 数据类型
数据元素和基本类型对应关系 数据字典预置类型 ABAP类型 运行长度 说明 ACCP N(6) 6 会计计算周期 CHAR C(n) 1-255 字符 CLNT C(3) 3 集团,数据区域代码 CU ...
- maven(二)基于intellij idea搭建maven项目
搭建步骤: 1.File -> New Module,进入创建项目窗口. 接着下一步,这里需要注在Properties中添加一个参数 archetypeCatalog=internal,不加这个 ...
- mysql里max_allowed_packet的作用
MySQL根据配置文件会限制Server接受的数据包大小.有时候大的插入和更新会受 max_allowed_packet 参数限制,导致写入或者更新失败. 查看目前配置: 代码如下: show VAR ...
- pandas的日常笔记--查询
- 网站访问者UA检测及跳转
/*!* UA检测及跳转*/;(function(){ var whatdevice = {}; var myUA = window.navigator.userAgent.toLowerCase() ...
- 相对熵(KL散度)
https://blog.csdn.net/weixinhum/article/details/85064685 上一篇文章我们简单介绍了信息熵的概念,知道了信息熵可以表达数据的信息量大小,是信息处理 ...
- HDU-1087.SuperJUmpingJUmpingJumping.(DP and LISPP)
本题大意:给定一个长度为n的序列a,让你输出这个序列子序列中元素和最大的最大上升子序列. 本题思路:一开始肯定可以想到用LIS实现,我们用LIS实现的时候可以发现这个问题并不满足LIS问题的最优子结构 ...