Enable detection of bmaptool, and if present generate sparse files.

This uses https://github.com/intel/bmap-tools to generate a .bmap file
which can be copied around. The bmaptool allows storing sparse files
onto for instance an SD card, thus avoiding having to transfer the full
disk image every time one burns one.
Thus saving lots of time (and SD card cycles).

This also adds some instructions for then transfering and copying the
sparse file.

bmaptool: info: discovered bmap file '/Users/jeroen/berry.img.bmap'
bmaptool: info: block map format version 2.0
bmaptool: info: 7324219 blocks of size 4096 (27.9 GiB), mapped 1539940 blocks (5.9 GiB or 21.0%)
bmaptool: info: copying image 'berry.img' to file 'rdisk4' using bmap file 'berry.img.bmap'
bmaptool: info: 100% copied
bmaptool: info: synchronizing '/dev/rdisk4'
bmaptool: info: copying time: 6m 49.7s, copying speed 14.7 MiB/sec

versus copying the whole 30G which would take forever...
This commit is contained in:
Jeroen Massar
2019-10-02 11:33:07 +02:00
parent 8c840f9c82
commit a4e2fe02b6
2 changed files with 59 additions and 5 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
*.img *.img
*.img.bmap
*.pcap *.pcap
__pycache__ __pycache__
_backups _backups

View File

@ -5,14 +5,17 @@
set -eu set -eu
REQUIREMENTS=( wget gunzip git dd e2fsck resize2fs parted losetup qemu-system-x86_64 ) REQUIREMENTS=( wget gunzip git dd e2fsck resize2fs parted losetup qemu-system-x86_64 )
DEBREQUIREMENTS=( wget gzip git parted qemu-system-x86 qemu-user-static parted bmap-tools )
REPO_DIR="$(dirname "$(dirname "$(realpath "$0")")")" REPO_DIR="$(dirname "$(dirname "$(realpath "$0")")")"
TMP_DIR="${REPO_DIR}/tmp" TMP_DIR="${REPO_DIR}/tmp"
MNT_DIR="${TMP_DIR}/mnt" MNT_DIR="${TMP_DIR}/mnt"
THIS_DIR=$(pwd)
PWNI_NAME="pwnagotchi" PWNI_NAME="pwnagotchi"
PWNI_OUTPUT="pwnagotchi.img" PWNI_OUTPUT="pwnagotchi.img"
PWNI_SIZE="4" PWNI_SIZE="4"
OPT_SPARSE=0
OPT_PROVISION_ONLY=0 OPT_PROVISION_ONLY=0
OPT_CHECK_DEPS_ONLY=0 OPT_CHECK_DEPS_ONLY=0
OPT_IMAGE_PROVIDED=0 OPT_IMAGE_PROVIDED=0
@ -26,6 +29,18 @@ if [[ "$EUID" -ne 0 ]]; then
fi fi
function check_dependencies() { function check_dependencies() {
if [ -f /etc/debian_version ];
then
echo "[+] Checking Debian dependencies"
for REQ in "${DEBREQUIREMENTS[@]}"; do
if ! dpkg -s "$REQ" >/dev/null 2>&1; then
echo "Dependency check failed for ${REQ}; use 'apt-get install ${REQ}' to install"
exit 1
fi
done
fi
echo "[+] Checking dependencies" echo "[+] Checking dependencies"
for REQ in "${REQUIREMENTS[@]}"; do for REQ in "${REQUIREMENTS[@]}"; do
if ! type "$REQ" >/dev/null 2>&1; then if ! type "$REQ" >/dev/null 2>&1; then
@ -76,8 +91,31 @@ function provide_raspbian() {
} }
function setup_raspbian(){ function setup_raspbian(){
echo "[+] Resize image" # Detect the ability to create sparse files
dd if=/dev/zero bs=1G count="$PWNI_SIZE" >> "${TMP_DIR}/raspbian.img" if [ "${OPT_SPARSE}" -eq 0 ];
then
which bmaptool >/dev/null 2>&1
if [ $? -eq 0 ];
then
echo "[+] Defaulting to sparse image generation as bmaptool is available"
OPT_SPARSE=1
else
echo "[!] bmaptool not available, not creating a sparse image"
fi
fi
# Note that we 'extend' the raspbian.img
if [ "${OPT_SPARSE}" -eq 1 ];
then
# Resize sparse (so that we can use bmaptool later)
echo "[+] Resizing sparse image of ${PWNI_SIZE}GB (1000s)"
truncate -s ${PWNI_SIZE}GB "${TMP_DIR}/raspbian.img"
else
echo "[+] Resizing full image to ${PWNI_SIZE}G"
# Full disk-space using image (appends to raspbian image)
dd if=/dev/zero bs=1G count="${PWNI_SIZE}" >> "${TMP_DIR}/raspbian.img"
fi
echo "[+] Setup loop device" echo "[+] Setup loop device"
mkdir -p "${MNT_DIR}" mkdir -p "${MNT_DIR}"
LOOP_PATH="$(losetup --find --partscan --show "${TMP_DIR}/raspbian.img")" LOOP_PATH="$(losetup --find --partscan --show "${TMP_DIR}/raspbian.img")"
@ -107,7 +145,7 @@ function provision_raspbian() {
cd "${MNT_DIR}" cd "${MNT_DIR}"
sed -i'' 's/^\([^#]\)/#\1/g' etc/ld.so.preload # add comments sed -i'' 's/^\([^#]\)/#\1/g' etc/ld.so.preload # add comments
echo "[+] Run chroot commands" echo "[+] Run chroot commands"
LANG=C chroot . bin/bash -x <<EOF LANG=C LC_ALL=C LC_CTYPE=C chroot . bin/bash -x <<EOF
set -eu set -eu
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
@ -203,7 +241,11 @@ EOF
cd "${REPO_DIR}" cd "${REPO_DIR}"
umount -R "${MNT_DIR}" umount -R "${MNT_DIR}"
losetup -D "$(losetup -l | awk '/raspbian\.img/{print $1}')" losetup -D "$(losetup -l | awk '/raspbian\.img/{print $1}')"
mv "${TMP_DIR}/raspbian.img" "$PWNI_OUTPUT" mv "${TMP_DIR}/raspbian.img" "${PWNI_OUTPUT}"
if [ "${OPT_SPARSE}" -eq 1 ];
then
bmaptool create -o "${PWNI_OUTPUT}.bmap" "${PWNI_OUTPUT}"
fi
} }
function usage() { function usage() {
@ -216,6 +258,7 @@ usage: $0 [OPTIONS]
-i <file> # Provide the path of an already downloaded raspbian image -i <file> # Provide the path of an already downloaded raspbian image
-o <file> # Name of the img-file (default: pwnagotchi.img) -o <file> # Name of the img-file (default: pwnagotchi.img)
-s <size> # Size which should be added to second partition (in Gigabyte) (default: 4) -s <size> # Size which should be added to second partition (in Gigabyte) (default: 4)
-S # Create a sparse image and generate bmap file (default when bmaptool is available)
-v <version> # Version of raspbian (Supported: ${SUPPORTED_RASPBIAN_VERSIONS[*]}; default: latest) -v <version> # Version of raspbian (Supported: ${SUPPORTED_RASPBIAN_VERSIONS[*]}; default: latest)
-p # Only run provisioning (assumes the image is already mounted) -p # Only run provisioning (assumes the image is already mounted)
-d # Only run dependencies checks -d # Only run dependencies checks
@ -283,4 +326,14 @@ fi
setup_raspbian setup_raspbian
provision_raspbian provision_raspbian
echo -ne "[+] Congratz, it's a boy (⌐■_■)!\n[+] One more step: dd if=../$PWNI_OUTPUT of=<PATH_TO_SDCARD> bs=4M status=progress" echo -e "[+] Congratz, it's a boy (⌐■_■)!"
echo -e "[+] One more step: dd if=../${PWNI_OUTPUT} of=<PATH_TO_SDCARD> bs=4M status=progress"
if [ "${OPT_SPARSE}" -eq 1 ];
then
echo -e "[t] To transfer use: rsync -vaS --progress $(whoami)@$(hostname -f):${THIS_DIR}/../${PWNI_OUTPUT} <DEST>"
echo -e "[t] To burn with bmaptool: bmaptool copy ~/${PWNI_OUTPUT} /dev/<DEVICE>"
fi
# Helpful OSX reminder
echo -e "[t] Mac: use 'diskutil list' to figure out which device to burn to; 'diskutil unmountDisk' to unmount that disk'; then use /dev/rdiskX (note the 'r') for faster transfer"