bzip2 adds about 8kb of size. For tiny builds it's often disabled.
It's not directly used by stock OpenWrt programs.
Kernel images compressed with bzip2 are also not fully supported.
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
[fix \ indention]
Signed-off-by: Paul Spooren <mail@aparcar.org>
(cherry picked from commit bffee5ea19)
328 lines
7.8 KiB
Bash
Executable File
328 lines
7.8 KiB
Bash
Executable File
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() {
|
|
[ -n "$VERBOSE" ] && [ "$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";;
|
|
*) cmd="cat";;
|
|
esac
|
|
fi
|
|
|
|
cat "$from" 2>/dev/null | $cmd
|
|
}
|
|
|
|
get_image_dd() {
|
|
local from="$1"; shift
|
|
|
|
(
|
|
exec 3>&2
|
|
( exec 3>&2; get_image "$from" 2>&1 1>&3 | grep -v -F ' Broken pipe' ) 2>&1 1>&3 \
|
|
| ( exec 3>&2; dd "$@" 2>&1 1>&3 | grep -v -E ' records (in|out)') 2>&1 1>&3
|
|
exec 3>&-
|
|
)
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
get_magic_gpt() {
|
|
(get_image "$@" | dd bs=8 count=1 skip=64) 2>/dev/null
|
|
}
|
|
|
|
get_magic_vfat() {
|
|
(get_image "$@" | dd bs=1 count=3 skip=54) 2>/dev/null
|
|
}
|
|
|
|
part_magic_efi() {
|
|
local magic=$(get_magic_gpt "$@")
|
|
[ "$magic" = "EFI PART" ]
|
|
}
|
|
|
|
part_magic_fat() {
|
|
local magic=$(get_magic_vfat "$@")
|
|
[ "$magic" = "FAT" ]
|
|
}
|
|
|
|
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]-[A-F0-9][A-F0-9][A-F0-9][A-F0-9]-[A-F0-9][A-F0-9][A-F0-9][A-F0-9]-[A-F0-9][A-F0-9][A-F0-9][A-F0-9]-[A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9]0002)
|
|
uuid="${disk#PARTUUID=}"
|
|
uuid="${uuid%0002}0002"
|
|
for disk in $(find /dev -type b); do
|
|
set -- $(dd if=$disk bs=1 skip=$((2*512+256+128+16)) count=16 2>/dev/null | hexdump -v -e '4/1 "%02x"' | awk '{ \
|
|
for(i=1;i<9;i=i+2) first=substr($0,i,1) substr($0,i+1,1) first; \
|
|
for(i=9;i<13;i=i+2) second=substr($0,i,1) substr($0,i+1,1) second; \
|
|
for(i=13;i<16;i=i+2) third=substr($0,i,1) substr($0,i+1,1) third; \
|
|
fourth = substr($0,17,4); \
|
|
five = substr($0,21,12); \
|
|
} END { print toupper(first"-"second"-"third"-"fourth"-"five) }')
|
|
if [ "$1" = "$uuid" ]; then
|
|
uevent="/sys/class/block/${disk##*/}/uevent"
|
|
export SAVE_PARTITIONS=0
|
|
break
|
|
fi
|
|
done
|
|
;;
|
|
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
|
|
;;
|
|
PARTUUID=????????-????-????-????-??????????02)
|
|
uuid="${rootpart#PARTUUID=}"
|
|
uuid="${uuid%02}00"
|
|
for disk in $(find /dev -type b); do
|
|
set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
|
|
if [ "$4$3$2$1-$6$5-$8$7-$9" = "$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
|
|
part_magic_efi "$disk" && {
|
|
#export_partdevice will fail when partition number is greater than 15, as
|
|
#the partition major device number is not equal to the disk major device number
|
|
for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
|
|
set -- $(hexdump -v -n 48 -s "$((0x380 + $part * 0x80))" -e '4/4 "%08x"" "4/4 "%08x"" "4/4 "0x%08X "' "$disk")
|
|
|
|
local type="$1"
|
|
local lba="$(( $(hex_le32_to_cpu $4) * 0x100000000 + $(hex_le32_to_cpu $3) ))"
|
|
local end="$(( $(hex_le32_to_cpu $6) * 0x100000000 + $(hex_le32_to_cpu $5) ))"
|
|
local num="$(( $end - $lba ))"
|
|
|
|
[ "$type" = "00000000000000000000000000000000" ] && continue
|
|
|
|
printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename"
|
|
done
|
|
} || {
|
|
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
|
|
}
|
|
|
|
indicate_upgrade() {
|
|
. /etc/diag.sh
|
|
set_state upgrade
|
|
}
|
|
|
|
# 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
|
|
}
|