diff options
Diffstat (limited to 'images/raspberry-pi-2/scripts/mkrootimg')
-rwxr-xr-x | images/raspberry-pi-2/scripts/mkrootimg | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/images/raspberry-pi-2/scripts/mkrootimg b/images/raspberry-pi-2/scripts/mkrootimg new file mode 100755 index 0000000..ff4f07c --- /dev/null +++ b/images/raspberry-pi-2/scripts/mkrootimg @@ -0,0 +1,107 @@ +#!/bin/bash +set -e + +print_usage() { + cat 1>&2 <<EOF +Usage: $0 <rootfs_directory> <image_file> +Package the contents of a debian root filesystem into a binary image file, ready to be burned onto an sd card. + +This script will create an image with two partitions, the first one for /boot/firmware and the second one for /. +EOF +} + +fail() { + echo "$1" >&2 + exit 1 +} + +log() { + echo "mkrootimg: $1" >&2 +} + +# Directory to package +rootfs="$1" + +# Binary image file +image="$2" + +# Contains temporary build files +builddir=$(mktemp -d) + +([ -n "$rootfs" ] && [ -n "$image" ]) || fail "$(print_usage)" +[ -d "$rootfs" ] || fail "$rootfs does not exist or is not a directory" + +[ "$EUID" -eq 0 ] || fail "$0 must be run as root" + +cleanup() { + set +e + umount --lazy "$builddir/mount/boot/firmware" 2> /dev/null + umount --lazy "$builddir/mount" 2> /dev/null + sync + losetup --detach "$bootfs_loop" 2> /dev/null + losetup --detach "$rootfs_loop" 2> /dev/null + rm -rf "$builddir" + trap - 0 1 2 3 6 +} +trap cleanup 0 1 2 3 6 + +# Partition layout +# +# Content Size +# --------------------------------------------- +# reserved 1024k (1M, for e.g. a bootloader) +# bootfs 100*1024k (100M) +# rootfs as required + +# calculate minimum required space for root partition +# (with 25% overhead for reserved blocks and journaling) +rootfs_raw_size_min=$(du --block-size=1M -s "$rootfs" | awk '{ print $1 }') +rootfs_size_min=$(( rootfs_raw_size_min + rootfs_raw_size_min * 25 / 100 )) + +# create and partition image file +truncate --size $(( 1 + 100 + rootfs_size_min ))M "$image" +parted "$image" --script mklabel msdos +parted "$image" --script mkpart primary fat32 1M 100M +parted "$image" --script mkpart primary ext4 100M 100% + +# get actual byte offsets of the partitions within the image +bootfs_start=$(parted --machine --script "$image" unit B print | grep '^1:' | cut -d ':' -f 2 | sed 's/B//g') +bootfs_size=$(parted --machine --script "$image" unit B print | grep '^1:' | cut -d ':' -f 4 | sed 's/B//g') +rootfs_start=$(parted --machine --script "$image" unit B print | grep '^2:' | cut -d ':' -f 2 | sed 's/B//g') +rootfs_size=$(parted --machine --script "$image" unit B print | grep '^2:' | cut -d ':' -f 4 | sed 's/B//g') + +# set up temporary loop devices +log "setting up image loop devices" +bootfs_loop=$(losetup \ + --offset "$bootfs_start" \ + --sizelimit "$bootfs_size" \ + --find \ + --show \ + "$image") +rootfs_loop=$(losetup \ + --offset "$rootfs_start" \ + --sizelimit "$rootfs_size" \ + --find \ + --show \ + "$image") + +# format partitions +log "formatting partitions" +mkfs.vfat -F 32 "$bootfs_loop" &> /dev/null +mkfs.ext4 -O^64bit "$rootfs_loop" &> /dev/null + +# mount partitions +log "mounting partitions" +mkdir -p "$builddir/mount" +mount "$rootfs_loop" "$builddir/mount" +mkdir -p "$builddir/mount/boot/firmware" +mount "$bootfs_loop" "$builddir/mount/boot/firmware" + +# copy root filesystem to image +log "copying root filesystem" +rsync -a "$rootfs/" "$builddir/mount/" + +log "cleaning up" +cleanup + +log "done" |