DM646x的启动程序备份机制实现(二)

DM646x的启动程序备份机制实现(二)


第二部分,kernel与rootfs的备份

下面对kernel与rootfs的备份方法进行研究,主要是回答了下面几个问题:

1,kernel是如何写入的?
2,rootfs的概念
3,rootfs是如何写入的?
4,kernel与rootfs写在什么位置上?
5,由谁来备份?
6,由谁来使用备份?
7,具体如何实现备用功能?


1,kernel是如何写入的?
       kernel是在uboot中写入的。一般的步骤是通过tftp下载到内存中,然后写入到nand flash中。例如如下命令:
tftp 0x80700000 uImage   //从tftp服务器拷贝至内存中
nand erase 0x200000 0x200000    //擦除2M的空间
nand write 0x80700000 0x200000 0x200000 //从内存拷贝至nand flash中
由这些命令,可以知道,只需要指定不同的nand 地址,很容易实现多次写入内核。

2,rootfs的概念
       rootfs即根文件系统。 Linux启动时,第一个必须挂载的是根文件系统;若系统不能从指定设备上挂载根文件系统,则系统会出错而退出启动。根文件系统包含系统引导和使其他文件系统得以挂载(mount)所必要的文件。根文件系统包括Linux启动时所必须的目录和关键性的文件,例如Linux启动时都需要有init目录下的相关文件,在 Linux挂载分区时Linux一定会找/etc/fstab这个挂载文件等。

3,rootfs是如何写入的?
       通常有两种方法:在uboot下烧写,或者使用nfs启动系统,然后在linux下烧写。
       (1)在uboot下烧写
       在uboot下烧写时,需要注意uboot烧写nand的方式,是否与内核中使用的方式相同,特别是nand的ecc校验方式,在不同版本的uboot与不同的内核版本中,都会有所不同。另外,不同的文件系统也会有不同的需求。
步骤:
tftp 0x90700000 root_fs.jffs2   //从tftp服务器拷贝至内存中
nand erase 0x800000 0x700000  //擦除6M的空间
nand write.jffs2 0x90700000 0x800000 0x700000//从内存拷贝至Flash中

       (2)在nfs下烧写
       通常,在nfs启动linux系统后的烧写方式是安全的。步骤如下:
       先在linux服务器下建立一个目录,在该目录下存放根文件系统所有文件。将该目录设置为nfs可访问目录,并从板卡的uboot中设置为启动的根文件系统。
在linux服务器下生成映像文件:
./mkfs.jffs2 -n -s 2048 -e 128KiB -d /home/root/root_fs -o root_fs.jffs2 --pad=0x700000
启动板卡,运行起来linux系统后,使用:
flash_eraseall /dev/mtd3  //删除整个分区
nandwrite -a  -m -p /dev/mtd3 /root_fs.jffs2   //写入文件系统内容
重启板卡,设置使用flash上的文件系统即可。

4,kernel与rootfs写在什么位置上?
       通常,kernel是存放在uboot之后,是在uboot的烧写命令中确定的。而rootfs存放在kernel之后,这个位置,是由内核指定的分区情况来决定的。具体的使用情况,在本部分的结尾有一个实例。

5,由谁来备份?
       kernel的备份,是在uboot下通过命令烧写的。多次烧写,指定不同地址即可。

       rootfs的备份,这里涉及到nand的分区了。在内核启动前,都是直接使用偏移地址来访问nand上存放的东西,内核启动后,就使用分区的概念进行访问数据了。
       首先,要将nand分为多个区,包括ubl、uboot、内核、文件系统四大部分。在文件系统这个概念下,由于要做备份,就需要至少分出两个区。通常的做法,是分3个区,一个是数据与应用程序区,比较大,存放所有与应用相关的代码与数据。另外两个分区都存放同样的rootfs,由于把应用程序分离出去,就可以将rootfs做得很小,这样便于节省存储空间,实现在一个nand上保存两份rootfs。
       做好rootfs之后,就可以采用第3步介绍的方法烧写了。

6,由谁来使用备份?
       kernel的备份使用,是在uboot下设置的启动参数来使用的。当然,也可以修改uboot源码来实现,但是由于uboot的启动参数比较灵活,已经能够实现,就不需要拿把牛刀来杀鸡了。
       假定两次烧写的位置分别是2M与5M的位置,可以如下设置启动参数:
setenv bootcmd 'nboot 0x80700000 0 0x200000; bootm;nboot 0x80700000 0 0x500000; bootm'
       对于bootcmd命令,会一句一句的执行。执行第一句nboot 0x80700000 0 0x200000,就是从nand 偏移地址2M的地方读取内核,然后执行第二句bootm,即进行启动。若启动失败,会执行第三句,后面的过程就是类似的操作了,只是内核的偏移地址不同。

       rootfs的备份使用,是内核来实现的,需要修改内核源码,在启动内核成功后,寻找有效的rootfs时,若发现不是有效的,就去寻找第二个rootfs。

7,具体如何实现备用功能?
       备份的使用,是在默认启动程序有问题的时候,才启用的。而这个判断默认启动程序是否有问题,是需要上一级的启动程序来进行判断的。所以,内核的默认启动程序是否异常,需要uboot来判断,出了异常后,如何处理,是否启用备用程序,也是由uboot来决定的。同样,rootfs的备份是否使用,是依赖于kernel程序的。
       对于kernel的备份与使用,在uboot已经支持,只要配置好启动参数就行了。
       对于rootfs的备份,首先需要修改内核的分区情况,然后需要在读取rootfs时添加有效性判断,并进行异常后的再次处理。

 
 烧写之后的nand存储格局示例:
 
 第0个块 (0-128k)为空。

 第1个块 (20000存放块头)保存了ubl  ,20800--238ab
 第2个块 (40000存放块头),ubl
 第3个块 (60000存放块头),ubl
 第4个块 (80000),没有块头信息,存放uboot的参数。
 第5个块 (a0000存放块头),ubl

 第6-7个块  (C0000存放块头),   保存uboot,c0800--e261b
 第8-9个块  (100000存放块头),  保存uboot,100800--12261b
 第10-11个块 (140000存放块头),  保存uboot,140800--16261b
 第12-13个块 (180000存放块头),  保存uboot,180800--1a261b
 第14-15个块 (1c0000存放块头),  保存uboot,1C0800--1e261b

200000-400000 uImage  16-31
400000-500000 空  32-39 -留空
500000-700000 uImage  40-55
700000-800000 空  56-63 -留空

0800000-0F00000 空  7M,第一个rootfs
0F00000-1000000 空  1M -留空
1000000-1700000 空  7M,第二个rootfs
1700000-1800000 空  56-63 -留空
1800000-7800000 空  96M,存放应用程序的分区
 
说明:

       我使用的nand flash,一个块的大小为128k,总大小为128M。

       只所以每两个数据块之间,都要留空,是考虑到在使用flash烧写器进行整片nand数据拷贝时,可能会遇到坏块,需要将有效数据往后平移,从而避免覆盖后面的有效数据。 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值