1.3. 利用mtd工具升级Linux系统

利用mtd工具升级系统,其实说白了,就是:

  1. 用flasherase擦除数据

    先用flasherase擦除对应mtd分区中的内容

  2. 用nandwrite写入数据

    然后将对应的数据(uboot或uImage或rootfs)用nandwrite写入到对应的mtd中对应的位置即可。

前面介绍过了,对于常见的是把uboot(和kernel)放到nor flash中,而把kernel和rootfs放在nand flash中的。

而我此处的举的例子,是另外一种,即全部内容都放在nand flash上的。

但是,不论是是nor flash,还是nand flash,都在Linux的MTD框架下,管理起来,都是一样的。都是可以用对应的mtd的工具去操作的。所以,如果你本身是要升级对应的uboot(和kernel)到nor flash,对于整个过程,也是一样的,自己照葫芦画瓢即可。

关于我此处举例所用的MTD的分区是如何的,此处先给出相关部分的代码:

#define UBOOT_SIZE 	(SZ_1M)
#define KERNEL_SIZE 	(SZ_8M)
#define ROOTFS_SIZE (SZ_1M*200)
#define TEMP_SIZE 	(SZ_1M*64)

#define BEFORE_DATA_PARTION_SIZE 					\
		(ROOTFS_SIZE + KERNEL_SIZE + UBOOT_SIZE + TEMP_SIZE)
。。。
static struct mtd_partition XXX_default_nand_part[] = {
	[0] = {
		.name	= "U-Boot",
		.offset	= 0,
		.size		= UBOOT_SIZE,
	},
	[1] = {
		.name	= "Kernel",
		.offset 	= UBOOT_SIZE,
		.size		= KERNEL_SIZE
	},
	[2] = {
		.name	= "Root filesystem",
		.offset 	= UBOOT_SIZE + KERNEL_SIZE,
		.size		= ROOTFS_SIZE,
	},
	[3] = {
		.name	= "Temp",
		.offset 	= UBOOT_SIZE + KERNEL_SIZE + ROOTFS_SIZE,
		.size		= TEMP_SIZE,
	},
	[4] = {
		.name	= "Data",
		.offset	= BEFORE_DATA_PARTION_SIZE,
		.size		= 0, /* set in XXX_init_nand_partion() */
	},
};
    

对应的用图表来说明,如下:

图 1.1. Linux系统中的Nand MTD分区

Linux系统中的Nand MTD分区

下面就来介绍,如何一步步升级uboot,kernel和rootfs。

1.3.1. 升级Uboot

  1. 擦除uboot所在分区的所有数据
    ./util/flash_eraseall /dev/mtd0
  2. 擦除旧的uboot的环境变量
    ./util/flash_erase /dev/mtd1 0x700000 2
    • 0x800000~0x900000

      即/dev/mtd1中的0x700000~0x800000, 用于存放uboot中的环境变量。

      重新升级uboot的同时,先把旧的环境变量擦除掉。

  3. 写入uboot数据
    ./util/nandwrite -p -s 0x80000 /dev/mtd0 u-boot_addHeader.bin
    • -p参数

      表示如果要写入的数据不是页大小的整数倍,会自己加填充数据即,如需要,自动padding。

    • 0x80000

      是当前4K的pagesize的nand flash的一个块的大小。

1.3.2. 升级Kernel

  1. 擦除旧的kernel数据
    ./util/flash_erase /dev/mtd1 0 10
    • 其中的参数0,表示从/dev/mtd1起始位置开始擦除
    • 参数10是表示要擦除的block数目

      /dev/mtd1的物理起始地址是0x100000,而0x100000~0x600000之间,是用于保存uImage的数据,所以:

      要擦除的block的数目

      = 要擦除的大小/块大小

      = 0x500000/块大小

      = 5M/512KB

      = 10

      其中,当前用的是这个4K pagesize的nand的块大小是512KB。

  2. 写入kernel数据
    ./util/nandwrite -p /dev/mtd1 uImage

1.3.3. 升级rootfs

  1. 擦除rootfs所在分区数据
    ./util/flash_eraseall /dev/mtd2
  2. 写入新的rootfs
    ./util/nandwrite -o /dev/mtd2 rootfs.4k.arm.yaffs2
    • 因为此处的rootfs镜像文件是yaffs2文件系统,包含了oob数据。所以此处加上参数-o,意思是写入页数据同时也写入oob数据,而且,加了-o 参数同时就不能再像之前的uboot和uImage一样,加-p参数了,因为包含了oob数据的rootfs,本身就是页大小的整数倍,不需要padding。
    • 不论实际使用的是4K+128 还是对于4K+218(内部处理为4K+192)的nand,此处都是使用4K+128的rootfs镜像。