概述
设备升级页面
升级固件简要说明
最新升级文件
文件下载地址
OTA文件分析
OEM的目录结构
概述
今日mixpad 精灵款推送了最新的OTA升级文件,
然而,此升级文件已经可以通过链接可以自由下载了!
设备升级页面
设备的升级页面如下:
升级固件简要说明
【精灵正式版】兼容单火/零火精灵, 合并5.3.2、5.3.3代码。
修复BUG:
1、MixPad 精灵被365删除后,频繁上报数据,导致服务器压力大问题;
2、特定情况下,MixPad 精灵自带遥控器出现异常时,崩溃问题。
最新升级文件
HomeAI_OS_5.3.6.307_MixPadGenius_OTA_202109301101.tar_30153439.gz
文件下载地址
等下我上传到我的网盘里,需要的可以发私信。
CSDN专属链接地址:https://download.csdn.net/download/leekwen/33193640
OTA文件分析
OTA文件内部包含文件系统的核心内容,到时我专门写篇文章来分析一下吧!
这里先大致让大家看一下目录结构!
[root@192-168-0-171 leekwen]# cd MixPadGenius_OTA/
[root@192-168-0-171 MixPadGenius_OTA]# ls
do_upgrade_oem oem upgrade.list
[root@192-168-0-171 MixPadGenius_OTA]# ls -l
total 124
-rwxr-xr-x 1 root root 12936 Sep 30 11:01 do_upgrade_oem
drwxr-xr-x 6 root root 329 Sep 30 11:01 oem
-rw-r--r-- 1 root root 107175 Sep 30 11:01 upgrade.list
[root@192-168-0-171 MixPadGenius_OTA]# cat do_upgrade_oem
#!/bin/sh
# 用于打印
PROCESS_NAME=$0
EMBER_DISK=/oem
FIRM_PATH=/oem/ember-host
EMBER_APP_PATH=$EMBER_DISK/ember-host/bin/
VIHOME_BAKDIR=$EMBER_APP_PATH/vihome.bak
TMP_PATH=/tmp/
VIHOME_ENV_HARDWARE=MixpadHostLinux
FW_MD5FILE=fw.md5
UPGRADE_LIST=upgrade.list
UPGRADE_MARK=upgrade.mark
#工厂测试相关文件,升级时空间不够,删除
AGING_FILE=/oem/app/aging_test.tar.gz
FACTORY_TEST_FILE=/oem/app/factory_test.tar.gz
#安装失败的标记
UPGRADE_FAIL_MARK=/userdata/upgrade_failed_mark
#第三方脚本
MIXPAD_THIRD_PROG=/oem/third_start.sh
# 先检查参数是否合规
if [ $# -ne 1 ]; then
echo "ERROR: args $# error!!"
echo "USAGE: $0 [ota_file_name]"
exit 1
fi
remount_ro_partition() {
#恢复只读
sync
mount -o remount,ro $EMBER_DISK
}
prepare() {
# 固件目录创建
[ -d $EMBER_DISK ] || mkdir $EMBER_DISK
#获取oem分区读写权限
mount -o remount,rw $EMBER_DISK
#[ -d $UPGRADE_DIR ] && rm -rf $UPGRADE_DIR
#mkdir -p $UPGRADE_DIR
# 固件目录改为传进来
if [ ! -d $UPGRADE_DIR ]; then
remount_ro_partition
exit 1
fi
}
set_busybox() {
# BUSYBOX=$EMBER_APP_PATH/busybox
MD5SUM="busybox md5sum"
AWK="busybox awk"
SYNC="busybox sync"
SED="busybox sed"
DF="busybox df"
baseNAME="busybox basename"
DIRNAME="busybox dirname"
}
set_boot_logo() {
#确认当前语言设置
lan_str=`cat /userdata/config/blackboard.ini | grep -w language`
if [ "$lan_str"x != ""x ]; then
#去掉空格
lan_str=`echo $lan_str | sed 's/ //g'`
#截取=后面的字符串
lan_str=`echo ${lan_str#*=}`
else
echo "do_upgrade_oem: language not found"
logger "do_upgrade_oem: language not found in /userdata/config/blackboard.ini"
fi
LOGO_EN_PATH="/usr/share/logo/update-en.ebm"
if [ "$lan_str"x == "en"x ] && [ -f $LOGO_EN_PATH ]; then
logo_file=$LOGO_EN_PATH
else
logo_file="/usr/share/logo/update.ebm"
fi
if [ -f ${logo_file} ]; then
dd if=${logo_file} of=/dev/fb0
fi
}
stop_all_app() {
echo "=== stop_all_app ==="
logger "stop_all_app, freeze display"
echo "output:all:freeze" > /tmp/.weston_drm.conf
/oem/orb_start.sh stop
#显示升级logo
set_boot_logo
#20201126临时方案 start
GATEWAY_PID=$(pidof ember-host)
if [ "$GATEWAY_PID"x != ""x ] && [ "$GATEWAY_PID"x != " "x ]; then
killall -9 init.gw-service
killall -9 proxy_system_daemon
killall -9 host_http_ota
/oem/ember-host/bin/ember_main stopmon
/oem/ember-host/bin/ember_main stop
killall -9 mesh_provisioner
fi
:'
if [ -f $AGING_FILE ]; then
rm -f $AGING_FILE
fi
if [ -f $FACTORY_TEST_FILE ]; then
rm -f $FACTORY_TEST_FILE
fi
'
#20201126临时方案 end
sleep 3
}
start_all_app() {
echo "=== start_all_app ==="
logger "=== start_all_app ==="
/oem/orb_start.sh start
#执行第三方程序脚本
if [ -f $MIXPAD_THIRD_PROG ]; then
$MIXPAD_THIRD_PROG restart
fi
sleep 5
echo "output:all:unfreeze" > /tmp/.weston_drm.conf
logger "unfreeze display"
}
progress_bar() {
percent=$(awk 'BEGIN{printf "%03d",('$line_no'/'$line_sum')*100}')
let line_no=line_no+1
echo "percent:$percent%"
logger "percent:$percent%"
}
start_upgrade() {
RET=0
# 只读时,需则重新挂载
# mount -o remount,rw /system
# make a Mark
date >> $EMBER_DISK/$UPGRADE_MARK
let line_sum=$(cat $UPGRADE_DIR/$UPGRADE_LIST | wc -l)
let line_no=1
BAR_PIPE=/tmp/do_upgrade_oem.pipe
[ ! -p do_upgrade_oem.pipe ] || rm $BAR_PIPE
mkfifo $BAR_PIPE
# 重命名后缀文件名记录
MODIFY_NAME_FILE=$TMP_PATH/do_upgrade_modify_file.text
[ -f $MODIFY_NAME_FILE ] && rm -f $MODIFY_NAME_FILE
find /oem -name *._upg_tmp | xargs rm -f
# copy file to specified path
while read line
do
# 进度条
progress_bar
WPATH_CHECK_BIN=/$(echo $line | $AWK '{print $2}')
DIR_CHECK_BIN=$($DIRNAME $WPATH_CHECK_BIN)
MD5=$(echo $line | $AWK '{print $1}')
# WPATH : 绝对路径+文件名称
WPATH=/$(echo $line | $AWK '{print $2}')
FILE=$($baseNAME $WPATH)
DIR=$($DIRNAME $WPATH)
echo ""
echo WPATH:$WPATH FILE:$FILE
echo MD5:$MD5
# get MD5 CHECKSUM
if [ -e "$WPATH" ]; then
SUM=$($MD5SUM $WPATH | $AWK '{print $1}')
if [ "$SUM" == "$MD5" ]; then
echo "same as last, skip upgrade: $FILE"
continue
fi
fi
# loop copy until file's md5 correct
TRY_TIMES=1
while [ $TRY_TIMES -lt 10 ];
do
# 先创建文件夹
DIR_NAME=`dirname ${WPATH}`
[ -d ${DIR_NAME} ] || mkdir -p ${DIR_NAME}
# 将目标文件拷贝到目标文件系统,重命名成临时后缀
UPGRADE_TMP="${WPATH}._upg_tmp"
CUR_PRO_PID=$(pidof $FILE)
if [ "$CUR_PRO_PID"x != ""x ] && [ "$CUR_PRO_PID"x != " "x ]; then
echo "killall $FILE"
logger "killall $FILE"
killall -9 $FILE
sleep 0.1
fi
echo "install copy $UPGRADE_DIR/$WPATH --> $UPGRADE_TMP"
logger "install copy $UPGRADE_DIR/$WPATH --> $UPGRADE_TMP"
time cp -f "$UPGRADE_DIR/$WPATH" "$UPGRADE_TMP"
if [ $? -eq 0 ]; then
$SYNC
echo $UPGRADE_TMP >> $MODIFY_NAME_FILE
# 计算 MD5
TMP_FILE_SUM=$($MD5SUM $UPGRADE_TMP | $AWK '{print $1}')
if [ "$TMP_FILE_SUM" != "$MD5" ]; then
echo "tmp_file $UPGRADE_TMP check md5[$TMP_FILE_SUM] failded!!"
logger "tmp_file $UPGRADE_TMP check md5[$TMP_FILE_SUM] failded!!"
RET=255
fi
break
else
echo "cp firmware file failed!"
logger "cp firmware file failed!"
#拷贝失败可能是进程还在运行,终止进程
CUR_PRO_PID=$(pidof $FILE)
if [ "$CUR_PRO_PID"x != ""x ] && [ "$CUR_PRO_PID"x != " "x ]; then
echo "killall $FILE"
logger "killall $FILE"
killall -9 $FILE
sync
sleep 0.1
fi
RET=255
fi
let "TRY_TIMES = TRY_TIMES + 1"
done
# failed upgrade, break loop
[ $RET -ne 0 ] && break
done < $UPGRADE_DIR/$UPGRADE_LIST
# 完成时,将临时后缀去掉,重命名成目标文件
if [ $RET -eq 0 -a -f $MODIFY_NAME_FILE ]; then
echo "======== start move =========="
logger "======== start move =========="
# cat $MODIFY_NAME_FILE
cat $MODIFY_NAME_FILE | xargs -i echo mv {} {} | sed 's/._upg_tmp//2'
time cat $MODIFY_NAME_FILE | xargs -i echo mv {} {} | sed 's/._upg_tmp//2' | sh
$SYNC
echo "======== finish move =========="
logger "======== finish move =========="
else
echo "======== nothing to move =========="
logger "======== nothing to move =========="
fi
if [ $RET -eq 0 ]; then
echo "Upgrade Complete."
logger "Upgrade Complete."
else
echo "Upgrade End with error: $RET !!"
logger "Upgrade End with error: $RET !!"
fi
return $RET
}
start_upgrade_userdata() {
RET=0
# make a Mark
date >> $EMBER_DISK/$UPGRADE_MARK
let line_sum=$(cat $UPGRADE_DIR/$UPGRADE_LIST | wc -l)
let line_no=1
BAR_PIPE=/tmp/do_upgrade_oem.pipe
[ ! -p do_upgrade_oem.pipe ] || rm $BAR_PIPE
mkfifo $BAR_PIPE
# 重命名后缀文件名记录
MODIFY_NAME_FILE=$TMP_PATH/do_upgrade_modify_file.text
[ -f $MODIFY_NAME_FILE ] && rm -f $MODIFY_NAME_FILE
find /oem -name *._upg_tmp | xargs rm -f
# copy file to specified path
while read line
do
# 进度条
progress_bar
WPATH_CHECK_BIN=/$(echo $line | $AWK '{print $2}')
DIR_CHECK_BIN=$($DIRNAME $WPATH_CHECK_BIN)
MD5=$(echo $line | $AWK '{print $1}')
# WPATH : 绝对路径+文件名称
WPATH=/$(echo $line | $AWK '{print $2}')
FILE=$($baseNAME $WPATH)
DIR=$($DIRNAME $WPATH)
echo ""
echo WPATH:$WPATH FILE:$FILE
echo MD5:$MD5
# get MD5 CHECKSUM
if [ -e "$WPATH" ]; then
SUM=$($MD5SUM $WPATH | $AWK '{print $1}')
if [ "$SUM" == "$MD5" ]; then
echo "same as last, skip upgrade: $FILE"
logger "same as last, skip upgrade: $FILE"
continue
fi
fi
# loop copy until file's md5 correct
TRY_TIMES=1
while [ $TRY_TIMES -lt 10 ];
do
# 先创建文件夹
DIR_NAME=`dirname ${WPATH}`
[ -d ${DIR_NAME} ] || mkdir -p ${DIR_NAME}
# 将目标文件覆盖到目标文件
echo "install copy $UPGRADE_DIR/$WPATH --> $WPATH"
logger "install copy $UPGRADE_DIR/$WPATH --> $WPATH"
CUR_PRO_PID=$(pidof $FILE)
echo "#######################CUR_PRO_PID=$CUR_PRO_PID"
if [ "$CUR_PRO_PID"x != ""x ] && [ "$CUR_PRO_PID"x != " "x ]; then
echo "killall $FILE"
logger "killall $FILE"
killall -9 $FILE
sleep 0.1
fi
time cp -f "$UPGRADE_DIR/$WPATH" "$WPATH"
if [ $? -eq 0 ]; then
$SYNC
echo $WPATH >> $MODIFY_NAME_FILE
# 计算 MD5
TMP_FILE_SUM=$($MD5SUM $WPATH | $AWK '{print $1}')
if [ "$TMP_FILE_SUM" != "$MD5" ]; then
echo "tmp_file $WPATH check md5[$TMP_FILE_SUM] failded!!"
logger "tmp_file $WPATH check md5[$TMP_FILE_SUM] failded!!"
RET=255
fi
break
else
echo "cp firmware file failed!"
logger "cp firmware file failed!"
#拷贝失败可能是进程还在运行,终止进程
CUR_PRO_PID=$(pidof $FILE)
if [ "$CUR_PRO_PID"x != ""x ] && [ "$CUR_PRO_PID"x != " "x ]; then
echo "killall $FILE"
logger "killall $FILE"
killall -9 $FILE
sync
sleep 0.1
fi
RET=255
fi
let "TRY_TIMES = TRY_TIMES + 1"
done
# failed upgrade, break loop
[ $RET -ne 0 ] && break
done < $UPGRADE_DIR/$UPGRADE_LIST
if [ $RET -eq 0 ]; then
echo "Upgrade Complete."
logger "Upgrade Complete."
else
echo "Upgrade End with error: $RET !!"
logger "Upgrade End with error: $RET !!"
fi
return $RET
}
# check md5
check_upgradefile_md5() {
$MD5SUM -c $UPGRADE_DIR/$UPGRADE_LIST
RET=$?
return $RET
}
# check disk space
check_free_disk() {
FUNCNAME="check_free_disk()"
RET=0
UPGRADE_FILE_SIZE=$(du -ks $UPGRADE_DIR | $AWK '{print $1}')
echo "[$PROCESS_NAME $FUNCNAME] UPGRADE_FILE_SIZE:$UPGRADE_FILE_SIZE"
logger "[$PROCESS_NAME $FUNCNAME] UPGRADE_FILE_SIZE:$UPGRADE_FILE_SIZE"
# 获取可用空间
DISK_SPACE=$($DF $EMBER_DISK | grep "$EMBER_DISK" | $AWK '{print $4}')
echo "[$PROCESS_NAME $FUNCNAME] DISK_SPACE:$DISK_SPACE"
logger "[$PROCESS_NAME $FUNCNAME] DISK_SPACE:$DISK_SPACE"
if [ $DISK_SPACE -lt $UPGRADE_FILE_SIZE ]; then
echo "[$PROCESS_NAME $FUNCNAME] Disk space Not enough! $DISK_SPACE < $UPGRADE_FILE_SIZE"
logger "[$PROCESS_NAME $FUNCNAME] Disk space Not enough! $DISK_SPACE < $UPGRADE_FILE_SIZE"
RET=128
fi
return $RET
}
# clear upgrade files
clean_upgrade() {
echo "Clean Upgrade files."
logger "Clean Upgrade files."
rm -rf $UPGRADE_DIR
}
main() {
FUNCNAME="main()"
# 1. 准备环境
echo "[$PROCESS_NAME $FUNCNAME] enter prepare"
logger "[$PROCESS_NAME $FUNCNAME] enter prepare"
prepare
set_busybox
if [ ! -s $UPGRADE_DIR/$UPGRADE_LIST ]; then
echo "[$PROCESS_NAME $FUNCNAME] upgrade_list $UPGRADE_LIST is not exist, error!!"
logger "[$PROCESS_NAME $FUNCNAME] upgrade_list $UPGRADE_LIST is not exist, error!!"
remount_ro_partition
exit 1
fi
# 检查 md5 值
cd $UPGRADE_DIR
check_upgradefile_md5
RET=$?
echo "[$PROCESS_NAME $FUNCNAME] check_upgradefile_md5 RET:$RET"
logger "[$PROCESS_NAME $FUNCNAME] check_upgradefile_md5 RET:$RET"
if [ $RET -ne 0 ]; then
echo "[$PROCESS_NAME $FUNCNAME] check_upgradefile_md5 RET error!!"
logger "[$PROCESS_NAME $FUNCNAME] check_upgradefile_md5 RET error!!"
remount_ro_partition
exit 1
fi
# 检查磁盘大小
check_free_disk
RET=$?
echo "[$PROCESS_NAME $FUNCNAME] check_free_disk RET:$RET"
logger "[$PROCESS_NAME $FUNCNAME] check_free_disk RET:$RET"
if [ $RET -ne 0 ]; then
echo "[$PROCESS_NAME $FUNCNAME] check_free_disk error!!"
logger "[$PROCESS_NAME $FUNCNAME] check_free_disk error!!"
# 空间不够时,尝试使用单个文件覆盖的方式 , 后续......
fi
# 停止 app
echo "[$PROCESS_NAME $FUNCNAME] stop apps"
logger "[$PROCESS_NAME $FUNCNAME] stop apps"
stop_all_app
if [ $RET -eq 0 ]; then
# 空间足够 开始升级
start_upgrade
else
# 空间不够 按单个覆盖方式升级
start_upgrade_userdata
fi
if [ $RET -ne 0 ]; then
echo "[$PROCESS_NAME $FUNCNAME] start_upgrade RET error!!"
logger "[$PROCESS_NAME $FUNCNAME] start_upgrade RET error!!"
# 错误不退出,直接重启系统,尝试重新安装一次
if [ ! -f $UPGRADE_FAIL_MARK ]; then
date > $UPGRADE_FAIL_MARK
sync
sleep 1
reboot
sleep 20
fi
fi
#升级成功,删除标记文件
rm -f $EMBER_DISK/$UPGRADE_MARK
rm -f $UPGRADE_FAIL_MARK
#升级成功,删除下载的文件
rm /userdata/app_oem_update.bin
# 清理
clean_upgrade
echo "[$PROCESS_NAME $FUNCNAME] upgrade done, start apps..."
logger "[$PROCESS_NAME $FUNCNAME] upgrade done, start apps..."
sync
# 启动 app
start_all_app
echo "[$PROCESS_NAME $FUNCNAME] upgrade done."
logger "[$PROCESS_NAME $FUNCNAME] upgrade done."
sync
}
UPGRADE_DIR=$1
echo "do_upgrade_oem $UPGRADE_DIR"
logger "do_upgrade_oem $UPGRADE_DIR"
# 主函数
main
remount_ro_partition
exit 0
OEM的目录结构
OTA升级包整体内部目录结构
具体的文件分析,我就不在这篇里面进行表述了。



