Skip to content

Instantly share code, notes, and snippets.

@jpkotta
Created September 24, 2015 18:06
Show Gist options
  • Save jpkotta/afbfff4b7d66058ba238 to your computer and use it in GitHub Desktop.
Save jpkotta/afbfff4b7d66058ba238 to your computer and use it in GitHub Desktop.
#!/bin/bash
set -o errexit -o nounset -o pipefail
IFS=$'\n\t'
this="$0"
emmc_mode=false
if [[ "$this" == *make-emmc.sh ]] ; then
emmc_mode=true
fi
default_rootfs_tarball="rootfs.tar.bz2"
interactive=false
rootfs_tarball="$default_rootfs_tarball"
function usage() {
echo "Usage: $this [-r rootfs-archive] disk-device"
echo "Creates a drive suitable for booting with U-Boot."
echo
echo "disk-device"
echo " Format the disk device to format (e.g. /dev/mmcblk0)."
echo
echo "-r rootfs-archive"
echo " A tarball that contains a rootfs. Default is '$default_rootfs_tarball'."
echo
echo "Here's a list of unmounted disks:"
find_unmounted_disks
}
function find_unmounted_disks() {
for pat in "/dev/sd[a-z]" "/dev/mmcblk[0-9]" ; do
if ls $pat >&/dev/null ; then
for i in $pat ; do
mount | grep -q "$i" || echo "$i"
done
fi
done
}
function parse_args() {
while [ $# -gt 1 ] ; do
case ${1:-} in
-h|--help)
usage
exit 0
;;
-r|--rootfs)
shift
rootfs_tarball="$1"
;;
-i|--interactive)
interactive=true
;;
*)
echo "Invalid argument '$1'."
exit 1
;;
esac
shift
done
if [ $# -ne 1 ] ; then
usage
exit 1
fi
disk_dev="${1:-}" # last arg
}
function clean_up() {
# this should always be the last command, so clear the traps
trap - ERR EXIT
echo "Cleaning up."
rm -rf "$extract_point"
umount "$mount_point" >&/dev/null || true
rm -rf "$mount_point"
}
function on_err() {
echo "Fail."
clean_up
}
function set_up() {
mount_point=$(mktemp -d)
extract_point=$(mktemp -d)
trap on_err ERR EXIT
if ! stat "$disk_dev" 2>/dev/null | grep -q "block special file" ; then
echo "Device '$disk_dev' does not exist or is not a block device."
exit 1
fi
if mount | grep -q "$disk_dev" ; then
echo "Disk '$disk_dev' is already mounted! Unmount and try again."
exit 1
fi
if ! [ -f "$rootfs_tarball" ] ; then
echo "Could not find rootfs '$rootfs_tarball'."
exit 1
fi
echo "Using disk '$disk_dev'."
echo "Using root filesystem in '$rootfs_tarball'."
if $interactive ; then
read -p "Press enter to continue or C-c to quit."
fi
# clear the partition table and the beginning of the disk
echo "Clearing partition table."
dd if=/dev/zero of="$disk_dev" bs=512 count=2048 conv=notrunc >&/dev/null
sync
echo "Untarring '$rootfs_tarball'."
tar xf "$rootfs_tarball" -C "$extract_point"
}
function make_sdcard() {
trap on_err ERR EXIT
echo "Partitioning '$disk_dev'."
# '\n' is replaced with '_' for readability
echo "n_p_1_2048___"\
"a_1_"\
"w_"\
| tr "_" "\n" \
| fdisk "$disk_dev" >&/dev/null
fdisk -l "$disk_dev"
# format
echo "Formatting partitions."
local p=
if [[ "$disk_dev" == */mmc* ]] ; then
# mmc partitions are enumerated like /dev/mmcblk0p1
# "SCSI" partitions are enumerated like /dev/sda1
p="p"
fi
local root_a="${disk_dev}${p}1"
mkfs.ext4 -L "root_a" "$root_a" >&/dev/null
sync
echo "Populating root partitions."
for fs in "$root_a" ; do
mount "$fs" "$mount_point"
cp -a "$extract_point"/* "$mount_point"
cp "$rootfs_tarball" "$mount_point"/root/rootfs.tar.bz2
cp "$this" "$mount_point"/root/make-emmc.sh
sync
umount "$mount_point"
done
}
function make_emmc() {
trap on_err ERR EXIT
# '\n' is replaced with '_' for readability
echo "n_p_1_2048_+1G_"\
"n_p_2__+1G_"\
"n_p_3___"\
"a_1_"\
"a_2_"\
"w_" \
| tr "_" "\n" \
| fdisk "$disk_dev" >&/dev/null
# format
echo "Formatting partitions."
local p=
if [[ "$disk_dev" == */mmc* ]] ; then
# mmc partitions are enumerated like /dev/mmcblk0p1
# "SCSI" partitions are enumerated like /dev/sda1
p="p"
fi
local root_a="${disk_dev}${p}1"
local root_b="${disk_dev}${p}2"
local usr_data="${disk_dev}${p}3"
mkfs.ext4 -L "root_a" "$root_a" >&/dev/null
mkfs.ext4 -L "root_b" "$root_b" >&/dev/null
mkfs.ext4 -L "usr_data" "$usr_data" >&/dev/null
sync
# populate
echo "Populating root partitions."
for fs in "$root_a" "$root_b" ; do
mount "$fs" "$mount_point"
cp -a "$extract_point"/* "$mount_point"
sync
umount "$mount_point"
done
}
if [ $UID -ne 0 ] ; then
echo "This script must be run as root."
exit 1
fi
parse_args $@
if $emmc_mode ; then
echo "Setting up SD card."
else
echo "Setting up eMMC."
fi
set_up
if $emmc_mode ; then
make_emmc
else
make_sdcard
fi
clean_up
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment