#!/bin/bash
#####################################################################################
# Script : sdcards.build
# Purpose: Build bootable SD card images for the supported Slackware ARM devices
# Author : Stuart Winter <mozes@slackware.com>
# Date...: 15-Feb-2019
# Version: 1.01
#####################################################################################
#####################################################################################
# References:
# https://www.element14.com/community/thread/38043/l/write-an-uimage-from-a-sd-card-to-the-emmc-memory
# https://www.bidouilliste.com/blog/2015/11/27/Porting-FreeBSD-to-a-new-ARM-Board-Part-1/
# https://olimex.wordpress.com/2013/09/18/7795/https://olimex.wordpress.com/2013/09/18/7795/
#####################################################################################

source /usr/share/slackdev/buildkit.sh

OUTDIR=../bin/

# This is packaged in the 'd' series on Slackware ARM/AArch64.
which kpartx 2>&1 > /dev/null || { echo "kpartx is required.  You can find it in the 'd' Slackware package series"; exit 1; }

# Find all of the U-Boot binaries (ignoring symlinks):
for ubootbin in $( find ${OUTDIR}/*.bin.xz -type f ) ; do
  SDIMAGEOUT="$( echo ${ubootbin} | sed 's?.bin.xz??g' )_sdcard.img"
  echo "Processing: ${ubootbin} --> $SDIMAGEOUT"

  # Destroy the partition table.  We don't need to do this since we're making an
  # image file, but it's worth noting if we were to run this script directly against
  # an SD card.
  #
  # dd if=/dev/zero of=/dev/mmcblk0 bs=1024 count=1

  # Create an empty image file:
  dd if=/dev/zero of=${SDIMAGEOUT} bs=1024 count=4096

  # Add it as a device and find out where it's gone (probably /dev/loop0):
  DEVLOC=$( basename $( losetup -f --show ${SDIMAGEOUT} ) )
  echo "Image file device location: $DEVLOC"

  # A single FAT partition:
  # I tried making two, but the 2nd one's start address didn't follow
  # from the 2nd partition, and I didn't see an easy way to automate that.
  # The issue is that u-boot then overwrites the 2nd partition.
  # That said, since it'll always be the same, I can automate it using the
  # fdisk example below.
  #
  cat <<EOF | sfdisk /dev/${DEVLOC}
1M,2M,1,*
EOF
#,,L

  # Create 2 partitions:
  #echo -e "o\nn\np\n1\n129\n384\nt\nc\nn\np\n2\n385\n\np\nw" | fdisk /dev/${DEVLOC}
  sync

  # Make the loop devices available:
  kpartx -av /dev/${DEVLOC} || exit 1

  # Wait a moment for the devices to settle/appear:
  sync
  sleep 3

  # Make the file systems:
  # U-Boot's FAT partition for its environment, scripts and so on:
  mkfs.msdos -F12 /dev/mapper/${DEVLOC}p1 || exit 1

  # An ext2 partition for the user to do what they wish:
  #mkfs.ext2 /dev/mapper/${DEVLOC}p2 || exit 1

  # If you want to add any files to the filesystem, do it here.
  # FAT partition:
  mount /dev/mapper/${DEVLOC}p1 /mnt/floppy
  echo "# FAT partition" > /mnt/floppy/is_fat.txt
  #echo "console=ttyS0,115200" >> /mnt/floppy/uEnv.txt
  #   cp script.bin uEnv.txt uImage /mnt/floppy
  umount /mnt/floppy
  # ext2 partition:
  #mount /dev/mapper/${DEVLOC}p2 /mnt/floppy
  #echo "# Ext2 partition" > /mnt/floppy/uEnv.txt
  #echo "console=ttyS0,115200" >> /mnt/floppy/uEnv.txt
  # stuff..
  #umount /mnt/floppy

  # Label the device.  This may be used in the future to detect
  # this device within the installer.
  # Name is max 16 chars.
  e2label /dev/mapper/${DEVLOC}p1 "SLKboot:${SLKPORTARCH}"

  # Write U-Boot to this device's SD card image:
  #xz -dc ${ubootbin} | dd of=/dev/${DEVLOC} bs=512 seek=2 conv=fsync
  # seek=8 skips over the MBR.
  xz -dc ${ubootbin} | dd of=/dev/${DEVLOC} bs=1k seek=8

  # Clean up u-boot parameters:
  #dd if=/dev/zero of=/dev/${DEVLOC} bs=512 seek=1024 count=16

  # Detach:
  kpartx -d /dev/${DEVLOC}
  losetup -d /dev/${DEVLOC}

  # Compress the SD card image:
  xz -fez9 ${SDIMAGEOUT}
  # Make a symlink for easy documentation:
  ln -rvfs ${SDIMAGEOUT}.xz ${OUTDIR}/$( echo $( basename ${ubootbin} ) | cut -d. -f1 ).sdcard_latest.img.xz
done
