diff options
author | Michael Brown <mcb30@ipxe.org> | 2021-01-13 11:50:26 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2021-01-13 17:58:02 +0000 |
commit | 79c0173d6df8580ea2e35fc173a5281e65d5321f (patch) | |
tree | 0320cc223756e5aa47426e4aeb6f586f9d995d96 /src | |
parent | c42f31bc8ad8ffce57b8662f902a343b1a4d3209 (diff) | |
download | ipxe-79c0173d6df8580ea2e35fc173a5281e65d5321f.tar.gz |
[build] Create util/genfsimg for building filesystem-based images
Generalise util/geniso, util/gensdsk, and util/genefidsk to create a
single script util/genfsimg that can be used to build either FAT
filesystem images or ISO images.
Extend the functionality to allow for building multi-architecture UEFI
bootable ISO images and combined BIOS+UEFI images.
For example:
./util/genfsimg -o combined.iso \
bin-x86_64-efi/ipxe.efi \
bin-arm64-efi/ipxe.efi \
bin/ipxe.lkrn
would generate a hybrid image that could be used as a CDROM (or hard
disk or USB key) on legacy BIOS, x86_64 UEFI, or ARM64 UEFI.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.efi | 6 | ||||
-rw-r--r-- | src/arch/x86/Makefile.pcbios | 43 | ||||
-rwxr-xr-x | src/util/genefidsk | 60 | ||||
-rwxr-xr-x | src/util/genfsimg | 253 | ||||
-rwxr-xr-x | src/util/geniso | 141 | ||||
-rwxr-xr-x | src/util/gensdsk | 65 |
6 files changed, 260 insertions, 308 deletions
diff --git a/src/Makefile.efi b/src/Makefile.efi index 10f3fe74b..4b35381d3 100644 --- a/src/Makefile.efi +++ b/src/Makefile.efi @@ -49,6 +49,6 @@ $(BIN)/efidrv.cab : $(BIN)/alldrv.efis # $(ALL_drv.efi) is not yet defined $(QM)$(ECHO) " [CAB] $@" $(Q)$(LCAB) -n -q $(ALL_drv.efi) $@ -$(BIN)/%.usb : $(BIN)/%.efi - $(QM)$(ECHO) " [GENEFIDSK] $@" - $(Q)bash util/genefidsk -o $@ -b $(EFI_BOOT_FILE) $< +$(BIN)/%.iso $(BIN)/%.usb : $(BIN)/%.efi util/genfsimg + $(QM)$(ECHO) " [GENFSIMG] $@" + $(Q)util/genfsimg -o $@ $< diff --git a/src/arch/x86/Makefile.pcbios b/src/arch/x86/Makefile.pcbios index c44eefc1f..751d7d28c 100644 --- a/src/arch/x86/Makefile.pcbios +++ b/src/arch/x86/Makefile.pcbios @@ -57,46 +57,11 @@ LIST_NAME_mrom := ROMS LIST_NAME_pcirom := ROMS LIST_NAME_isarom := ROMS -# Locations of isolinux files -# -SYSLINUX_DIR_LIST := \ - /usr/lib/syslinux \ - /usr/lib/syslinux/bios \ - /usr/lib/syslinux/modules/bios \ - /usr/share/syslinux \ - /usr/share/syslinux/bios \ - /usr/share/syslinux/modules/bios \ - /usr/local/share/syslinux \ - /usr/local/share/syslinux/bios \ - /usr/local/share/syslinux/modules/bios \ - /usr/lib/ISOLINUX -ISOLINUX_BIN_LIST := \ - $(ISOLINUX_BIN) \ - $(patsubst %,%/isolinux.bin,$(SYSLINUX_DIR_LIST)) -LDLINUX_C32_LIST := \ - $(LDLINUX_C32) \ - $(patsubst %,%/ldlinux.c32,$(SYSLINUX_DIR_LIST)) -ISOLINUX_BIN = $(firstword $(wildcard $(ISOLINUX_BIN_LIST))) -LDLINUX_C32 = $(firstword $(wildcard $(LDLINUX_C32_LIST))) - -# rule to make a non-emulation ISO boot image +# ISO or FAT filesystem images NON_AUTO_MEDIA += iso -%iso: %lkrn util/geniso - $(QM)$(ECHO) " [GENISO] $@" - $(Q)ISOLINUX_BIN=$(ISOLINUX_BIN) LDLINUX_C32=$(LDLINUX_C32) \ - VERSION="$(VERSION)" bash util/geniso -o $@ $< - -# rule to make a floppy emulation ISO boot image -NON_AUTO_MEDIA += liso -%liso: %lkrn util/geniso - $(QM)$(ECHO) " [GENISO] $@" - $(Q)VERSION="$(VERSION)" bash util/geniso -l -o $@ $< - -# rule to make a syslinux floppy image (mountable, bootable) -NON_AUTO_MEDIA += sdsk -%sdsk: %lkrn util/gensdsk - $(QM)$(ECHO) " [GENSDSK] $@" - $(Q)bash util/gensdsk $@ $< +$(BIN)/%.iso $(BIN)/%.sdsk: $(BIN)/%.lkrn util/genfsimg + $(QM)$(ECHO) " [GENFSIMG] $@" + $(Q)util/genfsimg -o $@ $< # rule to write disk images to /dev/fd0 NON_AUTO_MEDIA += fd0 diff --git a/src/util/genefidsk b/src/util/genefidsk deleted file mode 100755 index 7064f99b6..000000000 --- a/src/util/genefidsk +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -# -# Generate an EFI bootable disk image - -set -e - -function help() { - echo "Usage: ${0} [OPTIONS] <ipxe.efi>" - echo - echo "where OPTIONS are:" - echo " -h Show this help" - echo " -b Specify boot file name (e.g. bootx64.efi)" - echo " -o FILE Save disk image to file" -} - -BOOT=bootx64.efi - -while getopts "hb:o:" opt; do - case ${opt} in - h) - help - exit 0 - ;; - b) - BOOT="${OPTARG}" - ;; - o) - OUT="${OPTARG}" - ;; - esac -done - -shift $((OPTIND - 1)) -IN=$1 - -if [ -z "${IN}" ]; then - echo "${0}: no input file given" >&2 - help - exit 1 -fi - -if [ -z "${OUT}" ]; then - echo "${0}: no output file given" >&2 - help - exit 1 -fi - -# Create sparse output file -rm -f ${OUT} -truncate -s 1440K ${OUT} - -# Format disk -mformat -i ${OUT} -f 1440 :: - -# Create directory structure -mmd -i ${OUT} ::efi -mmd -i ${OUT} ::efi/boot - -# Copy bootable image -mcopy -i ${OUT} ${IN} ::efi/boot/${BOOT} diff --git a/src/util/genfsimg b/src/util/genfsimg new file mode 100755 index 000000000..e49d4d7ed --- /dev/null +++ b/src/util/genfsimg @@ -0,0 +1,253 @@ +#!/bin/sh +# +# Generate a filesystem-based image + +set -e +set -u + +# Print usage message +# +help() { + echo "usage: ${0} [OPTIONS] foo.lkrn|foo.efi [bar.lkrn|bar.efi,...]" + echo + echo "where OPTIONS are:" + echo " -h show this help" + echo " -o FILE save image to file" + echo " -p PAD pad filesystem (in kB)" +} + +# Get hex word from binary file +# +get_word() { + local FILENAME + local OFFSET + + FILENAME="${1}" + OFFSET="${2}" + + od -j "${OFFSET}" -N 2 -A n -t x1 -- "${FILENAME}" | tr -d " " +} + +# Get appropriate EFI boot filename for CPU architecture +# +efi_boot_name() { + local FILENAME + local PESIG + local ARCH + + FILENAME="${1}" + + PESIG=$(get_word "${FILENAME}" 192) + if [ "${PESIG}" != "5045" ] ; then + echo "${FILENAME}: not an EFI executable" >&2 + exit 1 + fi + ARCH=$(get_word "${FILENAME}" 196) + case "${ARCH}" in + "4c01" ) + echo "BOOTIA32.EFI" + ;; + "6486" ) + echo "BOOTX64.EFI" + ;; + "c201" ) + echo "BOOTARM.EFI" + ;; + "64aa" ) + echo "BOOTAA64.EFI" + ;; + * ) + echo "${FILENAME}: unrecognised EFI architecture ${ARCH}" >&2 + exit 1 + esac +} + +# Copy syslinux file +# +copy_syslinux_file() { + local FILENAME + local DESTDIR + local SRCDIR + + FILENAME="${1}" + DESTDIR="${2}" + + for SRCDIR in \ + /usr/lib/syslinux \ + /usr/lib/syslinux/bios \ + /usr/lib/syslinux/modules/bios \ + /usr/share/syslinux \ + /usr/share/syslinux/bios \ + /usr/share/syslinux/modules/bios \ + /usr/local/share/syslinux \ + /usr/local/share/syslinux/bios \ + /usr/local/share/syslinux/modules/bios \ + /usr/lib/ISOLINUX \ + ; do + if [ -e "${SRCDIR}/${FILENAME}" ] ; then + cp "${SRCDIR}/${FILENAME}" "${DESTDIR}/" + break + fi + done +} + +# Parse command-line options +# +OUTFILE= +PAD=0 +while getopts "hlo:p:" OPTION ; do + case "${OPTION}" in + h) + help + exit 0 + ;; + o) + OUTFILE="${OPTARG}" + ;; + p) + PAD="${OPTARG}" + ;; + *) + help + exit 1 + ;; + esac +done +if [ -z "${OUTFILE}" ]; then + echo "${0}: no output file given" >&2 + help + exit 1 +fi +shift $(( OPTIND - 1 )) + +# Create temporary working directory +# +WORKDIR=$(mktemp -d "${OUTFILE}.XXXXXX") +ISODIR="${WORKDIR}/iso" +FATDIR="${WORKDIR}/fat" +mkdir -p "${ISODIR}" "${FATDIR}" + +# Configure output +# +case "${OUTFILE}" in + *.iso) + ISOIMG="${OUTFILE}" + FATIMG="${ISODIR}/esp.img" + BIOSDIR="${ISODIR}" + SYSLINUXCFG="${ISODIR}/isolinux.cfg" + ;; + *) + ISOIMG= + FATIMG="${OUTFILE}" + BIOSDIR="${FATDIR}" + SYSLINUXCFG="${FATDIR}/syslinux.cfg" + ;; +esac +ISOARGS= + +# Locate required tools +# +if [ -n "${ISOIMG}" ] ; then + MKISOFS= + for CMD in genisoimage mkisofs ; do + if ${CMD} --version >/dev/null 2>/dev/null ; then + MKISOFS="${CMD}" + break + fi + done + if [ -z "${MKISOFS}" ] ; then + echo "${0}: cannot find mkisofs or equivalent" >&2 + exit 1 + fi +fi + +# Copy files to temporary working directory +# +LKRN= +EFI= +for FILENAME ; do + case "${FILENAME}" in + *.lkrn) + DESTDIR="${BIOSDIR}" + DESTFILE=$(basename "${FILENAME}") + if [ -z "${LKRN}" ] ; then + echo "SAY iPXE boot image" > "${SYSLINUXCFG}" + echo "TIMEOUT 30" >> "${SYSLINUXCFG}" + echo "DEFAULT ${DESTFILE}" >> "${SYSLINUXCFG}" + fi + echo "LABEL ${DESTFILE}" >> "${SYSLINUXCFG}" + echo " KERNEL ${DESTFILE}" >> "${SYSLINUXCFG}" + LKRN=1 + ;; + *.efi) + DESTDIR="${FATDIR}/EFI/BOOT" + DESTFILE=$(efi_boot_name "${FILENAME}") + if [ -z "${EFI}" ] ; then + mkdir -p "${DESTDIR}" + fi + EFI=1 + ;; + *) + echo "${0}: unrecognised input filename ${FILENAME}" >&2 + help + exit 1 + ;; + esac + if [ -e "${DESTDIR}/${DESTFILE}" ] ; then + echo "${0}: duplicate ${DESTFILE} from ${FILENAME}" >&2 + exit 1 + fi + cp "${FILENAME}" "${DESTDIR}/${DESTFILE}" +done + +# Configure ISO image, if applicable +# +# Note that the BIOS boot files are required even for an EFI-only ISO, +# since isohybrid will refuse to work without them. +# +if [ -n "${ISOIMG}" ] ; then + copy_syslinux_file "isolinux.bin" "${ISODIR}" + copy_syslinux_file "ldlinux.c32" "${ISODIR}" || true + ISOARGS="${ISOARGS} -no-emul-boot -eltorito-boot isolinux.bin" + ISOARGS="${ISOARGS} -boot-load-size 4 -boot-info-table" + if [ -n "${EFI}" ] ; then + ISOARGS="${ISOARGS} -eltorito-alt-boot -no-emul-boot -efi-boot esp.img" + else + FATIMG= + fi +fi + +# Create FAT filesystem image, if applicable +# +if [ -n "${FATIMG}" ] ; then + FATSIZE=$(du -s -k ${FATDIR} | cut -f1) + FATSIZE=$(( FATSIZE + PAD + 256 )) + touch "${FATIMG}" + if [ "${FATSIZE}" -le "1440" ] ; then + truncate -s 1440K "${FATIMG}" + mformat -f 1440 -i "${FATIMG}" :: + else + truncate -s "${FATSIZE}K" "${FATIMG}" + mformat -i "${FATIMG}" :: + fi + mcopy -i "${FATIMG}" -s "${FATDIR}"/* :: + if [ "${BIOSDIR}" = "${FATDIR}" ] ; then + syslinux "${FATIMG}" + fi +fi + +# Create ISO filesystem image, if applicable +# +if [ -n "${ISOIMG}" ] ; then + "${MKISOFS}" -quiet -volid "iPXE" -preparer "iPXE build system" \ + -appid "iPXE - Open Source Network Boot Firmware" \ + -publisher "ipxe.org" -sysid "iPXE" -J -R -o "${ISOIMG}" \ + ${ISOARGS} "${ISODIR}" + if isohybrid --version >/dev/null 2>/dev/null ; then + isohybrid "${ISOIMG}" + fi +fi + +# Clean up temporary working directory +# +rm -rf "${WORKDIR}" diff --git a/src/util/geniso b/src/util/geniso deleted file mode 100755 index ff090d4a0..000000000 --- a/src/util/geniso +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/bash -# -# Generate a isolinux ISO boot image - -function help() { - echo "usage: ${0} [OPTIONS] foo.lkrn [bar.lkrn,...]" - echo - echo "where OPTIONS are:" - echo " -h show this help" - echo " -l build legacy image with floppy emulation" - echo " -o FILE save iso image to file" -} - -LEGACY=0 -FIRST="" - -while getopts "hlo:" opt; do - case ${opt} in - h) - help - exit 0 - ;; - l) - LEGACY=1 - ;; - o) - OUT="${OPTARG}" - ;; - esac -done - -shift $((OPTIND - 1)) - -if [ -z "${OUT}" ]; then - echo "${0}: no output file given" >&2 - help - exit 1 -fi - -# There should either be mkisofs or the compatible genisoimage program -for command in genisoimage mkisofs; do - if ${command} --version >/dev/null 2>/dev/null; then - mkisofs=(${command}) - break - fi -done - -if [ -z "${mkisofs}" ]; then - echo "${0}: mkisofs or genisoimage not found, please install or set PATH" >&2 - exit 1 -fi - -dir=$(mktemp -d bin/iso.dir.XXXXXX) -cfg=${dir}/isolinux.cfg - -mkisofs+=(-quiet -l -volid "iPXE" -preparer "iPXE build system" - -appid "iPXE ${VERSION} - Open Source Network Boot Firmware" - -publisher "http://ipxe.org/" -c boot.cat) - -# generate the config -cat > ${cfg} <<EOF -# These default options can be changed in the geniso script -SAY iPXE ISO boot image -TIMEOUT 30 -EOF -for f; do - if [ ! -r ${f} ]; then - echo "${f} does not exist, skipping" >&2 - continue - fi - b=$(basename ${f}) - g=${b%.lkrn} - g=${g//[^a-z0-9]} - g=${g:0:8}.krn - case "${FIRST}" in - "") - echo "DEFAULT ${b}" - FIRST=${g} - ;; - esac - echo "LABEL ${b}" - echo " KERNEL ${g}" - cp ${f} ${dir}/${g} -done >> ${cfg} - -case "${LEGACY}" in - 1) - # check for mtools - case "$(mtools -V)" in - Mtools\ version\ 3.9.9*|Mtools\ version\ 3.9.1[0-9]*|[mM]tools\ *\ [4-9].*) - ;; - *) - echo "Mtools version 3.9.9 or later is required" >&2 - exit 1 - ;; - esac - - # generate floppy image - img=${dir}/boot.img - mformat -f 1440 -C -i ${img} :: - - # copy lkrn file to floppy image - for f in ${dir}/*.krn; do - mcopy -m -i ${img} ${f} ::$(basename ${g}) - rm -f ${f} - done - - # copy config file to floppy image - mcopy -i ${img} ${cfg} ::syslinux.cfg - rm -f ${cfg} - - # write syslinux bootloader to floppy image - if ! syslinux ${img}; then - echo "${0}: failed writing syslinux to floppy image ${img}" >&2 - exit 1 - fi - - # generate the iso image - "${mkisofs[@]}" -b boot.img -output ${OUT} ${dir} - ;; - 0) - # copy isolinux bootloader - cp ${ISOLINUX_BIN} ${dir} - - # syslinux 6.x needs a file called ldlinux.c32 - if [ -n "${LDLINUX_C32}" -a -s "${LDLINUX_C32}" ]; then - cp ${LDLINUX_C32} ${dir} - fi - - # generate the iso image - "${mkisofs[@]}" -b isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -output ${OUT} ${dir} - - # isohybrid will be used if available - if isohybrid --version >/dev/null 2>/dev/null; then - isohybrid ${OUT} >/dev/null - fi - ;; -esac - -# clean up temporary dir -rm -fr ${dir} diff --git a/src/util/gensdsk b/src/util/gensdsk deleted file mode 100755 index fe302d587..000000000 --- a/src/util/gensdsk +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# -# Generate a syslinux floppy that loads a iPXE image -# -# gensdsk foo.sdsk foo.lkrn -# -# the floppy image is the first argument -# followed by list of .lkrn images -# - -case $# in -0|1) - echo Usage: $0 foo.sdsk foo.lkrn ... - exit 1 - ;; -esac -case "`mtools -V`" in -Mtools\ version\ 3.9.9*|Mtools\ version\ 3.9.1[0-9]*|[mM]tools\ *\ [4-9].*) - ;; -*) - echo Mtools version 3.9.9 or later is required - exit 1 - ;; -esac -img=$1 -shift -dir=`mktemp -d bin/sdsk.dir.XXXXXX` - -mformat -f 1440 -C -i $img :: -cfg=$dir/syslinux.cfg -cat > $cfg <<EOF - -# These default options can be changed in the gensdsk script -TIMEOUT 30 -EOF -first= -for f -do - if [ ! -r $f ] - then - echo $f does not exist, skipping 1>&2 - continue - fi - # shorten name for 8.3 filesystem - b=$(basename $f) - g=${b%.lkrn} - g=${g//[^a-z0-9]} - g=${g:0:8}.krn - case "$first" in - "") - echo DEFAULT $b - ;; - esac - first=$g - echo LABEL $b - echo "" KERNEL $g - mcopy -m -i $img $f ::$g -done >> $cfg -mcopy -i $img $cfg ::syslinux.cfg -if ! syslinux $img -then - exit 1 -fi - -rm -fr $dir |