#! /bin/sh

# Script to construct a firmware image for a SPARC Padre platform,
# such as NetGear's ReadyNas Duo Network Attached Storage appliance.

if [ "$1" = '-o' ]; then
    shift
    if [ -z "$1" ]; then
	echo "Usage: `basename $0` [-o output ] kernel-image [initrd-image]" \
		1>&2
	exit 1
    fi
    OUTPUT=">$1"
    shift
else
    OUTPUT=
fi

if [ $# -ne 1 -a $# -ne 2 ]; then
    echo "Usage: `basename $0` [-o output ] kernel-image [initrd-image]" 1>&2
    exit 1
elif [ -z "`which readynas_crypto`" ]; then
    echo 'Required executable "readynas_crypto" not found!' 1>&2
    exit 2
elif [ -z "`which md5sum`" ]; then
    echo 'Required executable "md5sum" not found!' 1>&2
    exit 2
fi

# Name of your distro (<= ~10 bytes)
FW_NAME='DIET-PC'
# Brief one-line description of your distro (<= ~70 bytes)
FW_DESC='DIskless Embedded Technology Personal Computer (http://dietpc.org)'
# Version of your distro
FW_VERS='3'
# URI for release notes for this version (<= ~60 bytes)
FW_RELNOTES='http://wiki.dietpc.org/wiki/DIET-PC_3_Introduction'
# Release timestamp.  If you don't have Perl, use a dummy value here instead
# (10 digits starting with 1355 would be vaguely plausible).
FW_TSTAMP=`perl -e 'printf "%u\n", time();'`

WORK_DIR="/tmp/`basename $0`-$$"

zero_pad() {
# $1 is pathname, $2 is its size in bytes, $3 is block size
    PAD_BY=0
    REMAINDER=`expr $2 % $3`
    if [ "$REMAINDER" -ne 0 ]; then
	PAD_BY=`expr $3 - $REMAINDER`
	dd if=/dev/zero of=$1 seek=$2 bs=1 count=$PAD_BY 2>/dev/null
    fi
    echo `expr $2 + $PAD_BY`
}

mkdir $WORK_DIR
cp "$1" $WORK_DIR/vmlinux.bin
if [ $# -eq 2 ]; then
   cp "$2" $WORK_DIR/initrd.img
else
   : > $WORK_DIR/initrd.img
fi
pushd $WORK_DIR >/dev/null

KSIZE_ACTUAL=`ls -l vmlinux.bin | awk '{print $5}'`
KSIZE_PADDED=`zero_pad vmlinux.bin $KSIZE_ACTUAL 512`
readynas_crypto -e -k0 < vmlinux.bin > vmlinux.bin.enc

INITRD_ACTUAL=`ls -l initrd.img | awk '{print $5}'`
INITRD_PADDED=`zero_pad initrd.img $INITRD_ACTUAL 512`
INITRD_OFFSET=`expr $KSIZE_PADDED / 512 + 1`
readynas_crypto -e -k3 < initrd.img > initrd.img.enc

cat > header <<EOF
vmlinux.bin::1::$KSIZE_ACTUAL
initrd.img::$INITRD_OFFSET::$INITRD_ACTUAL
EOF
HEADER_ACTUAL=`ls -l header | awk '{print $5}'`
zero_pad header $HEADER_ACTUAL 80 >/dev/null
readynas_crypto -e -k0 < header > header.enc

PAYLOAD_SIZE=`expr $KSIZE_PADDED + $INITRD_PADDED`
PAYLOAD_MD5=`cat vmlinux.bin.enc initrd.img.enc | md5sum | awk '{print $1}'`
cat > header2 <<EOF
info::name=$FW_NAME,version=$FW_VERS,time=$FW_TSTAMP,size=$PAYLOAD_SIZE,md5sum=$PAYLOAD_MD5,descr=$FW_DESC,release_notes=$FW_RELNOTES
EOF
HEADER2_ACTUAL=`ls -l header2 | awk '{print $5}'`
zero_pad header2 $HEADER2_ACTUAL 432 >/dev/null

popd >/dev/null
eval cat $WORK_DIR/header.enc $WORK_DIR/header2 $WORK_DIR/vmlinux.bin.enc \
	$WORK_DIR/initrd.img.enc $OUTPUT
rm -rf $WORK_DIR
exit 0
