[PATCH V3 3/6] Add utils/gen-hd-image
gen-hd-image creates partitioned harddisk images from a directory
tree and optionally installs a bootloader into the image. Supported
target filesystems are fat16, fat32 and ext2.
Its main use is building bootable images for armhf/armel/arm64
systems which use u-boot as their system firmware. U-boot
requires the boot device to have an MBR-style partition table,
therefore booting from "superfloppy" style images (like they
are built by d-i for i386/amd64 systems) does not work there.
---
build/util/gen-hd-image | 380 ++++++++++++++++++++++++++++++++++++++++++++++++
debian/changelog | 2 +
debian/control | 9 +-
debian/copyright | 5 +
4 files changed, 394 insertions(+), 2 deletions(-)
create mode 100755 build/util/gen-hd-image
diff --git a/build/util/gen-hd-image b/build/util/gen-hd-image
new file mode 100755
index 0000000..13913f0
--- /dev/null
+++ b/build/util/gen-hd-image
@@ -0,0 +1,380 @@
+#!/bin/sh
+#
+# gen-hd-image V1.01
+# Copyright 2014,2015 by Karsten Merker <merker@debian.org>
+#
+# This file is dual-licensed. It is provided under (at your option)
+# either the terms of the GPL2+ or the terms of the X11 license as
+# described below. Note that this dual licensing only applies to this
+# file, and not this project as a whole.
+#
+# License options:
+#
+# - Option "GPL2+":
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+# On Debian systems, the full text of the GPL version 2 is
+# available in the file /usr/share/common-licenses/GPL-2.
+#
+# - or, alternatively, option "X11":
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+PATH="${PATH}:/bin:/sbin:/usr/bin:/usr/sbin"
+export PATH
+
+FSTYPE="fat32"
+PARTID="0x0c"
+FATSIZE="32"
+BUILDTYPE="complete"
+SOURCEDIR="."
+PARTOFFSET="2048"
+DEFAULT_IMAGESIZE="976560" # default d-i FLOPPY_SIZE for hd-media images
+IMAGESIZE="${DEFAULT_IMAGESIZE}"
+COMPRESS="none"
+COMPRESS_OPTS=""
+VERBOSITY="0"
+PREREQUISITES="fmt sfdisk"
+PREREQUISITES_MISSING=""
+
+log()
+{
+ if [ "${VERBOSITY}" -gt 0 ]; then
+ echo "$(basename $0): $1"
+ fi
+}
+
+error()
+{
+ echo "$(basename $0): $1" 1>&2
+}
+
+clean_tempfiles()
+{
+ [ -f "${TEMP_FS_IMAGEFILE}" ] && rm -f "${TEMP_FS_IMAGEFILE}"
+ [ -f "${TEMP_HD_IMAGEFILE}" ] && rm -f "${TEMP_HD_IMAGEFILE}"
+}
+
+check_prerequisites()
+{
+ for TOOL in $1
+ do
+ which >/dev/null ${TOOL}
+ if [ ! "$?" -eq 0 ]; then
+ PREREQUISITES_MISSING="${PREREQUISITES_MISSING}${TOOL} "
+ fi
+ done
+ if [ -n "${PREREQUISITES_MISSING}" ]; then
+ error "ERROR: The following programs are unavailable, but required"
+ error "ERROR: for the selected options: ${PREREQUISITES_MISSING}"
+ error "ERROR: Exiting."
+ exit 1
+ fi
+}
+
+usage()
+{
+ fmt -w 75 -s <<EOF
+
+$(basename $0) - bootable harddisk image generator
+
+SYNOPSIS:
+
+$(basename $0) -o output_image_name [-s image_size] [-i sourcedir] [-t fstype] [-p partition_offset] [-b build_type] [-z|-j|-J] [-h] [[bootloader_image bootloader_offset] ...]
+
+DESCRIPTION:
+
+$(basename $0) generates harddisk images with a partition table and a
+single primary partition from a directory tree without requiring root
+privileges. It optionally also installs firmware/bootloader
+binaries (usually u-boot) in the image area between the MBR and the
+first partition and allows to generate concatenateable partial images
+(only the MBR+firmware area or only the partition area).
+
+OPTIONS
+
+ -b build_type
+
+ Specify the type of image to build. Valid options are:
+
+ - complete: complete harddisk image (MBR/firmware + partition)
+ - firmware: only MBR/firmware/bootloader image
+ - partition: only partition image
+
+ The default is building a complete harddisk image.
+
+ -h
+
+ Display this help text and exit.
+
+ -i sourcedir
+
+ Specify the source directory from which the filesystem in
+ the image should be generated. The default is the current
+ directory.
+
+ -j
+
+ Compress the image with bzip2.
+
+ -J
+
+ Compress the image with xz.
+
+ -o output_image_name
+
+ Specify the name of the generated image. If one of the
+ compression options (-z/-j/-J) is selected, the according
+ suffix (.gz/.bz2/.xz) will be appended to the supplied
+ file name.
+
+ -p partition_offset
+
+ Specify the partition offset from the beginning of the
+ device in blocks of 512 Bytes. The default is 2048, i.e.
+ the partition starts at an offset of 1 MB.
+
+ -s image_size
+
+ Specify the size of the complete harddisk image in kB.
+ When building partial images, the size of the parts is
+ calculated accordingly, so that the sum of the parts is
+ the specified image size. The default image size is
+ ${DEFAULT_IMAGESIZE} kB.
+
+ -t fstype
+
+ Type of the filesystem to create in the harddisk image.
+ Available options are fat32 (default), fat16 and ext2.
+ Generating large ext2 images can be very slow (ca. 5
+ minutes for a 1GB image on a 1GHz Cortex-A7).
+
+ -v
+
+ Verbose output.
+
+ -z
+
+ Compress the image with gzip.
+
+The bootloader_image and bootloader_offset parameters specify which
+bootloader image should be installed at which offset (in blocks of 512
+Bytes) from the start of the harddisk image. This parameter set can be
+used multiple times to install multi-part bootloader images (e.g. to
+install u-boot versions with separate SPL images).
+
+EOF
+}
+
+# Parse parameters:
+# -h help
+# -i input directory
+# -o output filename
+# -s size of disk image
+# -t type of filesystem (fat16/fat32/ext2)
+# -p partition offset
+# -b build type (complete/firmware/partition)
+# -z/-j/-J gzip/bzip2/xz compression
+# -v verbose
+
+while getopts "hi:o:s:t:p:b:zjJv" option; do
+ case ${option} in
+ h)
+ usage
+ exit 0
+ ;;
+ i)
+ SOURCEDIR="${OPTARG}"
+ ;;
+ o)
+ IMAGEFILE="${OPTARG}"
+ ;;
+ s)
+ IMAGESIZE="${OPTARG}"
+ ;;
+ t)
+ FSTYPE="${OPTARG}"
+ case "${FSTYPE}" in
+ fat16)
+ PARTID="0x0e"
+ FATSIZE="16"
+ ;;
+ fat32)
+ PARTID="0x0c"
+ FATSIZE="32"
+ ;;
+ ext2)
+ PARTID="0x83"
+ ;;
+ *)
+ echo "$(basename $0): Invalid filesystem type \"${FSTYPE}\". Use fat16, fat32 or ext2."
+ exit 1
+ ;;
+ esac
+ ;;
+ p)
+ PARTOFFSET="${OPTARG}"
+ ;;
+ b)
+ BUILDTYPE="${OPTARG}"
+ case "${BUILDTYPE}" in
+ complete|firmware|partition)
+ ;;
+ *)
+ echo "$(basename $0): Invalid build type \"${BUILDTYPE}\". Use complete, firmware or partition."
+ exit 1
+ ;;
+ esac
+ ;;
+ z)
+ COMPRESS="gzip"
+ COMPRESS_OPTS="-n"
+ PREREQUISITES="${PREREQUISITES} gzip"
+ ;;
+ j)
+ COMPRESS="bzip2"
+ PREREQUISITES="${PREREQUISITES} bzip2"
+ ;;
+ J)
+ COMPRESS="xz"
+ PREREQUISITES="${PREREQUISITES} xz"
+ ;;
+ v)
+ VERBOSITY="1"
+ ;;
+ esac
+done
+
+shift $((${OPTIND}-1))
+
+case "${FSTYPE}" in
+ fat16|fat32)
+ PREREQUISITES="${PREREQUISITES} mkfs.msdos mcopy"
+ ;;
+ ext2)
+ PREREQUISITES="${PREREQUISITES} genext2fs"
+ ;;
+esac
+
+check_prerequisites "${PREREQUISITES}"
+
+FS_SIZE=$((${IMAGESIZE}-${PARTOFFSET}/2))
+if [ ${FS_SIZE} -lt 34816 ] && [ "${FSTYPE}" = "fat32" ]; then
+ error "INFO: Image size too small for FAT32, using FAT16."
+ FSTYPE="fat16"
+ PARTID="0x0e"
+ FATSIZE="16"
+fi
+if [ ${FS_SIZE} -gt 2097152 ] && [ "${FSTYPE}" = "fat16" ]; then
+ error "INFO: Image size too big for FAT16, using FAT32."
+ FSTYPE="fat32"
+ PARTID="0x0c"
+ FATSIZE="32"
+fi
+
+log "Starting to generate image ${IMAGEFILE} ..."
+
+case "${BUILDTYPE}" in
+ complete|firmware)
+ log "Building partition table ..."
+ TEMP_HD_IMAGEFILE=$(mktemp)
+ dd 2>/dev/null if=/dev/zero bs=1k of="${TEMP_HD_IMAGEFILE}" seek=$((${IMAGESIZE}-1)) count=1
+ sfdisk --force -u S "${TEMP_HD_IMAGEFILE}" 1>/dev/null 2>/dev/null <<EOF
+${PARTOFFSET}, ,${PARTID},*,
+EOF
+ while [ "$#" -ge "2" ]
+ do
+ if [ -n "$1" ]; then
+ BOOTLOADER_IMAGE="$1"
+ BOOTLOADER_OFFSET="$2"
+ log "Installing ${BOOTLOADER_IMAGE} at sector ${BOOTLOADER_OFFSET} ..."
+ dd 2>/dev/null if="${BOOTLOADER_IMAGE}" of="${TEMP_HD_IMAGEFILE}" bs=512 seek="${BOOTLOADER_OFFSET}" conv=notrunc
+ fi
+ shift 2
+ done
+ if [ "$#" -eq 1 ]; then
+ error "ERROR: Firmware/bootloader image name or offset missing. Exiting."
+ clean_tempfiles
+ exit 1
+ fi
+ ;;
+esac
+
+case "${BUILDTYPE}" in
+ complete|partition)
+ log "Building filesystem ..."
+ TEMP_FS_IMAGEFILE=$(mktemp)
+ TEMP_FS_IMAGESIZE=$((${IMAGESIZE}-${PARTOFFSET}/2)) # fs size in kB
+ dd 2>/dev/null if=/dev/zero bs=1k of="${TEMP_FS_IMAGEFILE}" seek=$((${TEMP_FS_IMAGESIZE}-1)) count=1
+ case "${FSTYPE}" in
+ fat16|fat32)
+ mkfs.msdos >/dev/null -F "${FATSIZE}" "${TEMP_FS_IMAGEFILE}" "${TEMP_FS_IMAGESIZE}"
+ mcopy -s -i "${TEMP_FS_IMAGEFILE}" ${SOURCEDIR}// ::
+ # The trailing // is necessary to make mcopy copy the contents
+ # of ${SOURCEDIR} but not ${SOURCEDIR} itself. Using ${SOURCEDIR}/*
+ # would omit dotfiles and ${SOURCEDIR}/. does not work with mcopy.
+ ;;
+ ext2)
+ genext2fs -z -U -d "${SOURCEDIR}" -b "${TEMP_FS_IMAGESIZE}" "${TEMP_FS_IMAGEFILE}"
+ ;;
+ esac
+ ;;
+esac
+
+case "${BUILDTYPE}" in
+ firmware)
+ dd 2>/dev/null if="${TEMP_HD_IMAGEFILE}" bs=512 count="${PARTOFFSET}" of="${IMAGEFILE}"
+ ;;
+ complete)
+ dd 2>/dev/null if="${TEMP_HD_IMAGEFILE}" bs=512 count="${PARTOFFSET}" of="${IMAGEFILE}"
+ cat "${TEMP_FS_IMAGEFILE}" >> "${IMAGEFILE}"
+ ;;
+ partition)
+ mv "${TEMP_FS_IMAGEFILE}" "${IMAGEFILE}"
+ ;;
+esac
+
+if [ ! "${COMPRESS}" = "none" ];
+then
+ log "Compressing image ..."
+ "${COMPRESS}" ${COMPRESS_OPTS} -f "${IMAGEFILE}"
+fi
+
+clean_tempfiles
+
+log "Image finished."
+
+exit 0
diff --git a/debian/changelog b/debian/changelog
index d81210a..4fafb44 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,8 @@ debian-installer (201410XX) UNRELEASED; urgency=medium
* Add boot/arm/u-boot-image-config (a list of u-boot components and their
offsets on disk, needed to create bootable images for arm-based systems).
* Provide u-boot binaries for armhf systems without u-boot in flash.
+ * Add utils/gen-hd-image (a script to create partitioned harddisk images
+ from a directory and optionally install a bootloader into the image).
[ Aurelien Jarno ]
* Add scsi-modules to the cdrom flavour on ppc64el to be able to access
diff --git a/debian/control b/debian/control
index fbdb166..bf3a66d 100644
--- a/debian/control
+++ b/debian/control
@@ -68,11 +68,12 @@ Build-Depends:
# default.)
hfsutils [powerpc],
# For making bootable HFS USB sticks for powerpc.
- dosfstools [i386 ia64 m68k amd64 arm64],
+ dosfstools [i386 ia64 m68k amd64 armhf arm64],
# For creating FAT filesystems with mkfs.msdos.
# Of course i386/amd64 use this for floppies, CDs etc.
# ia64 uses it for floppies (?)
# m68k uses it for atari floppies
+# armhf uses it for building bootable SD card images
cpio,
# For creating initramfs images.
xz-utils,
@@ -133,12 +134,16 @@ Build-Depends:
# Used to make EFI bootable images
grub-ieee1275-bin [ppc64el],
# IEEE1275 bootloader support.
+ u-boot-imx [armhf],
+ u-boot-omap [armhf],
+ u-boot-sunxi [armhf],
+# U-boot binaries, needed to build bootable SD card images.
#
# Architecture specific build dependencies:
tofrodos [i386 amd64 kfreebsd-i386 kfreebsd-amd64],
# For todos, used on files that need to be accessible from
# DOS.
- mtools [i386 ia64 m68k amd64 arm64 kfreebsd-i386 kfreebsd-amd64 hurd-i386],
+ mtools [i386 ia64 m68k amd64 armhf arm64 kfreebsd-i386 kfreebsd-amd64 hurd-i386],
# mcopy is used to put files onto FAT filesystems w/o
# mounting them.
#
diff --git a/debian/copyright b/debian/copyright
index a9bca6c..a733f34 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -25,3 +25,8 @@ a rebuilt-from-scratch "debian" word.
build/boot/hurd/pics/joy-hurd.{svg,png}
build/boot/kfreebsd/pics/joy-kbsd.{svg,png}
build/boot/x86/pics/joy.{svg,png}
+
+The gen-hd-image tool, used to build bootable partitioned disk images, is
+Copyright 2014,2015 Karsten Merker <merker@debian.org> and is dual-licensed.
+It is provided under the terms of the GNU GPL version 2 or any later
+version, or alternatively under the terms of the X11 license.
--
2.1.4
Reply to: