/
githubmirror
/
ipxe
Обзор
Документация
Войти
/
githubmirror
/
ipxe
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/util/gensrvimg
325 строк
6 KB
Michael Brown
[build] Create util/gensrvimg for building network boot server images
24 фев 2026, 18:44
24 фев 2026, 18:44
9250a90
Код
Авторство
О чём код?
#!/bin/sh # # Generate a network bootable directory image set -e set -u # Print usage message # help() { echo "usage: ${0} [OPTIONS] foo.[k]pxe|foo.efi [bar.[k]pxe|bar.efi,...]" echo echo "where OPTIONS are:" echo " -h show this help" echo " -a ARCH select default CPU architecture [x86_64]" echo " -d DIR install images to directory" echo " -e SHIM specify an EFI shim helper" echo " -o FILE save image archive to file" } # Get hex byte from binary file # get_byte() { local FILENAME local OFFSET FILENAME="${1}" OFFSET="${2}" od -j "${OFFSET}" -N 1 -A n -t x1 -- "${FILENAME}" | tr -d " " } # Get hex word from binary file # get_word() { local FILENAME local OFFSET local LSB local MSB FILENAME="${1}" OFFSET="${2}" LSB=$(get_byte "${FILENAME}" $(( ${OFFSET} + 0 )) ) MSB=$(get_byte "${FILENAME}" $(( ${OFFSET} + 1 )) ) echo "${MSB}${LSB}" } # Get hex dword from binary file # get_dword() { local FILENAME local OFFSET local LSW local MSW FILENAME="${1}" OFFSET="${2}" LSW=$(get_word "${FILENAME}" $(( ${OFFSET} + 0 )) ) MSW=$(get_word "${FILENAME}" $(( ${OFFSET} + 2 )) ) echo "${MSW}${LSW}" } # Get appropriate subdirectory name for CPU architecture from EFI binary # efi_subdir_name() { local FILENAME local MZSIG local PEOFF local PESIG local ARCH local OPTSIG local SECSIZE local SBSUFFIX FILENAME="${1}" MZSIG=$(get_word "${FILENAME}" 0) if [ "${MZSIG}" != "5a4d" ] ; then echo "${FILENAME}: invalid MZ header" >&2 exit 1 fi PEOFF=$(get_byte "${FILENAME}" 0x3c) PESIG=$(get_word "${FILENAME}" 0x${PEOFF}) if [ "${PESIG}" != "4550" ] ; then echo "${FILENAME}: invalid PE header" >&2 exit 1 fi ARCH=$(get_word "${FILENAME}" $(( 0x${PEOFF} + 4 )) ) OPTSIG=$(get_word "${FILENAME}" $(( 0x${PEOFF} + 24 )) ) case "${OPTSIG}" in "010b" ) SECSIZE=$(get_dword "${FILENAME}" $(( 0x${PEOFF} + 156 )) ) ;; "020b" ) SECSIZE=$(get_dword "${FILENAME}" $(( 0x${PEOFF} + 172 )) ) ;; * ) echo "${FILENAME}: unrecognised optional header ${OPTSIG}" >&2 exit 1 ;; esac if [ "${SECSIZE}" != "00000000" ] ; then SBSUFFIX="-sb" else SBSUFFIX="" fi case "${ARCH}" in "014c" ) echo "i386${SBSUFFIX}" ;; "8664" ) echo "x86_64${SBSUFFIX}" ;; "01c2" ) echo "arm32${SBSUFFIX}" ;; "6264" ) echo "loong64${SBSUFFIX}" ;; "aa64" ) echo "arm64${SBSUFFIX}" ;; "5064" ) echo "riscv64${SBSUFFIX}" ;; "5032" ) echo "riscv32${SBSUFFIX}" ;; * ) echo "${FILENAME}: unrecognised EFI architecture ${ARCH}" >&2 exit 1 esac } # Get appropriate subdirectory name for CPU architecture from iPXE NBP # nbp_subdir_name() { local FILENAME local LJMP local SEGMENT local MAGIC local ARCH FILENAME="${1}" LJMP=$(get_byte "${FILENAME}" 0) if [ "${LJMP}" != "ea" ] ; then echo "${FILENAME}: invalid LJMP instruction" >&2 exit 1 fi SEGMENT=$(get_word "${FILENAME}" 3) if [ "${SEGMENT}" != "07c0" ] ; then echo "${FILENAME}: invalid LJMP segment" >&2 exit 1 fi MAGIC=$(get_word "${FILENAME}" 6) if [ "${MAGIC}" != "18ae" ] ; then echo "${FILENAME}: invalid iPXE magic" >&2 exit 1 fi ARCH=$(get_byte "${FILENAME}" 5) case "${ARCH}" in "32" ) echo "i386" ;; "64" ) echo "x86_64" ;; * ) echo "${FILENAME}: unrecognised NBP architecture ${ARCH}" >&2 exit 1 esac } # Get appropriate subdirectory name for CPU architecture # subdir_name() { local FILENAME local BYTE FILENAME="${1}" BYTE=$(get_byte "${FILENAME}" 0) case "${BYTE}" in "4d" ) efi_subdir_name "${FILENAME}" ;; "ea" ) nbp_subdir_name "${FILENAME}" ;; * ) echo "${FILENAME}: unrecognised format" >&2 exit 1 esac } # Parse command-line options # DEFARCH=x86_64 OUTDIR= OUTFILE= SHIMAA64= SHIMX64= while getopts "ha:d:e:o:" OPTION ; do case "${OPTION}" in h) help exit 0 ;; a) DEFARCH="${OPTARG}" ;; d) OUTDIR="${OPTARG}" ;; e) SHIM="${OPTARG}" SHIMARCH=$(subdir_name "${SHIM}") case "${SHIMARCH}" in arm64* ) SHIMAA64="${SHIM}" ;; x86_64* ) SHIMX64="${SHIM}" ;; * ) echo "${SHIM}: unsupported shim architecture" >&2 exit 1 esac ;; o) OUTFILE="${OPTARG}" ;; *) help exit 1 ;; esac done if [ -z "${OUTDIR}" -a -z "${OUTFILE}" ] ; then echo "${0}: no output directory or file given" >&2 help exit 1 fi shift $(( OPTIND - 1 )) if [ $# -eq 0 ] ; then echo "${0}: no input files given" >&2 help exit 1 fi # Create temporary working directory, if applicable # WORKDIR= if [ -z "${OUTDIR}" ] ; then WORKDIR=$(mktemp -d "${OUTFILE}.XXXXXX") OUTDIR="${WORKDIR}/ipxeboot" fi mkdir -p "${OUTDIR}" # Copy files to output directory # for FILENAME ; do SUBDIR=$(subdir_name "${FILENAME}") ARCH="${SUBDIR%-sb}" DESTDIR="${OUTDIR}/${SUBDIR}" BASENAME=$(basename "${FILENAME}") SHIMLINK="${BASENAME%.efi}-shim.efi" mkdir -p "${DESTDIR}" install -m 644 "${FILENAME}" "${DESTDIR}/${BASENAME}" case "${SUBDIR}" in arm64-sb ) if [ -n "${SHIMAA64}" ] ; then install -m 644 "${SHIMAA64}" "${DESTDIR}/shimaa64.efi" ln -sfn "shimaa64.efi" "${DESTDIR}/${SHIMLINK}" fi ;; x86_64-sb ) if [ -n "${SHIMX64}" ] ; then install -m 644 "${SHIMX64}" "${DESTDIR}/shimx64.efi" ln -sfn "shimx64.efi" "${DESTDIR}/${SHIMLINK}" fi ;; esac if [ "${ARCH}" = "${DEFARCH}" ] ; then if [ "${ARCH}" = "${SUBDIR}" ] ; then ln -sfn "${SUBDIR}/${BASENAME}" "${OUTDIR}/${BASENAME}" else ln -sfn "${SUBDIR}" "${OUTDIR}/sb" fi fi done # Create output archive file, if applicable # if [ -n "${OUTFILE}" ] ; then TOPDIR=$(dirname "${OUTDIR}") BASENAME=$(basename "${OUTDIR}") case "${OUTFILE}" in *.tar ) tar cf "${OUTFILE}" -C "${TOPDIR}" "${BASENAME}" ;; *.tar.gz | *.tgz ) tar czf "${OUTFILE}" -C "${TOPDIR}" "${BASENAME}" ;; *.tar.bz2 ) tar cjf "${OUTFILE}" -C "${TOPDIR}" "${BASENAME}" ;; *.tar.xz ) tar cJf "${OUTFILE}" -C "${TOPDIR}" "${BASENAME}" ;; * ) echo "${OUTFILE}: unrecognised archive format" >&2 exit 1 ;; esac fi # Clean up temporary working directory # if [ -n "${WORKDIR}" ] ; then rm -rf "${WORKDIR}" fi