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

一、u-boot中环境变量与uImage中MTD的分区关系

分区只是内核的概念,就是说A~B地址放内核,C~D地址放文件系统,(也就是规定哪个地址区间放内核或者文件系统)等等。

一般我们只需要分3-4个区,第一个为boot区,一个为boot参数区(传递给内核的参数),一个为内核区,一个为文件系统区。(但是有的内核就会有很多分区,比如内核参数会有两个,还有会Logo的地址)

而对于bootloader中只要能将内核下载到A~B区的A地址开始处就可以,C~D区的C起始地址下载文件系统…….这些起始地址在MTD的分区信息中能找到。所以bootloader对分区的概念不重要,只要它能把内核烧到A位置,把文件系统烧到C位置即可。

所以,在bootloader对Flash进行操作时,哪块区域放什么是以内核为主(内核中MTD的分区信息可以从内核的代码中看到)。传递给u-boot的参数只要和内核中MTD分区信息一致即可。

而为了方便操作,bootloader类似也引入分区的概念。例如,可以使用“nandwrite 0x3000000 kernel 200000”命令将uImage烧到kernel分区,而不必写那么长:nand write 3000000 A 200000,也就是用分区名来代替具体的地址。

这要对bootloader对内核重新分区:这需要重新设置一下bootloader环境参数,就可以同步更新内核分区信息

如:

setenv bootargs 'noinitrd console=ttySAC0root=/dev/mtdblock3 rootfstype=jffs2 mtdparts=nand_flash:128k(u-boot)ro,64k(u-bootenvs),3m(kernel),30m(root.jffs2),30m(root.yaffs)'

解析:在这里的挂载文件系统的地方mtdblock3,可以从mtdparts中看出来,第一个文件系统(jffs2格式)在第四个分区,所以使用mtdblock3,关于分区和文件系统的挂载在下面有解释。

在设置了mtdparts变量之后,就可以在nand read/write/erase命令中直接使用分区的名字而不必指定分区的偏移位置.而这需要内核MTD最好没有规划分区。

如果你是通过uboot的内核命令行给MTD层传递MTD分区信息,这种情况下,内核读取到的分区信息始终和u-boot中的保持一致(推荐的做法)

如果你是把分区信息写在内核源代码MTD里定义好的方法,那最好保证它和u-boot中的保持一致,即同步修改uboot及内核的相关部分。

解析:从分析的内容可以看出来,首先使用bootargs是可以重新设置内核分区的,使用的mtdparts,也就是说,如果内核中没有指定好mtd分区信息的话,使用uboot给与分区是很好的办法,如果内核中指定好了分区的信息,最好保证uboot中的分区和内核中的分区一直,如果不一致的话,自我感觉是使用uboot的分区信息,或者是uimage启动不成功。




Uboot中分区和内核MTD分区之间的关系理解:

                  

首先觉得这两者是有关系的,但是关于在NAND分区过程中,是哪个依附于哪个,我觉得是uboot依附MTD,在内核flash device驱动中,如果有声明NAND分区信息的话,在uboot中可以再进行mtdparts分区,但是最终的结果是依照MTD进行挂载文件系统的,例如:

如果内核分区信息如下:

staticstruct mtd_partition smdk_default_nand_part[] = {

     [0] = {

          .name     = "uboot",

          .offset = 0x00000000,

          .size     = 0x00040000,

     },

     [1] = {

          .name     = "kernel",

          .offset = 0x00200000,

          .size     = 0x00300000,

     },

     [2] = {

          .name     = "yaffs2",

          .offset = 0x00500000,

          .size     = MTDPART_SIZ_FULL

     }

};

从中可以发现,ubootkernel是存在间隙的,但是不管怎么说,在NAND的最低端可定是uboot的信息,那么这个开发板的uboot的分区信息如下:

bootargs=noinitrdroot=/dev/mtdblock2  init=/linuxrc console=ttySAC0

mtdparts=mtdparts=nandflash0:256k@0(bios),128k(params),128k(toc),512k(eboot),1024k(logo),3m(kernel),-(root)

从上面便可以看出来,挂载文件系统的块并不是按照mtdparts中顺序数出来的文件系统块,因为在内核代码中,文件系统是挂载在mtdblock2上,但是在uboot分区中不是这个样子,如果按照uboot的话应该是mtdblock5,但是内核中ubootkernel之间是有间隙的,这个间隙正好别kernel之前的东西填充结束,总共2m,从内核信息中的mtd分区信息可知,在kernel声明中,偏移量offset=0x200000,也就是2m,但是uboot的大小是size=0x40000,也就是256K,

这两者中间是有间隙的,间隙的部分正好被填充满,但是挂载文件系统依旧是依照内核信息而不是依照uboot中的分区。

         但是也有人说,修改nand分区,直接修改uboot中的mtdparts就可以,也就是说,

 

1.如何对nand 分区。修改mtdparts环境变量就可以了么?

对于目前的U-boot而言,是的.而且, 设置了mtdparts变量之后,你可以在nand read/write/erase命令中直接使用分区的名字而不必指定分区的偏移位置.

set bootargs noinitrd console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2  mtdparts=nand_flash:128k(u-boot)ro,64k(u-boot envs),3m(kernel),30m(root.jffs2),30m(root.yaffs)

内核通过bootargs找到文件系统,bootargs中的mtdblockx即代表分区,block1,2,3代表哪个分区是如何确定的。

事实上,bootargs中的"root=/dev/mtdblockx"只是告诉内核,root fs从第x个(x=0,1,2...)MTD分 区挂载,mtdblock0对应第一个分区,mtdblock1对应第二个分区,以此类推.至于这个分区对应MTD device(NAND Flash)的哪一段范围,取决于内核读到的MTD分区信息,这个分区信息可以通过:

1) 写死在MTD层的NAND Controller驱动或者内核其他部分代码里

2) 通过U-boot传递给内核的命令行中的mtdparts=...部分解析得出,解析的规则同u-boot中mtdparts变量的赋值规则

3) 其他可以让内核知道分区信息的任何办法

在u-boot中给nand分区后是否要对应修改kernel的代码?

如果你用的是通过内核命令行给MTD层传递u-boot中的MTD分区信息,那是不需要的,在这种情况下,内核读取到的分区信息始终和u-boot中的保持一致(推荐的做法)

如果你用的是把分区信息写死在内核源代码里的方法,那最好保证它和u-boot中的保持一致,即同步修改内核的相关部分代码

从上面这几个情况看出来,如果在

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值