438dcbfe74
Depending on busybox applet selection, paths of basic utiilties may differ, and may not work as symlinks to busybox. Simply using whatever binary is found in PATH and detecting symlinks automatically is more robust and easier to maintain. The list of binaries is also slightly cleaned up and duplicates are removed. Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
238 lines
4.7 KiB
Bash
238 lines
4.7 KiB
Bash
#!/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 cat="$2"
|
|
|
|
if [ -z "$cat" ]; then
|
|
local magic="$(dd if="$from" bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
|
|
case "$magic" in
|
|
1f8b) cat="zcat";;
|
|
425a) cat="bzcat";;
|
|
*) cat="cat";;
|
|
esac
|
|
fi
|
|
|
|
$cat "$from" 2>/dev/null
|
|
}
|
|
|
|
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
|
|
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
|
|
. "$uevent"
|
|
|
|
export BOOTDEV_MAJOR=$MAJOR
|
|
export BOOTDEV_MINOR=$MINOR
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
export_partdevice() {
|
|
local var="$1" offset="$2"
|
|
local uevent MAJOR MINOR DEVNAME DEVTYPE
|
|
|
|
for uevent in /sys/class/block/*/uevent; do
|
|
. "$uevent"
|
|
if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then
|
|
export "$var=$DEVNAME"
|
|
return 0
|
|
fi
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
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="$(hexdump -v -n 2 -s 0x1FE -e '1/2 "0x%04X"' "$disk")"
|
|
if [ "$magic" != 0xAA55 ]; 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="$(($1 % 256))"
|
|
local lba="$(($2))"
|
|
local num="$(($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
|
|
}
|
|
|
|
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
|
|
}
|