linux在线升级

//=======================================
前提信息:
1.系统分区信息
SPI-Flash:
[0] 0x000000000000-0x000000020000 : "SPL,128KB"
[1] 0x000000020000-0x0000000e0000 : "U-Boot,768KB"
[2] 0x0000000e0000-0x000000100000 : "U-Boot Env,128KB"
[3] 0x000000100000-0x000000200000 : "Reseved,1024KB"
Nand-Flash:
[4] 0x000000000000-0x000000500000 : "Kernel,5MB"
[5] 0x000000500000-0x000004500000 : "Rootfs,64MB"
[6] 0x000004500000-0x000010000000 : "Data,187MB"

cat /proc/partitions
major minor  #blocks  name

  31        0        128 mtdblock0
  31        1        768 mtdblock1
  31        2        128 mtdblock2
  31        3       1024 mtdblock3
  31        4       5120 mtdblock4
  31        5      65536 mtdblock5
  31        6     191488 mtdblock6
# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00020000 00001000 "SPL,128KB"
mtd1: 000c0000 00001000 "U-Boot,768KB"
mtd2: 00020000 00001000 "U-Boot Env,128KB"
mtd3: 00100000 00001000 "Reseved,1024KB"
mtd4: 00500000 00020000 "Kernel,5MB"
mtd5: 04000000 00020000 "Rootfs,64MB"
mtd6: 0bb00000 00020000 "Data,187MB"
2.用到以下工具,均在根文件系统里有,需要拷出来
注意:以下文件一定是解压到在SDRAM中或Data分区[需要挂载在/dev/mtdblock6]中执行,否则影响rootfs的升级。
$ ls
flash_erase  flash_eraseall  nanddump  nandwrite
//=======================================
1.制作升级包update.tar.gz,解压里面应该有
|-- update.sh
|-- uImage
|-- ubi.img
`-- util/
     |-- flash_erase
     `-- nandwrite
2.升级Kernel
/tmp/updatefile/util/flash_erase /dev/mtd4 0 0
/tmp/updatefile/util/nandwrite -p /dev/mtd4 /tmp/updatefile/$NAME_KERNEL

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

3.升级rootfs
升级rootfs的话,尽量把其他非内核必须的进程都关闭掉,防止在升级过程中,还有进程或和程序去读取nand flash上的rootfs
方法一:以下两条命令,不能使用reboot命令[直接断电或看门狗]
/tmp/updatefile/util/flash_erase /dev/mtd5 0 0
/tmp/updatefil e/util/nandwrite -p /dev/mtd5  /tmp/updatefile/$NAME_ROOTFS
方法二:失败!!
/tmp/updatefil e/util/ ubidetach -p /dev/mtd5
/tmp/updatefile/util/flash_erase /dev/mtd5 0 0
/tmp/updatefil e/util/ubiformat /dev/mtd5 -f /tmp/updatefile/$NAME_ROOTFS

另外,发现有个更加好用的命令:
mtd_debug
# mtd_debug
usage: mtd_debug info <device>
       mtd_debug read <device> <offset> <len> <dest-filename>
       mtd_debug write <device> <offset> <len> <source-filename>
       mtd_debug erase <device> <offset> <len>
=================MLO的升级=======================
root@am335x-evm:/tmp#  mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NORFLASH
mtd.size =  131072 (128K)
mtd.erasesize = 4096 (4K)
mtd.writesize = 1
mtd.oobsize = 0
regions = 0

root@am335x-evm:/tmp#  mtd_debug erase /dev/mtd0 0 131072【擦除整个分区】
Erased 131072 bytes from address 0x00000000 in flash
root@am335x-evm:/tmp# du -sh /tmp/MLO.byteswap              
100.0K  /tmp/MLO.byteswap
root@am335x-evm:/tmp##  ls -l MLO.byteswap | awk '{print $5}'         
101169
root@am335x-evm:/tmp#  mtd_debug write /dev/mtd0 0 101169 /tmp/MLO.byteswap 【写入新内容,写入大小等于实际文件大小,否则出错!】
Copied 101169 bytes from /tmp/MLO.byteswap to address 0x00000000 in flash

=================U-boot的升级=======================
root@am335x-evm:/tmp#  mtd_debug info /dev/mtd1                             
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NORFLASH
mtd.size =  786432 (768K)
mtd.erasesize = 4096 (4K)
mtd.writesize = 1
mtd.oobsize = 0
regions = 0

root@am335x-evm:/tmp#  mtd_debug erase /dev/mtd1 0 786432     【擦除整个分区】                
Erased 786432 bytes from address 0x00000000 in flash
root@am335x-evm:/tmp# ls -l /tmp/u-boot.img                               
-rw-r--r--    1 root     root         482400 Jun 26 12:01 /tmp/u-boot.img
root@am335x-evm:/tmp#  mtd_debug write /dev/mtd1 0 482400 /tmp/u-boot.img   【写入新内容,写入大小等于实际文件大小,否则出错!】       
Copied 482400 bytes from /tmp/u-boot.img to address 0x00000000 in flash
root@am335x-evm:/tmp# 
参考资料:
//-------------------------------------------------------------------------------------------------
对于yaffs2系统(仅参考):
./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镜像。

//-------------------------------------------------------------------------------------------------
在烧写某个文件之后,如果希望查看当前写入的数据,是否是我们所期望的,那么可以用nanddump工具,将对应部分的数据“打印”出来,比
如:
查看uboot的第一page的数据:
./nanddump -l 0x1000 -s 0x80000 -p /dev/mtd0
//-------------------------------------------------------------------------------------------------
把东西放到ramdisk中以避免影响
之前遇到很多人问这个问题了。那就是,如果在升级的时候,由于也会升级rootfs,但是本身升级过程中,所利用到的文件,如果是放在rootfs中,岂
不是会导致系统崩溃了?
答案是,不会。因为我之前介绍的方法中,是把升级所需的mtd工具,放到U盘的。而U盘是单独mount系统中的。
不过,更加好的做法是,把此处升级所相关的,所有的文件,包括mtd工具,要升级的各个文件,甚至其他可能用到的reboot等工具,设置是这些工具
可能依赖的到库文件等等,都全部拷贝到ramdisk中。这样,通过运行ramdisk中的所有工具,访问ramdisk中的要升级的文件,去升级系统,就不会对
升级rootfs而有啥负面影响,也不会由于升级rootfs而可能导致任何的系统崩溃了

$cat update.sh
#!/bin/bash
# =============================================================
# Author     : QiuWeibo
# Date          : 2014.5.12
# Version     : V1.0.0
# Comment     : For update aPM.MCU
#          1.Support Kernel update
#          2.Support Rootfs update
#          3.Support Monitor App update
#
# =============================================================
# Author     : QiuWeibo
# Date          : 2014.6.9
# Version     : V1.0.1
# Comment     : Add MLO and uboot update
#          1.Support MLO update
#          2.Support uboot update
# =============================================================

echo "firmware update shell start..."

UPDATE_MLO="Y"
UPDATE_UBOOT="Y"
UPDATE_KERNEL="Y"
UPDATE_ROOTFS="Y"
CLEAR_UBOOT_ENV="Y"
MONITOR_APP="Y"

NAME_MLO="MLO.byteswap"
NAME_UBOOT="u-boot.img"
NAME_KERNEL="uImage"
NAME_ROOTFS="ubi.img"
NAME_MONITOR="Monitor"

echo "   UPDATE_MLO=$UPDATE_MLO=$NAME_MLO"
echo " UPDATE_UBOOT=$UPDATE_UBOOT=$NAME_UBOOT"
echo "UPDATE_KERNEL=$UPDATE_KERNEL=$NAME_KERNEL"
echo "UPDATE_ROOTFS=$UPDATE_ROOTFS=$NAME_ROOTFS"
echo "CLEAR_UBOOT_ENV=$CLEAR_UBOOT_ENV"
echo "MONITOR_APP=$MONITOR_APP"

rm -rf /var/ftp/pub/*.tar.gz
echo "end rm -rf /var/ftp/pub/*.tar.gz "
cd /tmp/

# ============== handle for Monitor App Update start============
case "$MONITOR_APP" in
     Y )
     cp -f /tmp/updatefile/$NAME_MONITOR /mnt/userfs/Monitor
        echo "update /mnt/userfs/Monitor success"
     ;;
     * )
        echo "Monitor App do not update"
     ;;
esac
rm -rf /tmp/updatefile/$NAME_MONITOR
echo "end rm -rf /tmp/updatefile/$NAME_MONITOR "
# ============== handle for Monitor App Update end============

# ============== handle for MLO update start============
case "$UPDATE_MLO" in
     Y )
     filesize=`ls -l /tmp/updatefile/$NAME_MLO | awk '{print $5}'`
     if [[ $filesize -gt 1024 ]];then
          mtd_debug erase /dev/mtd0 0 131072
          mtd_debug write /dev/mtd0 0 $filesize /tmp/updatefile/$NAME_MLO
             echo "mtd_debug write /dev/mtd0 0 $filesize /tmp/updatefile/$NAME_MLO"
     else
             echo "/tmp/updatefile/$NAME_MLO error! filesize= $filesize lt 1024!"
     fi
     ;;
     * )
        echo "MLO do not update"
     ;;
esac
rm -rf /tmp/updatefile/$NAME_MLO
echo "end rm -rf /tmp/updatefile/$NAME_MLO "
# ============== handle for MLO update end============

# ============== handle for Uboot update start============
case "$UPDATE_UBOOT" in
     Y )
     filesize=`ls -l /tmp/updatefile/$NAME_UBOOT | awk '{print $5}'`
     if [[ $filesize -gt 1024 ]];then
          mtd_debug erase /dev/mtd1 0 786432
          mtd_debug write /dev/mtd1 0 $filesize /tmp/updatefile/$NAME_UBOOT
          echo "mtd_debug write /dev/mtd1 0 $filesize /tmp/updatefile/$NAME_UBOOT"
     else
          echo "/tmp/updatefile/$NAME_UBOOT filesize error! $filesize lt 1024"
     fi
     ;;
     * )
        echo "u-boot do not update"
     ;;
esac
rm -rf /tmp/updatefile/$NAME_UBOOT
echo "end rm -rf /tmp/updatefile/$NAME_UBOOT "
# ============== handle for Uboot update end============

# ============== handle for clear u-boot env start============
case "$CLEAR_UBOOT_ENV" in
     Y )
     flash_erase /dev/mtd2 0 0
        echo "end clear uboot env at eraseall /dev/mtd2"
     ;;
     * )
        echo "uboot env do not erase!"
     ;;
esac
# ============== handle for clear u-boot env end============

# ============== handle for kernel update start============
case "$UPDATE_KERNEL" in
     Y )
     flash_erase /dev/mtd4 0 0
     nandwrite -p /dev/mtd4 /tmp/updatefile/$NAME_KERNEL
        echo "end nandwrite /tmp/updatefile/$NAME_KERNEL /dev/mtd4"
     ;;
     * )
        echo "KERNEL do not update"
     ;;
esac
rm -rf /tmp/updatefile/$NAME_KERNEL
echo "end rm -rf /tmp/updatefile/$NAME_KERNEL "
# ============== handle for kernel update end============

# ============== handle for rootfs update start============
case "$UPDATE_ROOTFS" in
     Y )
     if [ -e "/tmp/updatefile/util/flash_erase" ] && [ -e "/tmp/updatefile/util/nandwrite" ];then
          /tmp/updatefile/util/flash_erase /dev/mtd5 0 0
          /tmp/updatefile/util/nandwrite -p /dev/mtd5 /tmp/updatefile/$NAME_ROOTFS
             echo "end nandwrite /tmp/updatefile/$NAME_ROOTFS /dev/mtd5"
     else
             echo "/tmp/updatefile/util/flash_erase or nandwrite not exist! error"
     fi
     ;;
     * )
        echo "rootfs do not update"
     ;;
esac
rm -rf /tmp/updatefile/
echo "end rm -rf /tmp/updatefile/ "
# ============== handle for rootfs update end============

rm -rf /tmp/rarlist.txt/
echo "end rm -rf /tmp/rarlist.txt/ "

rm -rf /tmp/update.sh/
echo "end rm -rf /tmp/update_firmware.sh/ "

echo "firmware update shell end"

你可能感兴趣的:(在线升级)