#!/bin/dash
# jamesbond 2020

### configuration
TMP_MEMDISK=/tmp/memdisk.$$

FONT=${FONT:-/usr/share/grub2-efi/euro.pf2}
CONFIG=${CONFIG:-/usr/share/grub2-efi/grub2-embedded.cfg}
GRUB_PLATFORM=${GRUB_PLATFORM:-i386-pc}
GRUB_PATH=${GRUB_PATH:-/usr/lib64/grub/$GRUB_PLATFORM}
GRUB_FORMAT="$GRUB_PLATFORM"
TYPE=${1:-lnxboot}
OUTPUT=${2:-grub2.$TYPE}

PREFIX=/boot/grub
# these modules are linked by default as they don't interfere with each other
MODULES="\
memdisk tar \
biosdisk part_msdos part_gpt truecrypt \
iso9660 fat ext2 exfat udf ntfs btrfs xfs f2fs lvm cryptodisk luks squash4 ntfscomp \
gfxterm font png jpeg gfxterm_background usb_keyboard \
configfile normal syslinuxcfg legacycfg \
chain boot linux linux16 ntldr halt reboot freedos \
parttool drivemap loopback \
echo test regexp search read help minicmd keystatus \
videoinfo all_video lspci probe \
gfxmenu password pbkdf2 \
"
# these modules must be "insmod" before use, as they interfere with
# biosdisk and/or less often used
MEMDISK_MODULES="scsi ata pata ahci uhci ohci ehci cs5536 \
hdparm hexdump loadenv disk \
ldm \
"

### helper 
# $1-msg
die() {
	echo "$1"
	exit 1
}


#### main ####
# 0. sanity
case "$1" in
	-h|--help|-help) die "\
${0##*/} [type] [output-file]

This program creates a single-file grub2 BIOS boolotader that you can
boot using grub4dos 'kernel' command or syslinux 'linux' command.

It can also create a single-file BIOS PXE or El-Torito CD bootloader.

[type] is the bootloader type you want to use.
- 'lnxboot' for use by grub4dos or syslinux, or
- 'cdboot' for making an El-Torito CD bootloader, or
- 'pxeboot' for making PXE bootloader
Default is 'lnxboot'

[output-file] is the output filename, default is grub2.\$type.
"
esac

case "$TYPE" in
	pxeboot) # add modules required for pxe boot
		MODULES="$MODULES net tftp http pxe pxechain"
		GRUB_FORMAT=${GRUB_FORMAT}-pxe
		;;
	cdboot)
		GRUB_FORMAT=${GRUB_FORMAT}-eltorito
		;;
esac
[ -e $GRUB_PATH/${TYPE}.img ] || die "Type '$TYPE' is not recognised."

! type grub-mkimage > /dev/null && die "Missing grub-mkimage. Is grub2 installed?"
! [ -e "$FONT" ] && die "$FONT not found."
! [ -e "$CONFIG" ] && die "$CONFIG not found."

# 1. create memdisk
rm -rf $TMP_MEMDISK
mkdir -p $TMP_MEMDISK/$PREFIX/fonts $TMP_MEMDISK/$PREFIX/$GRUB_PLATFORM
cp $FONT $TMP_MEMDISK/$PREFIX/fonts
cp $CONFIG $TMP_MEMDISK/$PREFIX/grub.cfg 
for p in $MEMDISK_MODULES; do
	cp $GRUB_PATH/$p.mod $TMP_MEMDISK/$PREFIX/$GRUB_PLATFORM
done
(cd $TMP_MEMDISK; tar -c *) > $TMP_MEMDISK.tar

# 2. build the image
grub-mkimage -O $GRUB_FORMAT -o $OUTPUT.tmp -C xz \
	-m $TMP_MEMDISK.tar \
	-p "(memdisk)$PREFIX" $MODULES

# 3. combine with lnxboot.img to make it bootable on syslinux
#    for cdboot/pxeboot, this is done by mkimage - so no further work needed
case "$TYPE" in
	lnxboot) cat $GRUB_PATH/${TYPE}.img $OUTPUT.tmp > $OUTPUT; rm -f $OUTPUT.tmp ;;
	*) mv $OUTPUT.tmp $OUTPUT ;;
esac

# 4. cleanup
rm -r $TMP_MEMDISK $TMP_MEMDISK.tar
