Patchwork Add util/pad_image.sh.

login
register
about
Submitter Stefan Tauner
Date 2013-10-28 01:41:19
Message ID <1382924479-27428-1-git-send-email-stefan.tauner@student.tuwien.ac.at>
Download mbox | patch
Permalink /patch/4087/
State New
Headers show

Comments

Stefan Tauner - 2013-10-28 01:41:19
A convenient POSIX shell script to pad images by prepending or appending
constant data to prepare them for flashrom digestion.

Signed-off-by: Stefan Tauner <stefan.tauner@student.tuwien.ac.at>
---

Preparing images for iPXE was a pain without this (I had to build it many
times for debugging), and it is probably useful for other use cases too.

The only thing missing is a mode that repeats the file every 2^N bytes
where 2^N is the nearest larger power of two to the length of the image
to be padded, e.g. if you want to write a 256 kB chip in a 3Com NIC that
does only support up to 128 kB/is one address line short.

And maybe a SI-prefix parser... but first flashrom should get one ;)

 util/pad_image.sh | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 222 insertions(+)
 create mode 100755 util/pad_image.sh

Patch

diff --git a/util/pad_image.sh b/util/pad_image.sh
new file mode 100755
index 0000000..30813f4
--- /dev/null
+++ b/util/pad_image.sh
@@ -0,0 +1,222 @@ 
+#!/bin/sh
+#
+# This file is part of the flashrom project.
+#
+# Copyright (C) 2013 Stefan Tauner
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+#
+
+assert_cmds_avail () {
+	while [ $# -gt 0 ];
+	do
+		command -v $1 >/dev/null 2>&1 || {
+			echo "$1 is required."
+			exit 1
+		}
+		shift
+	done
+}
+
+assert_cmds_avail "cat" "cp" "dd" "mv" "printf" "tr" "wc"
+
+show_help() {
+	echo "Usage:
+	$0 [-a|-p] [-h] [-f] -i <infile> [-o <outfile>] -s <size> [-v <val>]
+
+	Copies infile into outfile and fills up the remaining space to size with val.
+Options
+    -h or --help
+        this message
+    -a or --append
+        append the padding (default)
+    -p or --prepend
+        prepend the padding
+    -f or --force
+        force to overwrite existing output file
+    -i or --infile <infile>
+        the input file
+    -o or --outfile <outfile>
+        the output file (\"<infile>-padded\" on default)
+    -s or --size <size>
+        the wanted size of the output file in bytes
+    -v or --value <value>
+        the value in common hexadecimal format to be used for padding (0xFF on default)
+"
+}
+
+check_action() {
+	if [ -n "$action" ]; then
+		echo "Error: Multiple actions given.">&2
+		exit 1
+	fi
+}
+
+check_arg() {
+	if [ -z "$2" ]; then
+		echo "Error: $1 requires an argument.">&2
+		exit 1
+	fi
+}
+
+
+prepend () {
+	 { tr '\0' $(printf "\\\\%o" "$val") < /dev/zero | dd bs=1 count=$padsize of="$outfile".tmp && \
+		cat "$infile" >> "$outfile".tmp && \
+		mv -f "$outfile".tmp "$outfile" ; } >/dev/null 2>&1 || \
+		return 1
+}
+
+append () {
+	{ cp "$infile" "$outfile".tmp && tr '\0' $(printf "\\\\%o" "$val") < /dev/zero | \
+		dd bs=1 count=$padsize of="$outfile".tmp conv=notrunc seek=$filesize && \
+		mv -f "$outfile".tmp "$outfile" ; } >/dev/null 2>&1 || \
+		return 1;
+}
+
+main () {
+	local action=
+	local outfile=
+	local infile=
+	local size=
+	local val=
+	local force=
+
+	# The is the main loop
+	while [ $# -gt 0 ];
+	do
+		case ${1} in
+		-h|--help)
+			action=show_help;
+			shift;;
+		-a|--append)
+			check_action $1
+			action=append
+			shift;;
+		-p|--prepend)
+			check_action $1
+			action=prepend
+			shift;;
+		-f|--force)
+			force=1
+			shift;;
+		-i|--infile)
+			if [ -z "$infile" ] ; then
+				check_arg $1 $2
+				infile=$2
+			else
+				echo "Error: More than one input file given.">&2;
+				exit 1
+			fi
+			shift 2;;
+		-o|--outfile)
+			if [ -z "$outfile" ] ; then
+				check_arg $1 $2
+				outfile=$2
+			else
+				echo "Error: More than one output file given.">&2;
+				exit 1
+			fi
+			shift 2;;
+		-v|--value)
+			if [ -z "$val" ] ; then
+				check_arg $1 $2
+				val=$2
+			else
+				echo "Error: More than one value given.">&2;
+				exit 1
+			fi
+			shift 2;;
+		-s|--size)
+			if [ -z "$size" ] ; then
+				check_arg $1 $2
+				size=$2
+				case $size in
+					''|[!0-9]*) echo "Error: Could not parse size $size.">&2; exit 1;;
+					*) ;;
+				esac
+			else
+				echo "Error: More than one size given.">&2;
+				exit 1
+			fi
+			shift 2;;
+		-*)
+			show_help;
+			echo "Error: Invalid option: ${1}">&2
+			exit 1;;
+		*)
+			echo "Error: Overabundant parameter: \"${1}\"">&2
+			shift;;
+		esac;
+	done
+
+	if [ -z "$infile" ] ; then
+		show_help
+		echo "Error: No input file specified">&2
+		exit 1
+	fi
+
+	if [ ! -e "$infile" -o ! -r "$infile" -o ! -w "$infile" ]; then
+		echo "Error: ${infile} is not accessible">&2
+		exit 1
+	fi
+
+	if [ -z "$outfile" ] ; then
+		outfile="${infile}-padded"
+	fi
+
+	if [ -z "$force" -a -e "$outfile" ]; then
+		echo "Error: ${outfile} exists already.">&2
+		exit 1
+	fi
+
+	if [ -z "$size" ] ; then
+		show_help
+		echo "Error: No target size specified.">&2
+		exit 1
+	fi
+
+	filesize=$(wc -c < "$infile") || exit 1
+	if [ $size -le $filesize ]; then
+		echo "File is already as large as or even larger than requested.">&2
+		exit 1
+	fi
+
+	# default action is to append
+	if [ -z "$action" ] ; then
+		action=append
+	fi
+
+	# default value is all ones
+	if [ -z "$val" ] ; then
+		val="0xff"
+	fi
+	case $val in
+		''|[!a-fA-F0-9]*) echo "Could not parse value $val.">&2; exit 1;;
+		*) ;;
+	esac
+
+	padsize=$(($size-$filesize))
+	printf "Copy data from file \"%s\" to \"%s\" and pad it from %d B to %d B by %sing 0x%x %d times... " \
+	       $infile $outfile $filesize $size $action $val $padsize
+	if $action ; then
+		echo "done."
+	else
+		echo "failed."
+		return 1
+	fi
+}
+
+main $@