Initial commit
This commit is contained in:
250
package/base-files/files/lib/upgrade/common.sh
Normal file
250
package/base-files/files/lib/upgrade/common.sh
Normal file
@@ -0,0 +1,250 @@
|
||||
#!/bin/sh
|
||||
|
||||
RAM_ROOT=/tmp/root
|
||||
|
||||
[ -x /usr/bin/ldd ] || ldd() { LD_TRACE_LOADED_OBJECTS=1 $*; }
|
||||
libs() { ldd $* 2>/dev/null | sed -r 's/(.* => )?(.*) .*/\2/'; }
|
||||
|
||||
install_file() { # <file> [ <file> ... ]
|
||||
local target dest dir
|
||||
for file in "$@"; do
|
||||
if [ -L "$file" ]; then
|
||||
target="$(readlink -f "$file")"
|
||||
dest="$RAM_ROOT/$file"
|
||||
[ ! -f "$dest" ] && {
|
||||
dir="$(dirname "$dest")"
|
||||
mkdir -p "$dir"
|
||||
ln -s "$target" "$dest"
|
||||
}
|
||||
file="$target"
|
||||
fi
|
||||
dest="$RAM_ROOT/$file"
|
||||
[ -f "$file" -a ! -f "$dest" ] && {
|
||||
dir="$(dirname "$dest")"
|
||||
mkdir -p "$dir"
|
||||
cp "$file" "$dest"
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
install_bin() {
|
||||
local src files
|
||||
src=$1
|
||||
files=$1
|
||||
[ -x "$src" ] && files="$src $(libs $src)"
|
||||
install_file $files
|
||||
}
|
||||
|
||||
run_hooks() {
|
||||
local arg="$1"; shift
|
||||
for func in "$@"; do
|
||||
eval "$func $arg"
|
||||
done
|
||||
}
|
||||
|
||||
ask_bool() {
|
||||
local default="$1"; shift;
|
||||
local answer="$default"
|
||||
|
||||
[ "$INTERACTIVE" -eq 1 ] && {
|
||||
case "$default" in
|
||||
0) echo -n "$* (y/N): ";;
|
||||
*) echo -n "$* (Y/n): ";;
|
||||
esac
|
||||
read answer
|
||||
case "$answer" in
|
||||
y*) answer=1;;
|
||||
n*) answer=0;;
|
||||
*) answer="$default";;
|
||||
esac
|
||||
}
|
||||
[ "$answer" -gt 0 ]
|
||||
}
|
||||
|
||||
v() {
|
||||
[ "$VERBOSE" -ge 1 ] && echo "$@"
|
||||
}
|
||||
|
||||
json_string() {
|
||||
local v="$1"
|
||||
v="${v//\\/\\\\}"
|
||||
v="${v//\"/\\\"}"
|
||||
echo "\"$v\""
|
||||
}
|
||||
|
||||
rootfs_type() {
|
||||
/bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }'
|
||||
}
|
||||
|
||||
get_image() { # <source> [ <command> ]
|
||||
local from="$1"
|
||||
local cmd="$2"
|
||||
|
||||
if [ -z "$cmd" ]; then
|
||||
local magic="$(dd if="$from" bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
|
||||
case "$magic" in
|
||||
1f8b) cmd="zcat";;
|
||||
425a) cmd="bzcat";;
|
||||
*) cmd="cat";;
|
||||
esac
|
||||
fi
|
||||
|
||||
cat "$from" 2>/dev/null | $cmd
|
||||
}
|
||||
|
||||
get_magic_word() {
|
||||
(get_image "$@" | dd bs=2 count=1 | hexdump -v -n 2 -e '1/1 "%02x"') 2>/dev/null
|
||||
}
|
||||
|
||||
get_magic_long() {
|
||||
(get_image "$@" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null
|
||||
}
|
||||
|
||||
export_bootdevice() {
|
||||
local cmdline uuid disk uevent line
|
||||
local MAJOR MINOR DEVNAME DEVTYPE
|
||||
|
||||
if read cmdline < /proc/cmdline; then
|
||||
case "$cmdline" in
|
||||
*block2mtd=*)
|
||||
disk="${cmdline##*block2mtd=}"
|
||||
disk="${disk%%,*}"
|
||||
;;
|
||||
*root=*)
|
||||
disk="${cmdline##*root=}"
|
||||
disk="${disk%% *}"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$disk" in
|
||||
PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-02)
|
||||
uuid="${disk#PARTUUID=}"
|
||||
uuid="${uuid%-02}"
|
||||
for disk in $(find /dev -type b); do
|
||||
set -- $(dd if=$disk bs=1 skip=440 count=4 2>/dev/null | hexdump -v -e '4/1 "%02x "')
|
||||
if [ "$4$3$2$1" = "$uuid" ]; then
|
||||
uevent="/sys/class/block/${disk##*/}/uevent"
|
||||
break
|
||||
fi
|
||||
done
|
||||
;;
|
||||
/dev/*)
|
||||
uevent="/sys/class/block/${disk##*/}/uevent"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -e "$uevent" ]; then
|
||||
while read line; do
|
||||
export -n "$line"
|
||||
done < "$uevent"
|
||||
export BOOTDEV_MAJOR=$MAJOR
|
||||
export BOOTDEV_MINOR=$MINOR
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
export_partdevice() {
|
||||
local var="$1" offset="$2"
|
||||
local uevent line MAJOR MINOR DEVNAME DEVTYPE
|
||||
|
||||
for uevent in /sys/class/block/*/uevent; do
|
||||
while read line; do
|
||||
export -n "$line"
|
||||
done < "$uevent"
|
||||
if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then
|
||||
export "$var=$DEVNAME"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
hex_le32_to_cpu() {
|
||||
[ "$(echo 01 | hexdump -v -n 2 -e '/2 "%x"')" == "3031" ] && {
|
||||
echo "${1:0:2}${1:8:2}${1:6:2}${1:4:2}${1:2:2}"
|
||||
return
|
||||
}
|
||||
echo "$@"
|
||||
}
|
||||
|
||||
get_partitions() { # <device> <filename>
|
||||
local disk="$1"
|
||||
local filename="$2"
|
||||
|
||||
if [ -b "$disk" -o -f "$disk" ]; then
|
||||
v "Reading partition table from $filename..."
|
||||
|
||||
local magic=$(dd if="$disk" bs=2 count=1 skip=255 2>/dev/null)
|
||||
if [ "$magic" != $'\x55\xAA' ]; then
|
||||
v "Invalid partition table on $disk"
|
||||
exit
|
||||
fi
|
||||
|
||||
rm -f "/tmp/partmap.$filename"
|
||||
|
||||
local part
|
||||
for part in 1 2 3 4; do
|
||||
set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk")
|
||||
|
||||
local type="$(( $(hex_le32_to_cpu $1) % 256))"
|
||||
local lba="$(( $(hex_le32_to_cpu $2) ))"
|
||||
local num="$(( $(hex_le32_to_cpu $3) ))"
|
||||
|
||||
[ $type -gt 0 ] || continue
|
||||
|
||||
printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
jffs2_copy_config() {
|
||||
if grep rootfs_data /proc/mtd >/dev/null; then
|
||||
# squashfs+jffs2
|
||||
mtd -e rootfs_data jffs2write "$CONF_TAR" rootfs_data
|
||||
else
|
||||
# jffs2
|
||||
mtd jffs2write "$CONF_TAR" rootfs
|
||||
fi
|
||||
}
|
||||
|
||||
# Flash firmware to MTD partition
|
||||
#
|
||||
# $(1): path to image
|
||||
# $(2): (optional) pipe command to extract firmware, e.g. dd bs=n skip=m
|
||||
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
|
||||
[ $? -ne 0 ] && exit 1
|
||||
}
|
||||
|
||||
do_upgrade_stage2() {
|
||||
v "Performing system upgrade..."
|
||||
if [ -n "$do_upgrade" ]; then
|
||||
eval "$do_upgrade"
|
||||
elif type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
|
||||
platform_do_upgrade "$IMAGE"
|
||||
else
|
||||
default_do_upgrade "$IMAGE"
|
||||
fi
|
||||
|
||||
if [ "$SAVE_CONFIG" -eq 1 ] && type 'platform_copy_config' >/dev/null 2>/dev/null; then
|
||||
platform_copy_config
|
||||
fi
|
||||
|
||||
v "Upgrade completed"
|
||||
sleep 1
|
||||
|
||||
v "Rebooting system..."
|
||||
umount -a
|
||||
reboot -f
|
||||
sleep 5
|
||||
echo b 2>/dev/null >/proc/sysrq-trigger
|
||||
}
|
||||
Reference in New Issue
Block a user