7783f31359
The sender domain has a DMARC Reject/Quarantine policy which disallows
sending mailing list messages using the original "From" header.
To mitigate this problem, the original message has been wrapped
automatically by the mailing list software.
This patch is in continuation of: commit 93aa860405
"procd: nand: make it possible to configure kernel and ubi partition"
The $CI_KERNPART variable should be used in place
of the fixed "kernel" partition name. This allows
targets to specifiy alternate names for the kernel
partition.
Cc: Chris Blake <chrisrblake93@gmail.com>
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
336 lines
8.2 KiB
Bash
336 lines
8.2 KiB
Bash
#!/bin/sh
|
|
# Copyright (C) 2014 OpenWrt.org
|
|
#
|
|
|
|
. /lib/functions.sh
|
|
|
|
# 'kernel' partition on NAND contains the kernel
|
|
CI_KERNPART="${CI_KERNPART:-kernel}"
|
|
|
|
# 'ubi' partition on NAND contains UBI
|
|
CI_UBIPART="${CI_UBIPART:-ubi}"
|
|
|
|
ubi_mknod() {
|
|
local dir="$1"
|
|
local dev="/dev/$(basename $dir)"
|
|
|
|
[ -e "$dev" ] && return 0
|
|
|
|
local devid="$(cat $dir/dev)"
|
|
local major="${devid%%:*}"
|
|
local minor="${devid##*:}"
|
|
mknod "$dev" c $major $minor
|
|
}
|
|
|
|
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
|
|
ubi_mknod "$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 )
|
|
ubi_mknod "$ubidevdir"
|
|
echo $ubidev
|
|
return 0
|
|
fi
|
|
done
|
|
}
|
|
|
|
nand_get_magic_long() {
|
|
dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
|
|
}
|
|
|
|
get_magic_long_tar() {
|
|
( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
|
|
}
|
|
|
|
identify_magic() {
|
|
local magic=$1
|
|
case "$magic" in
|
|
"55424923")
|
|
echo "ubi"
|
|
;;
|
|
"31181006")
|
|
echo "ubifs"
|
|
;;
|
|
"68737173")
|
|
echo "squashfs"
|
|
;;
|
|
"d00dfeed")
|
|
echo "fit"
|
|
;;
|
|
"4349"*)
|
|
echo "combined"
|
|
;;
|
|
*)
|
|
echo "unknown $magic"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
|
|
identify() {
|
|
identify_magic $(nand_get_magic_long "$1" "${2:-0}")
|
|
}
|
|
|
|
identify_tar() {
|
|
identify_magic $(get_magic_long_tar "$1" "$2")
|
|
}
|
|
|
|
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_prepare_ubi() {
|
|
local rootfs_length="$1"
|
|
local rootfs_type="$2"
|
|
local has_kernel="${3:-0}"
|
|
local has_env="${4:-0}"
|
|
|
|
local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
|
|
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" )"
|
|
[ "$has_env" -gt 0 ] && {
|
|
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 $CI_KERNPART )"
|
|
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
|
|
[ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true
|
|
[ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs || true
|
|
[ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
|
|
|
|
# update kernel
|
|
if [ "$has_kernel" = "1" ]; then
|
|
if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then
|
|
echo "cannot create kernel volume"
|
|
return 1;
|
|
fi
|
|
fi
|
|
|
|
# update rootfs
|
|
local root_size_param
|
|
if [ "$rootfs_type" = "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 [ "$rootfs_type" != "ubifs" ]; then
|
|
if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then
|
|
echo "cannot initialize rootfs_data volume"
|
|
return 1
|
|
fi
|
|
fi
|
|
sync
|
|
return 0
|
|
}
|
|
|
|
nand_do_upgrade_success() {
|
|
local conf_tar="/tmp/sysupgrade.tgz"
|
|
|
|
sync
|
|
[ -f "$conf_tar" ] && nand_restore_config "$conf_tar"
|
|
echo "sysupgrade successful"
|
|
umount -a
|
|
reboot -f
|
|
}
|
|
|
|
# Flash the UBI image to MTD partition
|
|
nand_upgrade_ubinized() {
|
|
local ubi_file="$1"
|
|
local mtdnum="$(find_mtd_index "$CI_UBIPART")"
|
|
|
|
[ ! "$mtdnum" ] && {
|
|
CI_UBIPART="rootfs"
|
|
mtdnum="$(find_mtd_index "$CI_UBIPART")"
|
|
}
|
|
|
|
if [ ! "$mtdnum" ]; then
|
|
echo "cannot find mtd device $CI_UBIPART"
|
|
umount -a
|
|
reboot -f
|
|
fi
|
|
|
|
local mtddev="/dev/mtd${mtdnum}"
|
|
ubidetach -p "${mtddev}" || true
|
|
sync
|
|
ubiformat "${mtddev}" -y -f "${ubi_file}"
|
|
ubiattach -p "${mtddev}"
|
|
nand_do_upgrade_success
|
|
}
|
|
|
|
# Write the UBIFS image to UBI volume
|
|
nand_upgrade_ubifs() {
|
|
local rootfs_length=`(cat $1 | wc -c) 2> /dev/null`
|
|
|
|
nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0"
|
|
|
|
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
|
|
local root_ubivol="$(nand_find_volume $ubidev rootfs)"
|
|
ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1
|
|
|
|
nand_do_upgrade_success
|
|
}
|
|
|
|
nand_board_name() {
|
|
if type 'platform_nand_board_name' >/dev/null 2>/dev/null; then
|
|
platform_nand_board_name
|
|
return
|
|
fi
|
|
|
|
cat /tmp/sysinfo/board_name
|
|
}
|
|
|
|
nand_upgrade_tar() {
|
|
local tar_file="$1"
|
|
local board_name="$(nand_board_name)"
|
|
local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
|
|
|
|
local kernel_length=`(tar xf $tar_file sysupgrade-$board_name/kernel -O | wc -c) 2> /dev/null`
|
|
local rootfs_length=`(tar xf $tar_file sysupgrade-$board_name/root -O | wc -c) 2> /dev/null`
|
|
|
|
local rootfs_type="$(identify_tar "$tar_file" sysupgrade-$board_name/root)"
|
|
|
|
local has_kernel=1
|
|
local has_env=0
|
|
|
|
[ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
|
|
tar xf $tar_file sysupgrade-$board_name/kernel -O | mtd write - $CI_KERNPART
|
|
}
|
|
[ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0
|
|
|
|
nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env"
|
|
|
|
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
|
|
[ "$has_kernel" = "1" ] && {
|
|
local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)"
|
|
tar xf $tar_file sysupgrade-$board_name/kernel -O | \
|
|
ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
|
|
}
|
|
|
|
local root_ubivol="$(nand_find_volume $ubidev rootfs)"
|
|
tar xf $tar_file sysupgrade-$board_name/root -O | \
|
|
ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
|
|
|
|
nand_do_upgrade_success
|
|
}
|
|
|
|
# Recognize type of passed file and start the upgrade process
|
|
nand_do_upgrade() {
|
|
if [ -n "$IS_PRE_UPGRADE" ]; then
|
|
# Previously, nand_do_upgrade was called from the platform_pre_upgrade
|
|
# hook; this piece of code handles scripts that haven't been
|
|
# updated. All scripts should gradually move to call nand_do_upgrade
|
|
# from platform_do_upgrade instead.
|
|
export do_upgrade=nand_do_upgrade
|
|
return
|
|
fi
|
|
|
|
local file_type=$(identify $1)
|
|
|
|
if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
|
|
platform_nand_pre_upgrade "$1"
|
|
fi
|
|
|
|
[ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
|
|
|
|
case "$file_type" in
|
|
"ubi") nand_upgrade_ubinized $1;;
|
|
"ubifs") nand_upgrade_ubifs $1;;
|
|
*) nand_upgrade_tar $1;;
|
|
esac
|
|
}
|
|
|
|
# Check if passed file is a valid one for NAND sysupgrade. Currently it accepts
|
|
# 3 types of files:
|
|
# 1) UBI - should contain an ubinized image, header is checked for the proper
|
|
# MAGIC
|
|
# 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume,
|
|
# header is checked for the proper MAGIC
|
|
# 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty
|
|
# "CONTROL" file (at this point its content isn't verified)
|
|
#
|
|
# You usually want to call this function in platform_check_image.
|
|
#
|
|
# $(1): board name, used in case of passing TAR file
|
|
# $(2): file to be checked
|
|
nand_do_platform_check() {
|
|
local board_name="$1"
|
|
local tar_file="$2"
|
|
local control_length=`(tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null`
|
|
local file_type="$(identify $2)"
|
|
|
|
[ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && {
|
|
echo "Invalid sysupgrade file."
|
|
return 1
|
|
}
|
|
|
|
return 0
|
|
}
|