#!/bin/bash
### rootfsinstall: create partitions and fileysytems
#
# Based on rpi-install by: Davide Madrisan
# Modified by: Silvan Calarco <silvan.calarco@mambasoft.it>
# License: GPL 3.0
#

SYSTEMFSTYPE=ext4
# All targets are arm currently
TARGET_ARCH=arm
VOLUME_LABEL="openmamba"

function usage() {
   echo "Usage: $0 device rootfs-archive [-bpi|-cubox|-rpi|-rpi64] [-a archive] [-c command] [-fs fstype] [-k kernel] [-p password] [-y]"
   echo
   echo "Target platform (optional):"
   echo "-baytrail   : make a BayTrail image with boot partition"
   echo "-bpi        : make a BananaPi image with boot partition"
   echo "-cubox      : make a Cubox image with boot partition"
   echo "-rpi|-rpi64 : make a RaspberryPi (aarch64) image with boot partition"
   echo
   echo "Options:"
   echo "-a archive  : additional archive to unpack in rootfs root (may be specified multiple times)"
   echo "-cp command : command to run before chroot (may be specified multiple times)"
   echo "              Use @ROOT@ as reference to rootfs path and @BOOT@ as reference to bootfs path"
   echo "-c command  : command to run through chroot in rootfs (may be specified multiple times)"
   echo "-fs fstype  : filesystem type for system partition (default: ext4)"
   echo "-g [size]   : grow system partition to fit storage size (to be used with -I)"
   echo "-h hostname : set given hostname"
   echo "-k kernel   : extract and use specified kernel file from ROOTFS/boot/ for boot"
   echo "-k[2,3] kernel: extract and use specified second/third kernel file from ROOTFS/boot/ for boot"
   echo "-i packages : install packages using package manager in chroot"
   echo "-I          : treat input as an image file"
   echo "-l          : force local installation only; don't perform installation from network"
   echo "-L          : rootfs volume label (default: 'openmamba')"
   echo "-p [user:]password : set given password for specified user (if none, set for root user)"
   echo "-r mode     : set given default video mode where applicable (e.g. -r 1920x1080-32@60)"
   echo "-s          : assume partitions are already done and proceed from scripts (for development)"
   echo "-y          : assume yes to all questions (script mode)"
   echo
   echo "Example 1: $0 /dev/sdb /tmp/openmamba-rootfs-light.arm.tar.xz"
   echo "Example 2: $0 /dev/sdb -rpi /tmp/openmamba-diskimg-raspberrypi-it-snapshot-20170910.arm.img.gz"
   exit 1
}

[ $UID -eq 0 ] || {
   echo "ERROR: this script must be called as root; aborting."
   exit 1
}

while [ "$1" ]; do
   case $1 in
      -y) ASSUMEYES=1 ;;
      -baytrail) TARGETDEVICE=baytrail ;;
      -cubox) TARGETDEVICE=cubox ;;
      -bpi) TARGETDEVICE=bpi ;;
      -rpi|-rpi64) TARGETDEVICE=rpi64; TARGET_ARCH=aarch64 ;;
      -fs) [ "$2" ] || {
              echo "Error: -fs option requires an argument; aborting."
              exit 1
           }
           SYSTEMFSTYPE=$2
           shift
           ;;
      -a) [ "$2" ] || {
              echo "Error: -a option requires an archive as argument; aborting."
              exit 1
           }
           ADDITIONALARCHIVE=`realpath $2`
           ADDITIONALARCHIVES[${#ADDITIONALARCHIVES[*]}]="${ADDITIONALARCHIVE}"
           [ -r "$ADDITIONALARCHIVE" ] || {
              echo "Error: file $ADDITIONALARCHIVE not found; aborting."
              exit 1
           }
           shift
           ;;
      -c) [ "$2" ] || {
              echo "Error: -c option requires a command string as argument; aborting."
              exit 1
           }
           CHROOTCOMMANDS[${#CHROOTCOMMANDS[*]}]="$2"
           shift
           ;;
      -cp) [ "$2" ] || {
              echo "Error: -cp option requires a command string as argument; aborting."
              exit 1
           }
           PRECHROOTCOMMANDS[${#PRECHROOTCOMMANDS[*]}]="$2"
           shift
           ;;
      -k) [ "$2" ] || {
              echo "Error: -k option requires a kernel file name as argument; aborting."
              exit 1
           }
           USEKERNEL=$2
           shift
           ;;
      -k2) [ "$2" ] || {
              echo "Error: -k2 option requires a kernel file name as argument; aborting."
              exit 1
           }
           USEKERNEL2=$2
           shift
           ;;
      -k3) [ "$2" ] || {
              echo "Error: -k3 option requires a kernel file name as argument; aborting."
              exit 1
           }
           USEKERNEL3=$2
           shift
           ;;
      -g) GROWIMAGE=1
          if [ "${2:0:1}" != "-" ]; then
             GROWIMAGESIZE=$2
             shift;
          else
             GROWIMAGESIZE=100%
          fi
          ;;
      -h) [ "$2" ] || {
              echo "Error: -h option requires a hostname as argument; aborting."
              exit 1
           }
           SETHOSTNAME=$2
           shift
           ;;
      -i) [ "$2" ] || {
              echo "Error: -i option requires a packages list as argument; aborting."
              exit 1
           }
           INSTALLPACKAGES="$2"
           shift
           ;;
      -I) IMAGEMODE=1 ;;
      -l) LOCALONLY=1 ;;
      -L) [ "$2" ] || {
              echo "Error: -L option requires a volume label as argument; aborting."
              exit 1
          }
          VOLUME_LABEL="$2"
          shift
          ;;
      -p) [ "$2" ] || {
              echo "Error: -p option requires a root password or 'user:password' as argument; aborting."
              exit 1
           }
           if [ "${2/:*}" != "${2}" ]; then
              SETUSERPASSWORD="$2"
           else
              SETUSERPASSWORD="root:$2"
           fi
           shift
           ;;
      -r) [ "$2" ] || {
              echo "Error: -r option requires a video mode as argument; aborting."
              exit 1
           }
           VIDEOMODE=$2
           shift
           ;;
      -s) FROMSCRIPTS=1 
          ;;
      -*) echo "Error: invalid option $1; aborting."
          exit 1
          ;;
       *) if [ ! "$DRIVE" ]; then
             DRIVE=$1
          elif [ ! "$ROOTFSARCHIVE" ]; then
             ROOTFSARCHIVE=`realpath $1`
          else
             echo "Error: invalid argument $1; aborting."
             exit 1
          fi
          ;;
    esac
    shift
done
[ "$ROOTFSARCHIVE" ] || { usage; exit 1; }

if [ "${DRIVE:0:11}" = "/dev/mmcblk" -o "${DRIVE:0:9}" = "/dev/loop" ]; then
   PARTITION1=${DRIVE}p1
   PARTITION2=${DRIVE}p2
else
   PARTITION1=${DRIVE}1
   PARTITION2=${DRIVE}2
fi

case $TARGETDEVICE in
   baytrail) ARCH=x86_64
        BOOTFSTYPE=fat16
        BOOTFSSIZE=22M
        BOOTFSSTART=1049k
        INSTALLPACKAGES="kernel-mamba-x86_64 kernel-mamba-x86_64-headers \
           chipone_ts grub-efi rtl8723bs_bt rtl8723bs axpd acpi_tables_patch $INSTALLPACKAGES"
        REMOVEPACKAGES=""
        FSTAB_ROOT_DEVICE="/dev/sda2"
        FSTAB_BOOT_DEVICE="/dev/mmcblk0p1"
        ;;
   bpi) ARCH=arm
        BOOTFSTYPE=fat32
        BOOTFSSIZE=22M
        BOOTFSSTART=1049k
        [ "$USEKERNEL" ] || USEKERNEL=uImage-sunxi
        KERNELDEST="@BOOT@/kernel.img"
        INSTALLPACKAGES="kernel-sunxi kernel-sunxi-modules u-boot-sunxi-Bananapi $INSTALLPACKAGES"
        REMOVEPACKAGES="kernel-mamba-arm"
        FSTAB_ROOT_DEVICE="/dev/mmcblk0p2"
        FSTAB_BOOT_DEVICE="/dev/mmcblk0p1"
        ;;
   rpi|rpi64) ARCH=aarch64
        BOOTFSTYPE=fat32
        BOOTFSSIZE=300M
        BOOTFSSTART=0
        # /boot kernel installation and configurations are done by raspberrypi-firmware package
        INSTALLPACKAGES="\
raspberrypi-firmware raspberrypi-utils $INSTALLPACKAGES"
        REMOVEPACKAGES=""
        FSTAB_ROOT_DEVICE="LABEL=openmamba"
        FSTAB_BOOT_DEVICE="LABEL=boot"
        ;;
   cubox) ARCH=arm
          BOOTFSTYPE=ext3
          BOOTFSSIZE=20M
          BOOTFSSTART=0
          [ "$USEKERNEL" ] || USEKERNEL=uImage-3.6.9-cubox
          KERNELDEST="@BOOT@/uImage"
          INSTALLPACKAGES="kernel-cubox kernel-cubox-modules xf86-video-dove $INSTALLPACKAGES"
          REMOVEPACKAGES="kernel-mamba-arm"
          ;;
   *) BOOTFSTYPE=
      if [ "$USEKERNEL" ]; then
         KERNELDEST="/tmp/$USEKERNEL"
      else
         KERNELDEST=
      fi
      PARTITION2=$PARTITION1 ;;
esac

[ -r "$ROOTFSARCHIVE" ] || {
   echo "ERROR: unable to read rootfs archive $ROOTFSARCHIVE; aborting."
   exit 1
}

if [ ! "${IMAGEMODE}" ]; then
   echo "Rootfs archive : $ROOTFSARCHIVE"
else
   echo "Image archive  : $ROOTFSARCHIVE"
fi

echo "Target SD card : ${DRIVE}"
[ "$TARGETDEVICE" ] && echo "Target platform: $TARGETDEVICE ($TARGET_ARCH)"
if [ ! "${IMAGEMODE}" ]; then
   [ "$BOOTFSTYPE" ] &&   echo "Boot fs        : $BOOTFSTYPE($BOOTFSSIZE)"
   [ "$BOOTFSTYPE" ] &&   echo "System fs      : $SYSTEMFSTYPE"
   [ "$USEKERNEL" ] &&    echo "Kernel         : $USEKERNEL -> $KERNELDEST"
   [ "$USEKERNEL2" ] &&   echo "Second kernel  : $USEKERNEL2 -> $KERNELDEST2"
   [ "$USEKERNEL3" ] &&   echo "Third kernel   : $USEKERNEL3 -> $KERNELDEST3"
fi
echo

[ -e qemu-${TARGET_ARCH}.static -o qemu-${TARGET_ARCH}-static ] || {
   echo "WARNING: qemu-static is not installed, please install it if installing a different arch rootfs"
}

[ "$ASSUMEYES" -o "$FROMSCRIPTS" ] || {
   echo -n "All current data in ${DRIVE} will be lost, do you want to proceed [y/N]?"
   read ans
   [ "$ans" = "y" -o "$ans" = "Y" ] || exit 1
}

if [ ! "$IMAGEMODE" -a ! "$FROMSCRIPTS" ]; then
   sudo parted -s ${DRIVE} mktable msdos
   RET=$?
   if [ "$RET" != "0" ]; then
      echo "ERROR: parted exited with error $RET while creating partition table on ${DRIVE}; aborting."
      exit 1
   fi
   sync

   if [ "$BOOTFSTYPE" ]; then
      # FAT partition
      sudo parted -s -a cyl -- ${DRIVE} mkpart primary $BOOTFSTYPE $BOOTFSSTART $BOOTFSSIZE
      RET=$?
      if [ "$RET" != "0" ]; then
         echo "ERROR: parted exited with error $RET while creating boot partition on ${DRIVE}; aborting."
         exit 1
      fi
      sudo parted -s -- ${DRIVE} toggle 1 boot
      RET=$?
      if [ "$RET" != "0" ]; then
         echo "ERROR: parted exited with error $RET while setting boot flag on ${DRIVE} boot partition; aborting."
         exit 1
      fi
      # rootfs partition
      sudo parted -s -a cyl -- ${DRIVE} mkpart primary $SYSTEMFSTYPE $BOOTFSSIZE -1
      RET=$?
      if [ "$RET" != "0" ]; then
         echo "ERROR: parted exited with error $RET while creating system partition on ${DRIVE}; aborting."
         exit 1
      fi
   else
      # rootfs partition
      sudo parted -s -a cyl -- ${DRIVE} mkpart primary $SYSTEMFSTYPE 0 -1
      RET=$1
      if [ "$RET" != "0" ]; then
         echo "ERROR: parted exited with error $RET while creating system partition on ${DRIVE}; aborting."
         exit 1
      fi
   fi

   if [ "$BOOTFSTYPE" ]; then
      echo "Formatting $PARTITION1 ($BOOTFSTYPE) ..."
      case "$BOOTFSTYPE" in
         vfat|fat32) mkfs.vfat -s 1 -F 32 -n "boot" $PARTITION1 || {
                  echo "ERROR: unable to format $PARTITION1; aborting."
                  exit 1
               } ;;
         fat16) mkfs.vfat -s 1 -F 16 -n "boot" $PARTITION1 || {
                  echo "ERROR: unable to format $PARTITION1; aborting."
                  exit 1
               } ;;
         ext*) mke2fs -q -t $BOOTFSTYPE -j -L "boot" $PARTITION1 || {
                  echo "ERROR: unable to format $PARTITION1; aborting."
                  exit 1
               } ;;
      esac
   fi

   echo "Formatting $PARTITION2 ($SYSTEMFSTYPE)..."
   mke2fs -q -F -t $SYSTEMFSTYPE -j -L "$VOLUME_LABEL" $PARTITION2 || {
      echo "ERROR: unable to format $PARTITION2; aborting."
      exit 1
   }

elif [ ! "$FROMSCRIPTS" ]; then
   # Image mode
   if [ "${ROOTFSARCHIVE: -4}" == ".zip" ]; then
      7z e -so ${ROOTFSARCHIVE} | dd of=${DRIVE} bs=4M conv=fsync status=progress
   elif [ "${ROOTFSARCHIVE: -3}" == ".gz" ]; then
      gunzip -c ${ROOTFSARCHIVE} | dd of=${DRIVE} bs=4M conv=fsync status=progress
   else
      dd if=${ROOTFSARCHIVE} of=${DRIVE} bs=4M conv=fsync status=progress
   fi
fi

sync

if [ "${GROWIMAGE}" ]; then
   # Grow system partition to 100%
   SAVE_BOOT_PARTUUID=`blkid -s PARTUUID -o value ${PARTITION1}`
   SAVE_ROOT_PARTUUID=`blkid -s PARTUUID -o value ${PARTITION2}`
   parted ${DRIVE} resizepart 2 ${GROWIMAGESIZE}
   e2fsck -f ${PARTITION2}
   resize2fs ${PARTITION2}
fi

ROOTMP=`mktemp -d -t rootfsinstall.XXXXXXXX`

[ -d $ROOTMP ] || {
   echo "Error: unable to create temporary mount points; aborting."
   exit 1
}

mount $PARTITION2 $ROOTMP || {
   echo "ERROR: unable to mount partition $PARTITION2; aborting."
   exit 1
}

trap "[ "$ROOTMP" -a -e $ROOTMP ] && umount $ROOTMP/dev/pts $ROOTMP/dev $ROOTMP/proc $ROOTMP/sys $ROOTMP/run $ROOTMP" 0 HUP INT QUIT ABRT KILL TERM

# Bind mount boot partition as /boot insited ROOTMP
if [ "$BOOTFSTYPE" ]; then
   mkdir $ROOTMP/boot
   BOOTMP=$ROOTMP/boot
   mount $PARTITION1 $BOOTMP || {
      echo "ERROR: unable to mount partition $PARTITION1; aborting."
      exit 1
   }
   trap "[ "$BOOTMP" -a -e $BOOTMP ] && umount $BOOTMP;[ "$ROOTMP" -a -e $ROOTMP ] && umount $ROOTMP/dev/pts $ROOTMP/dev $ROOTMP/proc $ROOTMP/sys $ROOTMP/run $ROOTMP" 0 HUP INT QUIT ABRT KILL TERM
fi

(
   cd $ROOTMP >/dev/null || {
      echo "ERROR: unable to access system partition mount point; aborting."
      umount $PARTITION2
      rmdir $ROOTMP
      exit 1
   }


   if [ ! "${IMAGEMODE}" ]; then
      echo "Uncompressing $ROOTFSARCHIVE..."
      echo -n "This can take a while, please wait..."
      tar xf $ROOTFSARCHIVE || {
         echo
         echo "ERROR: unable to uncompress rootfs archive; aborting."
         exit 1
      }
      echo "DONE"
   fi

   for b in dev dev/pts proc sys run; do
      mount -o bind /$b $ROOTMP/$b
   done

   for ADDITIONALARCHIVE in ${ADDITIONALARCHIVES[*]}; do
      echo "Uncompressing $ADDITIONALARCHIVE..."
      echo -n "This can take a while, please wait..."
      tar xf $ADDITIONALARCHIVE || {
         echo
         echo "ERROR: unable to uncompress additional archive; aborting."
         exit 1
      } 
      echo "DONE"
   done
)

[ $? -eq 0 ] || exit $?

for f in qemu-${TARGET_ARCH}.static qemu-${TARGET_ARCH}-static; do
   if [ -e /usr/bin/${f} ]; then
      cp /usr/bin/${f} $ROOTMP/usr/bin/qemu-${TARGET_ARCH}
      break
   fi
done

if [ "${SAVE_ROOT_PARTUUID}" -a "${GROWIMAGE}" ]; then
   # Update PARTUUID after growing root filesystem (Raspbian)
   NEW_BOOT_PARTUUID=`blkid -s PARTUUID -o value ${PARTITION1}`
   NEW_ROOT_PARTUUID=`blkid -s PARTUUID -o value ${PARTITION2}`
   sed -i "s|PARTUUID=${SAVE_ROOT_PARTUUID}|PARTUUID=${NEW_ROOT_PARTUUID}|" ${ROOTMP}/etc/fstab
   sed -i "s|PARTUUID=${SAVE_BOOT_PARTUUID}|PARTUUID=${NEW_BOOT_PARTUUID}|" ${ROOTMP}/etc/fstab
   if [ "$TARGETDEVICE" = "rpi" -o "$TARGETDEVICE" = "rpi64" ]; then
      sed -i "s|PARTUUID=${SAVE_ROOT_PARTUUID}|PARTUUID=${NEW_ROOT_PARTUUID}|" ${BOOTMP}/cmdline.txt
   fi
fi

if [ "$SETUSERPASSWORD" ]; then
   echo "$SETUSERPASSWORD" | chroot $ROOTMP chpasswd -c MD5 || {
      echo "ERROR: unable to set user password; aborting."
      exit 1
   }
fi

if [ "$SETHOSTNAME" ]; then
   echo "$SETHOSTNAME" > $ROOTMP/etc/hostname
   [ -e $ROOTMP/etc/sysconfig/network ] && sed -i "s|HOSTNAME=.*|HOSTNAME=$SETHOSTNAME|" $ROOTMP/etc/sysconfig/network
   sed -i "s|\(127\.0\.0\.1\W*\)\(.*\)|\1 $SETHOSTNAME.localdomain $SETHOSTNAME localhost.localdomain localhost|" $ROOTMP/etc/hosts
fi

if [ "$TARGETDEVICE" = "rpi" -o "$TARGETDEVICE" = "rpi64" ]; then
   echo "protect_running_kernel=False" >> $ROOTMP/etc/dnf/dnf.conf
   echo "installonlypkgs=\"\"" >> $ROOTMP/etc/dnf/dnf.conf
fi

if [ "$INSTALLPACKAGES" -a "$LOCALONLY" != "1" -a ! "${IMAGEMODE}" ]; then
   if [ ! -L $ROOTMP/etc/resolv.conf ]; then
      mv $ROOTMP/etc/resolv.conf $ROOTMP/etc/resolv.conf.rootfsinstall
      cp /etc/resolv.conf $ROOTMP/etc/resolv.conf
   fi
   chroot $ROOTMP dnf update --nogpgcheck -y || {
      echo "ERROR: error running chroot command 'dnf update --nogpgcheck -y'; aborting."
      exit 1
   }
   # dnf: diskspacecheck=0 workaround for bad free space calculations in chroot
   chroot $ROOTMP dnf install --nogpgcheck --setopt diskspacecheck=0 -y $INSTALLPACKAGES || {
      echo "ERROR: error running chroot command 'dnf install --nogpgcheck -y $INSTALLPACKAGES'; aborting."
      exit 1
   }
   [ -e $ROOTMP/etc/resolv.conf.rootfsinstall ] && mv $ROOTMP/etc/resolv.conf.rootfsinstall $ROOTMP/etc/resolv.conf
fi

if [ "$REMOVEPACKAGES" -a ! "${IMAGEMODE}" ]; then
   chroot $ROOTMP dnf remove --nogpgcheck -y $REMOVEPACKAGES 2>/dev/null || true
fi

KERNELDEST=`echo $KERNELDEST | sed "s|@BOOT@|$BOOTMP|g"`
KERNELDEST2=`echo $KERNELDEST2 | sed "s|@BOOT@|$BOOTMP|g"`
KERNELDEST3=`echo $KERNELDEST3 | sed "s|@BOOT@|$BOOTMP|g"`

#
# Prepare boot partition
#
if [ ! "${IMAGEMODE}" ]; then
if [ "$TARGETDEVICE" = "baytrail" ]; then
   # create EFI Grub 64 bit image
   mkdir -p $BOOTMP/EFI/BOOT/
   chroot $ROOTMP grub-mkimage -o /tmp/bootx64.efi -O x86_64-efi -p /efi/boot \
      part_gpt part_msdos ntfs ntfscomp hfsplus fat ext2 normal chain boot linux echo \
      help gfxterm gettext png efi_gop efi_uga search search_label search_fs_uuid \
      usb_keyboard all_video || {
      errorAndExit $"Error: unable to create GRUB x86_64-efi image" &>>$LOGFILE
   }
   mv $ROOTMP/tmp/bootx64.efi $BOOTMP/EFI/BOOT/

   for f in $ROOTMP/lib/modules/*mamba-x86_64; do
      KERNELVER=`basename $f`
   done
   KERNELDEST="vmlinuz-$KERNELVER"
   INITRAMFSDEST="initramfs-$KERNELVER.img"
   chroot $ROOTMP depmod $KERNELVER
   chroot $ROOTMP mkinitrd /boot/$INITRAMFSDEST $KERNELVER || exit 1

   cat >> $BOOTMP/EFI/BOOT/grub.cfg << _EOF
#
# GRUB configuration generated by openmamba rootfsinstall tool
#
font=unicode
#set gfxmode=auto
set gfxmode=1200x1920
insmod all_video
insmod gfxterm
insmod gettext
insmod usb_keyboard
terminal_output=gfxterm
set timeout=0
# theme
insmod=png
set menu_color_normal=white/black
set menu_color_highlight=white/green
search --no-floppy --label --set=root $VOLUME_LABEL

#
# Boot entries taken from ISO bootloader
#

menuentry "default" {
echo "Loading /boot/$KERNELDEST"
linux /boot/$KERNELDEST root=/dev/sda2 ro fbcon=rotate:1 systemd.gpt_auto=0 quiet splash
echo "Loading /boot/$INITRAMFSDEST"
initrd /boot/$INITRAMFSDEST
}
_EOF

   cat >> $ROOTMP/etc/X11/xorg.conf.d/50-rotatemonitor.conf << _EOF
Section "Monitor"
        Identifier "DSI1"
        Option     "Rotate" "right"
EndSection
_EOF
   cat >> $ROOTMP/etc/X11/xorg.conf.d/99-calibration.conf << _EOF
Section "InputClass"
        Identifier      "calibration"
        MatchProduct    "CHPN0001:00"
        Option  "Calibration"   "1920 0 1200 0"
EndSection
_EOF
   :
elif [ "$TARGETDEVICE" = "bpi" ]; then
   # TODO
   cp $ROOTMP/boot/Bananapi-script.bin $BOOTMP/
   IMAGE=`ls $ROOTMP/boot/uImage-*-sunxi | head -n 1`
   cp $IMAGE $BOOTMP/uImage-sunxi
   cat > $BOOTMP/uEnv.txt << _EOF
bootargs=console=ttyS0,115200 console=tty0 sunxi_g2d_mem_reserve=0 sunxi_ve_mem_reserve=0 disp.screen0_output_mode=EDID:1280x720p50 hdmi.audio=EDID:0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
aload_script=fatload mmc 0 0x43000000 Bananapi-script.bin;
aload_kernel=fatload mmc 0 0x48000000 uImage-sunxi; bootm 0x48000000;
uenvcmd=run aload_script aload_kernel
_EOF
   dd if=$ROOTMP/boot/Bananapi/u-boot-sunxi-with-spl.bin of=${DRIVE} bs=1024 seek=8
   :
elif [ "$TARGETDEVICE" = "rpi" -o "$TARGETDEVICE" = "rpi64" ]; then

   [ -e /usr/libexec/init_resize -a ! -e ${ROOTMP}/usr/libexec/init_resize ] && cp /usr/libexec/init_resize ${ROOTMP}/usr/libexec/
   [ -e ${ROOTMP}/usr/libexec/init_resize ] && CMDLINE_ADD=" init=/usr/libexec/init_resize"

   KERNEL_IMAGE=$(ls ${ROOTMP}/boot/vmlinux-* ${ROOTMP}/boot/vmlinuz-* 2>/dev/null | head -n 1)
   if [ -z "$KERNEL_IMAGE" ]; then
      echo "ERROR: no kernel image found in ${ROOTMP}/boot; aborting."
      exit 1
   fi
   KERNEL_VERSION=${KERNEL_IMAGE##*/vmlinux-}
   KERNEL_VERSION=${KERNEL_VERSION##*/vmlinuz-}
   echo "Detected kernel version: $KERNEL_VERSION"
   chroot $ROOTMP rpi-prepare-boot /boot "$KERNEL_VERSION"

   [ "$SWHOME" -a "${SWHOME:0:4}" = "/tmp" ] && rm -rf $SWHOME

elif [ "$TARGETDEVICE" = "cubox" ]; then
   if [ -e $ROOTMP/boot/uImage-*-cubox ]; then
      IMAGE=`ls $ROOTMP/boot/uImage-*-cubox | head -n 1`
      cp $IMAGE* $BOOTMP/
      ln -s ${IMAGE/*\/}-boot.scr $BOOTMP/boot.scr
   else
      [ "$VIDEO_MODE" ] || VIDEO_MODE="1920x1080-32@60"
      mkdir -p $BOOTMP
      echo "Creating u-boot boot.scr..."
      cat > $BOOTMP/boot.txt << _EOF
setenv bootargs 'console=ttyS0,115200n8 vmalloc=384M root=/dev/mmcblk0p2 video=dovefb:lcd0:$VIDEO_MODE-edid clcd.lcd0_enable=1 clcd.lcd1_enable=0 rootwait'
echo ======== Loading kernel ========
ext2load mmc 0:1 0x00200000 /uImage
echo ======== Booting kernel ========
bootm
_EOF
      mkimage -A arm -O linux -T script -C none -n "u-boot commands" -d $BOOTMP/boot.txt $BOOTMP/boot.scr || {
         echo "ERROR: mkimage: error creating boot.scr; aborting."
         exit 1
      }
   fi
fi

if [ "$FSTAB_ROOT_DEVICE" ]; then
   cat >> $ROOTMP/etc/fstab << _EOF
$FSTAB_ROOT_DEVICE	/	auto	defaults	0	0
_EOF
fi

if [ "$FSTAB_BOOT_DEVICE" ]; then
   cat >> $ROOTMP/etc/fstab << _EOF
$FSTAB_BOOT_DEVICE	/boot	auto	defaults	0	2
_EOF
fi

# Remove legacy usbfs fstab entry if present
sed -i '/^usbfs[[:space:]]/d' $ROOTMP/etc/fstab

if [ "$USEKERNEL" ]; then
   if [ -r $ROOTMP/boot/$USEKERNEL ]; then
      cp $ROOTMP/boot/$USEKERNEL $KERNELDEST || {
         echo "ERROR: unable to find or copy kernel $USEKERNEL; aborting."
         exit 1
      }
      echo "Kernel image available as $KERNELDEST"
   else
      echo "WARNING: can't find kernel file $ROOTMP/boot/$USERKERNEL"
   fi
fi

fi # ! IMAGEMODE

#
# Final custom commands
#
for c in `seq 1 ${#PRECHROOTCOMMANDS[*]}`; do
   PRECHROOTCOMMAND=`echo ${PRECHROOTCOMMANDS[c-1]} | sed "s|@ROOT@|$ROOTMP|g;s|@BOOT@|$BOOTMP|g"`
   eval $PRECHROOTCOMMAND || {
      echo "ERROR: error running pre-chroot command '${PRECHROOTCOMMAND}'; aborting."
      exit 1
   }
done

for c in `seq 1 ${#CHROOTCOMMANDS[*]}`; do
   eval chroot $ROOTMP ${CHROOTCOMMANDS[c-1]} || {
      echo "ERROR: error running chroot command '${CHROOTCOMMANDS[c-1]}'; aborting."
      exit 1
   }
done

# Kill any daemon process run in chroot
FOUND=0
for ROOT in /proc/*/root; do
    LINK=$(readlink $ROOT)
    if [ "x$LINK" != "x" ]; then
        if [ "x${LINK:0:${#ROOTMP}}" = "x$ROOTMP" ]; then
            # this process is in the chroot...
            PID=$(basename $(dirname "$ROOT"))
            kill -9 "$PID"
            FOUND=1
        fi
    fi
done

sync

echo "Done."
exit 0
