#!/bin/bash

# Create U-Boot image and Chrome image script.
# Copyright (C) 2015  Márcio Alexandre Silva Delgado <coadde@parabola.nu>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Set default dirs and files variables
_prefix='/'
_bindir="${_prefix}/usr/bin"
_bootdir="${_prefix}/boot"
_dtbdir='dtbs'
_pimgfile='preImage'
_uimgfile='uImage'
_lcuimgfile='vmlinux.kpart'
_uboot_litsfile='kernel.its'
_uboot_luimgfile='vmlinux.uimg'
_cmdlinefile='cmdline.txt'
_vboot_keyblk='kernel.keyblock'
_vboot_signprv='kernel_data_key.vbprivk'
_empty_blfile='bootloader.bin'

# Check if exist executable files to use this script
if [ ! -f "${_bindir}/cat" ]; then
	# coreutils:
	echo "!!! Error: cat not found !!!" && exit 1
elif [ ! -f "${_bindir}/dd" ]; then
	# coreutils:
	echo "!!! Error: dd not found !!!" && exit 1
elif [ ! -f "${_bindir}/install" ]; then
	# coreutils:
	echo "!!! Error: install not found !!!" && exit 1
elif [ ! -f "${_bindir}/grub-install" ]; then
	# grub:
	echo "!!! Error: grub-install not found !!!" && exit 1
elif [ ! -f "${_bindir}/mkimage" ]; then
	# uboot-tools:
	echo "!!! Error: mkimage not found !!!" && exit 1
elif [ ! -f "${_bindir}/vbutil_kernel" ]; then
	# vboot-utils:
	echo "!!! Error: vbutil_kernel not found !!!" && exit 1
fi

# Set printed variables
_kernel="${1}"
_board="${2}"

# Set default address
_address='0x00008000'

# Set '_arch' variable
if [ "$(uname -m)" = armv7l ]; then
	_arch='arm'
else
	_arch="$(uname -m)"
fi

# Set '_kernelname' and '_kerneltype' variables
if [ ${_kernel/linux-libre*/linux-libre} = linux-libre ]; then
	_kernelname="${_kernel/linux/vmlinuz}"
	_kerneltype="${_kernel/linux*/linux}"
else
	_kernelname="${_kernel}"
	_kerneltype="${_kernel}"
fi

_mkuimage() {
	cat "${_bootdir}/${_kernelname}" "${_bootdir}/${_dtbdir}/${_kernel}/${_dtb}.dtb" "${_pimgfile}.img"
	mkimage -A "${_arch}" -O "${_kerneltype}" -T kernel -C none -a "${_loadaddress}" -e "${_entrypoint}" -n "${_board}" -d "${_pimgfile}.img" "${_bootdir}/${_uimgfile}-${_kernel}"
	_mkuimage-rmtmp
}

_mkuimage-gnu+linux-chromebook() {
	mkimage -D "-I dts -O dtb -p 2048" -f "${_uboot_litsfile}" "${_uboot_luimgfile}"
	dd if='/dev/zero' of="${_empty_blfile}" bs=512 count=1
	cat 'console=tty0 init=/usr/bin/init root=PARTUUID=%U/PARTNROFF=1 rootwait rw noinitrd' > "${_cmdlinefile}"
	# Note: "${_vboot_keyblk}" and "${_vboot_signprv}" is generated by vboot-utils
	vbutil_kernel --pack "${_bootdir}/${_lcuimgfile}" --version 1 --vmlinuz "${_uboot_luimgfile}" --arch "${_arch}" --keyblock "${_vboot_keyblk}" --signprivate "${_vboot_signprv}" --config "${_cmdlinefile}" --bootloader "${_empty_blfile}"
	_mkuimage-rmtmp
}

_mkuimage-grub() {
	grub-install
	install -vDm 0644 "${_bootdir}/grub/arm-uboot/core.img" "${_bootdir}/${_uimgfile}-${_kernel}"
	exit 0
}

_mkuimage-grub-chromebook() {
	grub-install
	dd if='/dev/zero' of="${_empty_blfile}" bs=512 count=1
	cat 'console=tty0 init=/usr/bin/init root=PARTUUID=%U/PARTNROFF=1 rootwait rw noinitrd' > "${_cmdlinefile}"
	# Note: "${_vboot_keyblk}" and "${_vboot_signprv}" is generated by vboot-utils
	vbutil_kernel --pack "${_bootdir}/${_lcuimgfile}" --version 1 --vmlinuz "${_uboot_luimgfile}" --arch "${_arch}" --keyblock "${_vboot_keyblk}" --signprivate "${_vboot_signprv}" --config "${_cmdlinefile}" --bootloader "${_empty_blfile}"
	_mkuimage-rmtmp
}

_mkuimage-rmtmp() {
	if [ -f "${_pimgfile}.img" ]; then
		rm -v "${_pimgfile}.img"
	fi
	if [ -f "${_uboot_litsfile}" ]; then
		rm -v "${_uboot_litsfile}"
	fi
	if [ -f "${_uboot_luimgfile}" ]; then
		rm -v "${_uboot_luimgfile}"
	fi
	if [ -f "${_cmdlinefile}" ]; then
		rm -v "${_cmdlinefile}"
	fi
	if [ -f "${_empty_blfile}" ]; then
		rm -v "${_empty_blfile}"
	fi
	exit 0
}

_mkuimage-custom() {
	_dtb="${_board}"
	echo "Set load address with a hex number (default: ${_address}):"
	read _loadaddress_tiped
	if [ -n "${_loadaddress_tiped}" ]; then
		_loadaddress="${_loadaddress_tiped}"
	else
		_loadaddress="${_address}"
	fi
	echo "Set entry point with a hex number (default: ${_address}):"
	read _entrypoint_tiped
	if [ -n "${_entrypoint_tiped}" ]; then
		_entrypoint="${_entrypoint_tiped}"
	else
		_entrypoint="${_address}"
	fi
}

if [ "${_arch}" = 'arm' ]; then
	if [ "${_kerneltype}" = 'linux' ]; then
		case ${_board} in
			ax3)
				_dtb='armada-xp-openblocks-ax3-4'
				_entrypoint="${_address}"
				_loadaddress="${_address}"
				;;
			cubox)
				_dtb='dove-cubox'
				_entrypoint="${_address}"
				_loadaddress="${_address}"
		#		;;
		#	chromebook)
		#		_mkuimage-gnu+linux-chromebook
				;;
			d3plug)
				_dtb='dove-d3plug'
				_entrypoint="${_address}"
				_loadaddress="${_address}"
				;;
			grub)
				_mkuimage-grub
		#		;;
		#	grub-chromebook|chromebook-grub)
		#		_mkuimage-grub-chromebook
				;;
			mirabox)
				_dtb='armada-370-mirabox'
				_entrypoint="${_address}"
				_loadaddress="${_address}"
				;;
			smileplug)
				_dtb='armada-370-smileplug'
				_entrypoint="${_address}"
				_loadaddress="${_address}"
				;;
			*)
				_mkuimage-custom
				;;
		esac
	else
		case ${_board} in
			grub)
				_mkuimage-grub
		#		;;
		#	grub-chromebook|chromebook-grub)
		#		_mkuimage-grub-chromebook
				;;
			*)
				_mkuimage-custom
				;;
		esac
	fi
else
	_mkuimage-custom
fi

_mkuimage