美文网首页路由联盟
18-Openwrt sysupgrade系统升级

18-Openwrt sysupgrade系统升级

作者: Creator_Ly | 来源:发表于2022-05-04 15:01 被阅读0次

    openwrt的升级是使用sysupgrade工具来升级的,该工具为sbin下面的一个脚本,可以附带很多参数,但是我们一般就直接sysupgrade openwrt-ramips-mt7621-device-squashfs-sysupgrade.
    bin升级

    参数 说明
    -i 开启交互模式
    -d 重启前延迟,延迟秒数是传进来的
    -v 会打印sysupgrade脚本中的一些信息,脚本中默认打印
    -q 与-v相反
    -n 升级后不保存配置,默认保存配置
    -c 保存所有的改动配置文件到/etc/
    -b 用sysupgrade.conf中指定的文件,创建.tar.gz格式备份文件
    -r 用上步创建的.tar.gz文件,恢复配置
    -l 列出将会备份的文件列表
    -f 从.tar.gz恢复配置
    -F 即使升级文件检测失败,也要升级,这个参数是危险的,慎用
    -T 验证升级文件和.tar.gz配置文件,但不升级
    -h 打印帮助信息

    sysupgrade的升级流程查看/sbin/sysupgrade脚本可以比较直观.

    1、check校验固件合法性

    sysupgrade的第一步就是校验固件合法性,如下判断platform_check_image函数存在则开始执行。

    type platform_check_image >/dev/null 2>/dev/null || {
        echo "Firmware upgrade is not implemented for this platform."
        exit 1
    }
    
    for check in $sysupgrade_image_check; do
            ( eval "$check \"\$1\"" ) || {             
                    echo "Image check '$check' $1 failed."
                    return 1
            }                         
    done   
    

    该函数位于lib/upgrade/platform.sh中,根据产品的型号来判断各自的magic值。

    platform_check_image() {
        local board=$(ramips_board_name)
        local magic="$(get_magic_long "$1")"
    
        [ "$#" -gt 1 ] && return 1
    
        case "$board" in
    
        br-6475nd)
            [ "$magic" != "43535953" ] && {
                echo "Invalid image type."
                return 1
            }
            return 0
            ;;
        ubnt-erx)
            nand_do_platform_check "$board" "$1"
            return $?;
            ;;
        mt7621-*)
            [ "$magic" != "d00dfeed" ] && {
                echo "Invalid image type."
                return 1
            }
            return 0;
            ;;
        esac
    
        echo "Sysupgrade is not yet supported on $board."
        return 1
    }
    

    我们一般会在该check函数下面添加私有的校验方式,如固件的验签等功能。

    2、保存config配置文件

    export SAVE_CONFIG=1
    

    默认的SAVE_CONFIG标志为为1,所以默认要保存uci配置文件

    if [ -n "$CONF_IMAGE" ]; then
        case "$(get_magic_word $CONF_IMAGE cat)" in
            # .gz files
            1f8b) ;;
            *)
                echo "Invalid config file. Please use only .tar.gz files"
                exit 1
            ;;
        esac
        get_image "$CONF_IMAGE" "cat" > "$CONF_TAR"
        export SAVE_CONFIG=1
    elif ask_bool $SAVE_CONFIG "Keep config files over reflash"; then
        [ $TEST -eq 1 ] || do_save_conffiles
        export SAVE_CONFIG=1
    else
        export SAVE_CONFIG=0
    fi
    

    保存config文件函数如下:

    do_save_conffiles() {
        local conf_tar="${1:-$CONF_TAR}"
    
        [ -z "$(rootfs_type)" ] && {
            echo "Cannot save config while running from ramdisk."
            ask_bool 0 "Abort" && exit
            return 0
        }
        run_hooks "$CONFFILES" $sysupgrade_init_conffiles
        ask_bool 0 "Edit config file list" && vi "$CONFFILES"
    
        v "Saving config files..."
        [ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V=""
        tar c${TAR_V}zf "$conf_tar" -T "$CONFFILES" 2>/dev/null
    
        rm -f "$CONFFILES"
    }
    
    

    如果sysupgrade的时候带参数-n,sysupgrade -n openwrt-ramips-mt7621-device-squashfs-sysupgrade. bin,则会将SAVE_CONFIG=0.

    3、run_hooks "" $sysupgrade_pre_upgrade

    这句的意思是:运行函数sysupgrade_pre_upgrade。先介绍下run_hooks函数,定义在文件common.sh中。

    run_hooks() {

    localarg="$1"; shift
    forfunc in "$@"; do
    eval"$func $arg"
    done
    

    }

    run_hooks函数是钩子函数,其中传过来的第一个参数是函数运行的参数,其余参数为要运行的函数。

    disable_watchdog() {
        killall watchdog
        ( ps | grep -v 'grep' | grep '/dev/watchdog' ) && {
            echo 'Could not disable watchdog'
            return 1
        }   
    }
    
    append sysupgrade_pre_upgrade disable_watchdog
    

    就是在升级前,去清除watchdog进程

    4、 ubus call system upgrade

    调用注册到ubus进程的system路径下的update方法,update方法设置了upgrade_running变量值为1,使得在ubus上注册的服务退出时无需等待。

    root@zihome:/usr/sbin# ubus list system -v
    'system' @3b46ff0c
            "board":{}
            "info":{}
            "upgrade":{}
            "watchdog":{"frequency":"Integer","timeout":"Integer","stop":"Boolean"}
            "signal":{"pid":"Integer","signum":"Integer"}
            "nandupgrade":{"path":"String"}
    

    5、do_upgrade升级

    vim /sbin/sysupgrade

    if [ -n "$(rootfs_type)" ]; then              
        v "Switching to ramdisk..."                     
        (run_ramfs '. /lib/functions.sh; include /lib/upgrade; do_upgrade') &
    else                                      
        (do_upgrade) &                     
    fi 
    

    vim /lib/upgrade/common.sh

    do_upgrade() {                                                    
        clear_caches
        v "Performing system upgrade..."
        if type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
                platform_do_upgrade "$ARGV"
        else
                default_do_upgrade "$ARGV"
        fi
    }  
    

    image升级,保存到对应的mtd分区,这边的PART_NAME在头部会定义为fireware

    default_do_upgrade() {
        sync
        if [ "$SAVE_CONFIG" -eq 1 ]; then
            get_image "$1" "$2" | mtd $MTD_CONFIG_ARGS -j "$CONF_TAR" write - "${PART_NAME:-image}"
        else
            get_image "$1" "$2" | mtd write - "${PART_NAME:-image}"
        fi  
    }
    
    

    6、config保存/删除

    保存完固件之后,就开始处理config配置文件

    if [ "$SAVE_CONFIG" -eq 1 ] && type 'platform_copy_config' >/dev/null 2>/dev/null; then
            platform_copy_config
    fi
    
    if [ "$SAVE_CONFIG" -eq 0 ] && type 'platform_remove_config' >/dev/null 2>/dev/null; then
            platform_remove_config
    fi
    
    

    如果需要保存配置文件,则将config拷贝到/overlay下,`这边的$CONF_TAR压缩包就是上面第二步保存的配置文件

    platform_copy_config() {
        local board_flash=$(mtk_board_flash)
    
        case "$board_flash" in
        "nand"|"spi")
                upgrade_log "Save config"
                rm -rf $1/*
                cp -af "$CONF_TAR" $1/
                sync
                ;;
        esac
    }
    
    

    如果不需要保存则删除/overlay下的config

    platform_remove_config() {
        local board_flash=$(mtk_board_flash)
    
        case "$board_flash" in
        "nand"|"spi")
                upgrade_log "Drop config"
                rm -rf $1/*
                ;;
        esac
    }
    
    

    7、重启

    v "Upgrade completed"
                                  
    [ -n "$DELAY" ] && sleep "$DELAY" 
    v "Rebooting system..."          
    upgrade_log_end                  
    reboot -f                        
    sleep 2                          
    force_reboot   
    

    相关文章

      网友评论

        本文标题:18-Openwrt sysupgrade系统升级

        本文链接:https://www.haomeiwen.com/subject/cdowyrtx.html