#!/bin/bash
NAME=$(basename $0)
CWD=$(pwd)
DIALOG_OUTPUT=/tmp/$$
LOGFILE=${NAME}.log

IMG_SIZE=507379712
#boot partition (P1) size in Mb 
BOOT_PART_SIZE=32
#where the firs partition starts in Mb
P1_START=1

#some defaults
MINIROOT_TARBALL=/tmp/slack-14.1-miniroot_04Nov13.tar.xz
MODULES_PKG=/tmp/kernel-modules-rpi2-3.18.9-armv7-1_13Mar15_fd.tgz
KERNEL_PKG=/tmp/kernel_rpi2-3.18.9-armv7-1_13Mar15_fd.tgz
FIRMWARE_PKG=/tmp/rpi2-boot-firmware-armv7-1_13Mar15_fd.tgz

cleanup ()
{ cd 
  sync
  umount /mnt/tmp/boot
  umount /mnt/tmp
  losetup -D
}

quit ()
{ echo $*
  exit 1
}

radiobox_dialog ()
{ TITLE=$1
  shift
  STRING=""
  for A in $*
  do
    [ "$STRING" = "" ] && STRING="$STRING $A . on" || STRING="$STRING $A . off"
  done 

  dialog --radiolist "${TITLE}"  0 0 0 $STRING 2>$DIALOG_OUTPUT
}

echo "$(date "+%H:%M %d/%m/%Y"): beginning image creation for RPI2" > $LOGFILE
[ $(id -u) -ne 0 ] && quit "Fatal: You need to run this as root."
[ "$(type -p dialog)" = "" ] && quit "Fatal: dialog is required to use this script"
[ "$(type -p dd)" = "" ] && quit "Fatal: dd is required to use this script"
[ "$(type -p sfdisk)" = "" ] && quit "Fatal: sfdisk is required to use this script"

dmesg -c >/dev/null 2>&1
dialog --msgbox "If you have the SD card on which you will put the image plesae insert it now, or reinsert it if it is already inserted. If you don't have it right now you will need to know the exact size of the media not the commertial size." 0 0

ENTRIES=$(dmesg |grep -E "sd.:|mmcblk.:" |sort -ru |sed -e "s/.*\(sd.\):.*/\1/" |sed -e "s/.*\(mmcblk.\):.*/\1/")

radiobox_dialog "Choose Target Device" $ENTRIES askme_the_image_size
TARGET_DEV=/dev/$(cat $DIALOG_OUTPUT)

IMG_SIZE=$(fdisk  -l $TARGET_DEV |grep "Disk.*$TARGET_DEV" |awk '{print $(NF-1)}')
if [ "$IMG_SIZE" = "" ]
then
  dialog --inputbox "Size of your desigred target image in bytes" 0 0 2>$DIALOG_OUTPUT
  IMG_SIZE=$(cat $DIALOG_OUTPUT) 
  echo "Supplied manually image size: $IMG_SIZE" >> $LOGFILE
else
  echo "Chosen target device: $TARGET_DEV size: $IMG_SIZE" >> $LOGFILE
fi

dialog --inputbox "How big do you want the boot partition to be n Mb ? Min 20Mb" 0 0 $BOOT_PART_SIZE 2>$DIALOG_OUTPUT
BOOT_PART_SIZE=$(cat $DIALOG_OUTPUT)
echo "Chosen boot partition size : $BOOT_PART_SIZE Mb" >> $LOGFILE

dialog --inputbox "How would you like to call the raw image file? " 0 0 "/tmp/rpi2.img" 2>$DIALOG_OUTPUT
IMAGE_NAME=$(cat $DIALOG_OUTPUT)
echo "Chosen image name: $IMAGE_NAME" >> $LOGFILE

clear
echo "creating the image file ... "
#creating the image file
dd if=/dev/zero of=$IMAGE_NAME bs=4096 count=$(($IMG_SIZE / 4096))
echo "dd if=/dev/zero of=$IMAGE_NAME bs=4096 count=$(($IMG_SIZE / 4096))" >>  $LOGFILE

echo "partitioning ... "
#partitionig image file
echo "sfdisk -f -uS $IMAGE_NAME" >>  $LOGFILE
cat << EOF |tee -a $LOGFILE |sfdisk -f -uS $IMAGE_NAME >/dev/null 2>&1
$(($P1_START * 2048)),$(($BOOT_PART_SIZE * 2048)),c,
$((($BOOT_PART_SIZE + $P1_START) * 2048)),,L
0,0,0
0,0,0
EOF
[ $? -ne 0 ] && quit "FATAL: could not partition $IMAGE_NAME"

#sizes and offsets in Mb for losetup
P1_OFFSET=$(($P1_START * 1024 * 1024))
P1_SIZE=$(($BOOT_PART_SIZE * 1024 * 1024))
#now we grow the second partition to use the rest of the space
P2_OFFSET=$(($P1_SIZE + $P1_OFFSET))
P2_SIZE=$(($IMG_SIZE - $P2_OFFSET))

[ "$(losetup -a)" != "" ] && quit "Aborting: there are loop devices in use"
echo "setting up loop devices ... "
#setting up loop devices
cat << EOF >> $LOGFILE
losetup -o $P1_OFFSET --sizelimit $P1_SIZE /dev/loop0 $IMAGE_NAME
losetup -o $P2_OFFSET --sizelimit $P2_SIZE /dev/loop1 $IMAGE_NAME
EOF
losetup -o $P1_OFFSET --sizelimit $P1_SIZE /dev/loop0 $IMAGE_NAME
[ $? -ne 0 ] && quit "FATAL: could not setup loop0"
losetup -o $P2_OFFSET --sizelimit $P2_SIZE /dev/loop1 $IMAGE_NAME
[ $? -ne 0 ] && quit "FATAL: could not setup loop1"

echo "formatting image partitions ... "
#formatting partitions
echo "mkdosfs -I -F 16 /dev/loop0" >> $LOGFILE
mkdosfs -I -F 16 /dev/loop0 >/dev/null 2>&1
[ $? -ne 0 ] && quit "FATAL: could not format loop0"
echo "mke2fs -t ext4 -b 4096 -i 16384 -j -m 0 -L root /dev/loop1" >> $LOGFILE
mke2fs -t ext4 -b 4096 -i 16384 -j -m 0 -L root /dev/loop1 >/dev/null 2>&1
[ $? -ne 0 ] && quit "FATAL: could not format loop1"

echo "mounting loop devices ... "
[ ! -d /mnt/tmp ] && mkdir -p /mnt/tmp
mount /dev/loop1 /mnt/tmp
[ $? -ne 0 ] && quit "FATAL: could not mount loop1"
mkdir /mnt/tmp/boot
mount /dev/loop0 /mnt/tmp/boot
[ $? -ne 0 ] && quit "FATAL: could not mount loop0"

if [ -f "$MINIROOT_TARBALL" -a -f "$MODULES_PKG" -a -f "$KERNEL_PKG" -a -f "$FIRMWARE_PKG" ]
then
  echo "found default tarballs and packages ... "
else
  dialog --msgbox "You need some files from fatdog's rpi2 repository http://rpi2.fatdog.eu/index.php?p=downloads and a miniroot image from http://ftp.arm.slackware.com/slackwarearm/slackwarearm-devtools/minirootfs/roots/ in particular kernel, kernel modules and boot firmware from fatdog and one of mozes's miniroot tarballs" 0 0
  clear
fi

while [ ! -f "$MINIROOT_TARBALL" ]
do
  dialog --inputbox "Type in the absolute path name of the miniroot tarball" 0 0 "$MINIROOT_TARBALL" 2>$DIALOG_OUTPUT
  MINIROOT_TARBALL=$(cat $DIALOG_OUTPUT)
  [ ! -f "$MINIROOT_TARBALL" ] && echo "File not found : $MINIROOT_TARBALL"
  sleep 2
done
echo "Chosen miniroot tarball : $MINIROOT_TARBALL" >> $LOGFILE

while [ ! -f "$MODULES_PKG" ]
do
  dialog --inputbox "Type in the absolute path name of the kernel modules package" 0 0  "$MODULES_PKG" 2>$DIALOG_OUTPU
  MODULES_PKG=$(cat $DIALOG_OUTPUT)
  [ ! -f "$MODULES_PKG" ] && echo "File not found : $MODULES_PKG" 
  sleep 2
done
echo "Chosen kernel modules package : $MODULES_PKG" >> $LOGFILE

while [ ! -f "$KERNEL_PKG" ]
do
  dialog --inputbox "Type in the absolute path name of the kernel package" 0 0  "$KERNEL_PKG" 2>$DIALOG_OUTPUT
  KERNEL_PKG=$(cat $DIALOG_OUTPUT)
  [ ! -f "$KERNEL_PKG" ] && echo "File not found : $KERNEL_PKG"
  sleep 2
done
echo "Chosen kernel package : $KERNEL_PKG" >> $LOGFILE

while [ ! -f "$FIRMWARE_PKG" ]
do
  dialog --inputbox "Type in the absolute path name of the boot firmware package" 0 0  "$FIRMWARE_PKG" 2>$DIALOG_OUTPUT
  FIRMWARE_PKG=$(cat $DIALOG_OUTPUT)
  [ ! -f "$FIRMWARE_PKG" ] && echo "File not found : $FIRMWARE_PKG"
  sleep 2
done
echo "Chosen boot frmare package : $FIRMWARE_PKG" >> $LOGFILE

echo "extracting miniroot ... "
cd /mnt/tmp
tar xf $MINIROOT_TARBALL -C .
cd /mnt/tmp/etc
cat << EOF >> fstab
/dev/mmcblk0p1 /boot vfat defaults,ro 0 0
LABEL=root / ext4 defaults,errors=remount-ro,noatime 0 0
EOF
#comment the following like if you like the uk keyboard layout
sed -i "s/uk\.map/us\.map/g" rc.d/rc.keymap

echo "extracting kernel modules package ... "
cd /mnt/tmp
tar xf $MODULES_PKG -C .
cd /mnt/tmp/etc/rc.d
mv $(ls rc.modules-*.new |tail -1) rc.modules
cd /mnt/tmp
rm -rf install

echo "extracting kernel package ... "
cd /mnt/tmp
tar xf $KERNEL_PKG -C .
cd /mnt/tmp/boot
mv cmdline.txt.new cmdline.txt
sed -i -e "s:@ROOTDEV@:/dev/mmcblk0p2:" cmdline.txt

echo "extracting boot firmware package ... "
cd /mnt/tmp
tar xf $FIRMWARE_PKG -C .
cd /mnt/tmp/boot
mv config.txt.new config.txt
cd /mnt/tmp
rm -rf install

cd $CDW
echo
echo -n "Check the image and hit ENTER when your done to umount the image and clean up loop devices"
read
cleanup

#wget ftp://ftp.arm.slackware.com/slackwarearm/slackwarearm-14.1/slackware/ap/slackpkg-2.82.0-noarch-14_slack14.1.txz
#wget ftp://ftp.arm.slackware.com/slackwarearm/slackwarearm-14.1/slackware/l/mpfr-3.1.2-arm-1.tgz
#installpkg slackpkg-2.82.0-noarch-14_slack14.1.txz mpfr-3.1.2-arm-1.tgz
#ntpdate -b pool.ntp.og
#slackpkg update

#slackpkg  install libtiff dnsmasq bridge-utils iptables ppp rp-pppoe iw ethtool libnl
#
