Signed-off-by: John Crispin <blogic@openwrt.org> SVN-Revision: 41129master
parent
3417834ffc
commit
1e876b4191
@ -0,0 +1,303 @@ |
||||
#!/bin/sh |
||||
# Copyright (C) 2014 OpenWrt.org |
||||
# |
||||
|
||||
. /lib/functions.sh |
||||
|
||||
# combined-image uses 64k blocks |
||||
CI_BLKSZ=65536 |
||||
# 'data' partition on NAND contains UBI |
||||
CI_UBIPART="ubi" |
||||
|
||||
nand_find_volume() { |
||||
local ubidevdir ubivoldir |
||||
ubidevdir="/sys/devices/virtual/ubi/$1" |
||||
[ ! -d "$ubidevdir" ] && return 1 |
||||
for ubivoldir in $ubidevdir/${1}_*; do |
||||
[ ! -d "$ubivoldir" ] && continue |
||||
if [ "$( cat $ubivoldir/name )" = "$2" ]; then |
||||
basename $ubivoldir |
||||
return 0 |
||||
fi |
||||
done |
||||
} |
||||
|
||||
nand_find_ubi() { |
||||
local ubidevdir ubidev mtdnum |
||||
mtdnum="$( find_mtd_index $1 )" |
||||
[ ! "$mtdnum" ] && return 1 |
||||
for ubidevdir in /sys/devices/virtual/ubi/ubi*; do |
||||
[ ! -d "$ubidevdir" ] && continue |
||||
cmtdnum="$( cat $ubidevdir/mtd_num )" |
||||
[ ! "$mtdnum" ] && continue |
||||
if [ "$mtdnum" = "$cmtdnum" ]; then |
||||
ubidev=$( basename $ubidevdir ) |
||||
echo $ubidev |
||||
return 0 |
||||
fi |
||||
done |
||||
} |
||||
|
||||
nand_restore_config() { |
||||
sync |
||||
local ubidev=$( nand_find_ubi $CI_UBIPART ) |
||||
local ubivol="$( nand_find_volume $ubidev rootfs_data )" |
||||
[ ! "$ubivol" ] && |
||||
ubivol="$( nand_find_volume $ubidev rootfs )" |
||||
mkdir /tmp/new_root |
||||
if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then |
||||
echo "mounting ubifs $ubivol failed" |
||||
rmdir /tmp/new_root |
||||
return 1 |
||||
fi |
||||
mv "$1" "/tmp/new_root/sysupgrade.tgz" |
||||
umount /tmp/new_root |
||||
sync |
||||
rmdir /tmp/new_root |
||||
} |
||||
|
||||
nand_upgrade_ubinized() { |
||||
local upgrade_image="$1" |
||||
local conf_tar="$2" |
||||
local save_config="$3" |
||||
local mtdnum="$( find_mtd_index "$CI_UBIPART" )" |
||||
if [ ! "$mtdnum" ]; then |
||||
echo "cannot find mtd device $CI_UBIPART" |
||||
return 1; |
||||
fi |
||||
local mtddev="/dev/mtd${mtdnum}" |
||||
ubidetach -p "${mtddev}" || true |
||||
sync |
||||
ubiformat "${mtddev}" -y -f "$upgrade_image" |
||||
ubiattach -p "${mtddev}" |
||||
sync |
||||
if [ -f "$conf_tar" -a "$save_config" -eq 1 ]; then |
||||
nand_restore_config "$conf_tar" |
||||
fi |
||||
return 0; |
||||
} |
||||
|
||||
# get the first 4 bytes (magic) of a given file starting at offset in hex format |
||||
get_magic_long_at() { |
||||
dd if="$2" skip=$1 bs=$CI_BLKSZ count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' |
||||
} |
||||
|
||||
identify() { |
||||
local block; |
||||
local magic=$( get_magic_long_at ${2:-0} "$1" ) |
||||
case "$magic" in |
||||
"55424923") |
||||
echo "ubi" |
||||
;; |
||||
"31181006") |
||||
echo "ubifs" |
||||
;; |
||||
"68737173") |
||||
echo "squashfs" |
||||
;; |
||||
"d00dfeed") |
||||
echo "fit" |
||||
;; |
||||
"4349"*) |
||||
echo "combined" |
||||
;; |
||||
*) |
||||
echo "unknown $magic" |
||||
;; |
||||
esac |
||||
} |
||||
|
||||
nand_upgrade_combined_ubi() { |
||||
local kernel_image="$1" |
||||
local kernel_length=0 |
||||
local rootfs_image="$2" |
||||
local rootfs_length=`ls -la $rootfs_image | awk '{ print $5}')` |
||||
local conf_tar="$3" |
||||
local has_env="${4:-0}" |
||||
|
||||
local root_fs="$( identify "$rootfs_image" )" |
||||
local mtdnum="$( find_mtd_index "$CI_UBIPART" )" |
||||
local has_kernel=0 |
||||
|
||||
[ -z "$kernel_image" ] || { |
||||
has_kernel=1 |
||||
kernel_length=`ls -la $kernel_image | awk '{ print $5}')` |
||||
echo "kernel length $kernel_length" |
||||
} |
||||
[ "$has_kernel" = 0 ] || echo "kernel is inside ubi" |
||||
echo "rootfs type $root_fs, length $rootfs_length" |
||||
|
||||
if [ ! "$mtdnum" ]; then |
||||
echo "cannot find ubi mtd partition $CI_UBIPART" |
||||
return 1 |
||||
fi |
||||
local ubidev="$( nand_find_ubi "$CI_UBIPART" )" |
||||
if [ ! "$ubidev" ]; then |
||||
ubiattach -m "$mtdnum" |
||||
sync |
||||
ubidev="$( nand_find_ubi "$CI_UBIPART" )" |
||||
fi |
||||
if [ ! "$ubidev" ]; then |
||||
ubiformat /dev/mtd$mtdnum -y |
||||
ubiattach -m "$mtdnum" |
||||
sync |
||||
ubidev="$( nand_find_ubi "$CI_UBIPART" )" |
||||
[ -z "$has_env" ] || { |
||||
ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB |
||||
ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB |
||||
} |
||||
fi |
||||
local kern_ubivol="$( nand_find_volume $ubidev kernel )" |
||||
local root_ubivol="$( nand_find_volume $ubidev rootfs )" |
||||
local data_ubivol="$( nand_find_volume $ubidev rootfs_data )" |
||||
|
||||
# remove ubiblock device of rootfs |
||||
local root_ubiblk="ubiblock${root_ubivol:3}" |
||||
if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then |
||||
echo "removing $root_ubiblk" |
||||
if ! ubiblock -r /dev/$root_ubivol; then |
||||
echo "cannot remove $root_ubiblk" |
||||
return 1; |
||||
fi |
||||
fi |
||||
|
||||
# kill volumes |
||||
if [ "$kern_ubivol" ]; then |
||||
ubirmvol /dev/$ubidev -N kernel || true |
||||
fi |
||||
if [ "$root_ubivol" ]; then |
||||
ubirmvol /dev/$ubidev -N rootfs || true |
||||
fi |
||||
if [ "$data_ubivol" ]; then |
||||
ubirmvol /dev/$ubidev -N rootfs_data || true |
||||
fi |
||||
|
||||
# update kernel |
||||
if [ "$has_kernel" = "1" ]; then |
||||
if ! ubimkvol /dev/$ubidev -N kernel -s $kernel_length; then |
||||
echo "cannot create kernel volume" |
||||
return 1; |
||||
fi |
||||
fi |
||||
|
||||
# update rootfs |
||||
local root_size_param |
||||
if [ "$root_fs" = "ubifs" ]; then |
||||
root_size_param="-m" |
||||
else |
||||
root_size_param="-s $rootfs_length" |
||||
fi |
||||
if ! ubimkvol /dev/$ubidev -N rootfs $root_size_param; then |
||||
echo "cannot create rootfs volume" |
||||
return 1; |
||||
fi |
||||
|
||||
# create rootfs_data for non-ubifs rootfs |
||||
if [ "$root_fs" != "ubifs" ]; then |
||||
if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then |
||||
echo "cannot initialize rootfs_data volume" |
||||
return 1 |
||||
fi |
||||
fi |
||||
sync |
||||
|
||||
if [ "$has_kernel" = "1" ]; then |
||||
local kern_ubivol="$( nand_find_volume $ubidev kernel )" |
||||
ubiupdatevol /dev/$kern_ubivol -s $kernel_length $kernel_image |
||||
fi |
||||
|
||||
local root_ubivol="$( nand_find_volume $ubidev rootfs )" |
||||
ubiupdatevol /dev/$root_ubivol -s $rootfs_length $rootfs_image |
||||
if [ -f "$conf_tar" ]; then |
||||
nand_restore_config "$conf_tar" |
||||
fi |
||||
echo "sysupgrade successfull" |
||||
return 0 |
||||
} |
||||
|
||||
nand_do_upgrade_stage1() { |
||||
local board_name="$1" |
||||
local tar_file="$2" |
||||
local kernel_file="" |
||||
local kernel_file="" |
||||
|
||||
tar xzf $tar_file -C /tmp/ |
||||
[ -f "/tmp/sysupgrade-$board_name/CONTROL" ] || { |
||||
echo "failed to find /tmp/sysupgrade-$board_name/CONTROL" |
||||
return 1 |
||||
} |
||||
|
||||
kernel_file=/tmp/sysupgrade-$board_name/kernel |
||||
[ -f "$kernel_file" ] || { |
||||
echo "$kernel_file is missing" |
||||
return 1 |
||||
} |
||||
|
||||
rootfs_file=/tmp/sysupgrade-$board_name/root |
||||
[ -f "$rootfs_file" ] || { |
||||
echo "$rootfs_file is missing" |
||||
return 1 |
||||
} |
||||
|
||||
echo -n /tmp/sysupgrade-$board_name > /tmp/sysupgrade-nand-folder |
||||
cp /sbin/upgraded /tmp/ |
||||
|
||||
return 0 |
||||
} |
||||
|
||||
nand_do_upgrade_stage2() { |
||||
rootfs_file=$1/root |
||||
kernel_file=$1/kernel |
||||
config_file=$1/config |
||||
|
||||
[ -f $config_file ] || config_file="" |
||||
|
||||
. $1/CONTROL |
||||
|
||||
[ "$UBI_KERNEL" = "1" ] || { |
||||
mtd write $kernel_file kernel |
||||
kernel_file="" |
||||
} |
||||
nand_upgrade_combined_ubi "$kernel_file" "$rootfs_file" "$conf_tar" "$UBI_ENV" |
||||
reboot -f |
||||
} |
||||
|
||||
nand_do_upgrade() { |
||||
[ $1 = "nand" ] && { |
||||
[ -d "$2" ] && { |
||||
touch /tmp/sysupgrade |
||||
|
||||
killall -9 telnetd |
||||
killall -9 dropbear |
||||
killall -9 ash |
||||
|
||||
kill_remaining TERM |
||||
sleep 3 |
||||
kill_remaining KILL |
||||
|
||||
sleep 1 |
||||
|
||||
if [ -n "$(rootfs_type)" ]; then |
||||
v "Switching to ramdisk..." |
||||
run_ramfs ". /lib/functions.sh; include /lib/upgrade; nand_do_upgrade_stage2 $2" |
||||
else |
||||
nand_do_upgrade_stage2 $2 |
||||
fi |
||||
return 0 |
||||
} |
||||
echo "Nand upgrade failed" |
||||
exit 1 |
||||
} |
||||
} |
||||
|
||||
nand_upgrade_stage1() { |
||||
[ -f /tmp/sysupgrade-nand-folder ] && { |
||||
folder="$(cat /tmp/sysupgrade-nand-folder)" |
||||
[ "$SAVE_CONFIG" = 1 -a -f "$CONF_TAR" ] && |
||||
cp $CONF_TAR $folder/config |
||||
|
||||
ubus call system nandupgrade "{\"folder\": \"$folder\" }" |
||||
exit 0 |
||||
} |
||||
} |
||||
append sysupgrade_pre_upgrade nand_upgrade_stage1 |
Loading…
Reference in new issue