#!/bin/bash

usage () {
    echo "usage $(basename $0) <vmlinux> <original-kernelfs> <output-file>"
    exit 1
}

if [ "$#" -ne 3 ];then
    usage
fi

if [[ ! -f "$1" || ! -f "$2" ]];then
    echo "parameter 1 and 2 must be files!"
    usage
fi

VMLINUX=$1
ORIG=$2
OUTPUT=$3
RAW_FILE=vmlinux.raw

# programs used
CUT=/usr/bin/cut
DD=/bin/dd
GREP=/bin/grep
PRINTF=/usr/bin/printf
OBJCOPY=${CROSS_COMPILE}objcopy
READELF=/usr/bin/readelf
SED=/bin/sed
STAT=/usr/bin/stat
XXD=/usr/bin/xxd

# predefined stuff (magic numbers and offsets)
FLASH_BS=512
ORIG_PREAMBLE=1024
RAW_SIZE_OFFSET=$((0x4C))
ENTRY_POINT_OFFSET=$((0x288))

# get the basic things needed for the generation
ORIG_FILE_SIZE=$($STAT -c "%s" $ORIG)
ENTRY_POINT=$($READELF -h $VMLINUX | $GREP -i "entry point" | $SED 's/  //g' | $CUT -d' ' -f 4)

# create temporary vmlinux.raw file
$OBJCOPY -O binary --remove-section=.reginfo --remove-section=.mdebug --remove-section=.comment --remove-section=.note --remove-section=.pdr --remove-section=.options --remove-section=.MIPS.options $VMLINUX $RAW_FILE
RAW_FILE_SIZE=$($STAT -c "%s" $RAW_FILE)

# create output file
$DD if=/dev/zero of=$OUTPUT bs=$FLASH_BS count=$(($ORIG_FILE_SIZE/$FLASH_BS))
# copy bootloader
$DD if=$ORIG of=$OUTPUT bs=$FLASH_BS count=$(($ORIG_PREAMBLE/$FLASH_BS)) conv=notrunc
# copy raw file to output
$DD if=$RAW_FILE of=$OUTPUT bs=1 seek=$ORIG_PREAMBLE conv=notrunc

# modify file size
($PRINTF "00: %08x" $( printf 0x%08x $RAW_FILE_SIZE  | $SED 's/\(0x\)\(..\)\(..\)\(..\)\(..\)/\1\5\4\3\2/') | $XXD -r | $DD of=$OUTPUT bs=1 count=4 seek=$RAW_SIZE_OFFSET conv=notrunc)
# modify entry point
($PRINTF "00: %08x" $(echo $ENTRY_POINT | $SED 's/\(0x\)\(..\)\(..\)\(..\)\(..\)/\1\5\4\3\2/') | $XXD -r | $DD of=$OUTPUT bs=1 count=4 seek=$ENTRY_POINT_OFFSET conv=notrunc)

