[OpenWrt-Devel] [PATCH 4/8] mpc85xx: add firmware upgrade support for NM50

Dieter Pfeuffer dieter.pfeuffer at men.de
Wed Mar 23 08:17:28 EDT 2016


Signed-off-by: Dieter Pfeuffer <dieter.pfeuffer at men.de>
---
 scripts/men-mkfwupgrade.sh                         |  69 ++++++++
 target/linux/mpc85xx/base-files/lib/upgrade/men.sh | 188 +++++++++++++++++++++
 .../mpc85xx/base-files/lib/upgrade/platform.sh     |  10 +-
 3 files changed, 266 insertions(+), 1 deletion(-)
 create mode 100755 scripts/men-mkfwupgrade.sh
 create mode 100755 target/linux/mpc85xx/base-files/lib/upgrade/men.sh

diff --git a/scripts/men-mkfwupgrade.sh b/scripts/men-mkfwupgrade.sh
new file mode 100755
index 0000000..51f654e
--- /dev/null
+++ b/scripts/men-mkfwupgrade.sh
@@ -0,0 +1,69 @@
+#/bin/sh
+#
+# Copyright (c) 2016 MEN Mikro Elektronik GmbH
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+# 
+# Assemble individual sysupgrade image for MEN NM50 board. 
+#
+
+ME="${0##*/}"
+
+usage() {
+	echo "Usage: $ME <NM50> <upgrade bin> [-u <u-boot bin>] [-e <u-boot-env bin>] [-d <dtb bin>] [-k <kernel bin>] [-r <rootfs bin>]"
+	exit 1
+}
+
+[ "$#" -lt 4 ] && echo "*** to less arguments (at least one '-' option required)" && usage
+
+BOARD=$1
+BIN_OUT=$2
+
+case $BOARD in
+	NM50)
+		board=men_nm50
+		;;
+	*)
+		echo "Error - unsupported board: $BOARD"
+		exit 1
+		;;
+esac
+
+shift 2
+
+while [[ $# > 1 ]]
+do
+arg="$1"
+case $arg in
+    -u)
+    UBOOT="$2 u-boot"
+	shift
+    ;;
+    -e)
+    UBOOT_ENV="$2 u-boot-env"
+	shift
+    ;;
+    -d)
+    DTB="$2 dtb"
+	shift
+    ;;
+    -k)
+    KERNEL="$2 kernel"
+	shift
+    ;;
+    -r)
+    ROOTFS="$2 rootfs"
+	shift
+    ;;
+    *)
+		echo "Error - unsupported option: $arg"
+		usage
+		exit 1
+    ;;
+esac
+shift
+done
+
+$(dirname $0)/combined-ext-image.sh $board $BIN_OUT \
+	$UBOOT $UBOOT_ENV $DTB $KERNEL $ROOTFS 
diff --git a/target/linux/mpc85xx/base-files/lib/upgrade/men.sh b/target/linux/mpc85xx/base-files/lib/upgrade/men.sh
new file mode 100755
index 0000000..0fc214d
--- /dev/null
+++ b/target/linux/mpc85xx/base-files/lib/upgrade/men.sh
@@ -0,0 +1,188 @@
+#
+# Copyright (c) 2016 MEN Mikro Elektronik GmbH
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+# 
+# The MEN NM50 flash partitions can be individually updated with one combined
+# image file. The file header (64K) stores information about the target device,
+# the number of included binary files and for each included binary file, the
+# name of the dedicated partition, size and md5 checksum of the binary file.
+# Make creates an OpenWrt upgrade image (dtb + kernel + rootfs). Individual
+# upgrade images (e.g. for u-boot + kernel) can be created with the
+# men-mkfwupgrade.sh shell script. 
+# For detailed information of the combined image format, see the
+# combined-ext-image.sh shell script (used from mpc85xx/image/Makefile and
+# men-mkfwupgrade.sh).
+#
+
+trim()
+{
+	echo $1
+}
+
+platform_check_image_men()
+{
+	local img_magic=$1
+	local img_path=$2
+	local img_board_target= img_num_files=
+
+	case "$img_magic" in
+		# Combined Extended Image v1
+		43453031)
+			img_board_target=$(trim $(dd if="$img_path" bs=4 skip=1 count=8 2>/dev/null))
+			img_num_files=$(trim $(dd if="$img_path" bs=2 skip=18 count=1 2>/dev/null))
+			;;
+		*)
+			echo "Invalid image ($img_magic). Use combined extended images on this platform."
+			return 1
+			;;
+	esac
+
+	case "$img_board_target" in
+		men_nm50)
+			eepromid=$(dd if=/sys/bus/i2c/drivers/at24/0-0054/eeprom bs=1 count=6 skip=9 2>/dev/null)
+			([ $eepromid != "SC29" ]) && {
+				echo "Invalid board ($eepromid). Use the correct image for this platform."
+				return 1
+			}					
+			;;
+		*)
+			echo "Invalid board target ($img_board_target). Use the correct image for this platform."
+			return 1
+			;;
+	esac
+
+	# check number of files
+	([ $img_num_files -lt 1 ] || [ $img_num_files -gt 8 ]) && {
+		echo "Invalid number of embedded images ($img_num_files). Use the correct image for this platform."
+		return 1
+	}
+
+	# further checking (no upgrade yet)
+	platform_do_upgrade_men 0 "$2" && return 0
+	return 1
+}
+
+platform_find_partition() {
+	local dev size erasesize name
+	while read dev size erasesize name; do
+		name=${name#'"'}; name=${name%'"'}
+		[ "$name" = "$1" ] && {
+			echo "$dev$size:$erasesize:$name"
+			return
+		}
+	done < /proc/mtd
+	echo "error"
+}
+
+platform_do_upgrade_men()
+{
+	local doit=$1 
+	local img_path=$2 
+	local data_offset=$((64 * 1024)) offset=
+	local img_num_files= part_name= part_size= data_size= data_md5=
+	local ret= i=0 calc_md5=
+	local magic= magic_of=
+
+	img_num_files=$(trim $(dd if="$img_path" bs=2 skip=18 count=1 2>/dev/null))
+
+	offset=$data_offset
+	while [ "$i" -lt "$img_num_files" ]
+	do
+		part_name=$(trim $(dd if="$img_path" bs=2 skip=$((19 + i * 36)) count=16 2>/dev/null))
+		data_size=0x$(dd if="$img_path" bs=2 skip=$((35 + i * 36)) count=4 2>/dev/null)
+		data_md5=$(dd if="$img_path" bs=2 skip=$((39 + i * 36)) count=16 2>/dev/null)
+
+		ret=$(platform_find_partition $part_name)
+		[ $ret = "error" ] && {
+			echo "Unknown partition name ($part_name) for this platform: $board. Use the correct image for this platform."
+			return 1
+		}
+		
+		# further checking only 
+		if [ $doit = "0" ] 
+		then
+
+			part_size=${ret#*:}
+			part_size=0x${part_size%%:*}
+		
+			# check if partition is accessible/writable
+			mtd -n write /dev/null $part_name 2>&-
+			if [ $? = 1 ]; then			
+				echo "Partition $part_name is not accessible/writable. Use the correct image for this platform."
+				echo "Note: You may first need to perform an upgrade with an other image to make $part_name writable."
+				return 1
+			fi
+	
+			# check file size
+			[ $((data_size)) -gt $((part_size)) ] && {
+				echo "Data size ($data_size) greater than partition size ($part_size) of partition $part_name. Use the correct image for this platform."
+				return 1
+			}
+
+			# check md5
+			calc_md5=$(dd if=$img_path bs=1 skip=$offset count=$((data_size)) 2>&- | md5sum)
+			calc_md5=${calc_md5/-/}
+			[ $calc_md5 != $data_md5 ] && {
+				echo "Invalid md5 checksum (data_md5=$data_md5 != $calc_md5) for partition $part_name. Use the correct image for this platform."
+				return 1
+			}
+			
+			# check binary data
+			# u-boot: +0x40: 424f 4f54
+			# fdt: d00d feed
+			# kernel: 2705 1956
+			# rootfs: 6873 7173
+			case $part_name in
+			u-boot)
+				magic_of=$((offset + 0x40))
+				magic=0x424f4f54
+				;;	
+			# todo: crc32 tool not available in OpenWrt and cksum computes a different CRC32 value
+			#u-boot-env)
+			#	magic_of=$offset
+			#	magic=0x$(crc32 <(dd if="$img_path" bs=1 skip=$((offset + 4)) count=$((data_size)) 2>&-))
+			#	;;	
+			dtb)
+				magic_of=$offset			
+				magic=0xd00dfeed
+				;;	
+			kernel)
+				magic_of=$offset			
+				magic=0x27051956
+				;;	
+			rootfs)
+				magic_of=$offset			
+				magic=0x68737173
+				;;	
+			*)
+				magic_of=0			
+				;;
+			esac			
+			
+			if [ $magic_of != 0 ]
+			then
+				data_magic=0x$(xxd -s $magic_of -l 4 -g 4 -ps $img_path 2>&-)
+				[ $data_magic != $magic ]  && {
+					echo "Invalid image (data_magic=$data_magic != $magic) for partition $part_name. Use the correct image for this platform."
+					return 1
+				}
+			fi			
+			
+		# upgrade only
+		else		
+			if [ $part_name =  "rootfs" ] && [ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 ]
+			then
+				dd if="$img_path" bs=1 skip=$offset count=$((data_size)) 2>&- | mtd $MTD_CONFIG_ARGS -j "$CONF_TAR" write - "$part_name"			
+			else
+				dd if="$img_path" bs=1 skip=$offset count=$((data_size)) 2>&- | mtd $MTD_CONFIG_ARGS write - "$part_name"
+			fi		
+		fi
+		
+		offset=$((offset + data_size))
+		i=$((i+1))
+	done  	
+
+	return 0
+}
diff --git a/target/linux/mpc85xx/base-files/lib/upgrade/platform.sh b/target/linux/mpc85xx/base-files/lib/upgrade/platform.sh
index d95ec30..b693c05 100755
--- a/target/linux/mpc85xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mpc85xx/base-files/lib/upgrade/platform.sh
@@ -58,6 +58,11 @@ platform_check_image() {
 
 		return 0
 		;;
+		
+	men_nm50)
+		platform_check_image_men "$magic" "$1" && return 0
+		return 1
+		;;		
 	esac
 
 	echo "Sysupgrade is not yet supported on $board."
@@ -67,7 +72,10 @@ platform_check_image() {
 platform_do_upgrade() {
 	local board=$(mpc85xx_board_name)
 
-	case "$board" in
+	case $board in
+	men_nm50)
+		platform_do_upgrade_men 1 "$ARGV"
+		;;	
 	*)
 		default_do_upgrade "$ARGV"
 		;;
-- 
1.9.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list