EFI-32 ISO erstellen

Aus wiki.archlinux.de
Zur Navigation springen Zur Suche springen

Auf Geräten die nur ein 32-Bit UEFI besitzen, lässt sich das normale Installations ISO nicht starten. Das offizielle ISO kann jedoch modifiziert werden damit es auch auf 32-Bit UEFI Geräten geladen werden kann. Zum Beispiel mit diesem Script:

#!/bin/bash

#
# Description: Remaster Arch Linux ISO with 32-bit EFI
# Dependencies: grub-mkstandalone xorriso
#
# Example: efi32iso ./archlinux-2017.08.01-x86_64.iso
# Creates: ./archlinux-2017.08.01-x86_64-efi32.iso
#

work_dir="/tmp/efi32iso"

cleanup() {
	umount "${efi_image_dir}" 2>/dev/null
	umount "${iso_dir}"
	rm -r "${work_dir}"
	exit ${1}
}

if ((UID != 0)); then
	printf "This script requires root privileges!\n"
	exit 1
fi

if (($# != 1)); then
	printf "Usage: $(basename "${0}") <input_file>\n"
	exit 1
fi

! type -p grub-mkstandalone >/dev/null &&
	printf "grub-mkstandalone not found\n" &&
	exit 1

! type -p xorriso >/dev/null &&
	printf "xorriso not found\n" &&
	exit 1

# check input file, pattern tested with 2017-{06,07,08}
pattern="DOS/MBR boot sector; partition 2 : ID=0xef, \
start-CHS (0x3ff,254,63), end-CHS (0x3ff,254,63), \
startsector 164, 131072 sectors"
if [[ "$(file -b "${1}")" != "${pattern}" ]]; then
	printf "Not a valid iso file!\n"
	exit 1
fi

mkdir "${work_dir}" || exit 1

iso_file="${1}"
out_file="${iso_file/.iso/-efi32.iso}"
grub_config="${work_dir}/grub.cfg"
efi32_loader="${work_dir}/bootia32.efi"
efi_image_dir="${work_dir}/efi_image" # mount point for new efi image
iso_dir="${work_dir}/archiso" # mount point for original iso
new_iso_dir="${work_dir}/newiso" # working directory for new iso

# create grub config
cat << 'EOF' > "${grub_config}"
insmod part_gpt
insmod part_msdos
insmod fat
insmod efi_gop
insmod efi_uga
insmod video_bochs
insmod video_cirrus
insmod font

if loadfont "${prefix}/fonts/unicode.pf2" ; then
  insmod gfxterm
  set gfxmode="1024x768x32;auto"
  terminal_input console
  terminal_output gfxterm
fi

menuentry "Arch Linux archiso x86_64" {
  set gfxpayload=keep
  search --no-floppy --set=root --label ARCH_YYYYMM
  linux /arch/boot/x86_64/vmlinuz archisobasedir=arch archisolabel=ARCH_YYYYMM add_efi_memmap
  initrd /arch/boot/x86_64/archiso.img
}

menuentry "UEFI Shell x86_64 v2" {
  search --no-floppy --set=root --label ARCH_YYYYMM
  chainloader /EFI/shellx64_v2.efi
}

menuentry "UEFI Shell x86_64 v1" {
  search --no-floppy --set=root --label ARCH_YYYYMM
  chainloader /EFI/shellx64_v1.efi
}
EOF

# extract the iso
mkdir "${iso_dir}"
mount -t iso9660 -o loop "${iso_file}" "${iso_dir}" || cleanup 1
cp -a "${iso_dir}" "${new_iso_dir}" || cleanup 1

# get label and write it to the grub config
label="$(awk -F '=' '/archisolabel/ {print $3}' \
	"${new_iso_dir}/loader/entries/archiso-x86_64.conf")"
sed -i "s/ARCH_YYYYMM/${label}/g" "${grub_config}"

# generate 32-bit EFI loader
grub-mkstandalone \
	-d /usr/lib/grub/i386-efi/ \
	-O i386-efi \
	--modules="part_gpt part_msdos" \
	--fonts="unicode" \
	--locales="en@quot" \
	--themes="" \
	-o "${efi32_loader}" \
	"boot/grub/grub.cfg=${grub_config}"

# copy 32-bit EFI loader to new iso
cp "${efi32_loader}" "${new_iso_dir}/EFI/boot/bootia32.efi"

# update EFI image with new loader
mkdir "${efi_image_dir}"
mount -t vfat -o loop "${new_iso_dir}/EFI/archiso/efiboot.img" "${efi_image_dir}" || cleanup 1
cp "${efi32_loader}" "${efi_image_dir}/EFI/boot/" || cleanup 1
umount "${efi_image_dir}" # must be unmounted before calling xorriso

# create new iso
xorriso -as mkisofs \
	-iso-level 3 \
	-full-iso9660-filenames \
	-volid "${label}" \
	-eltorito-boot isolinux/isolinux.bin \
	-eltorito-catalog isolinux/boot.cat \
	-no-emul-boot \
	-boot-load-size 4 \
	-boot-info-table \
	-isohybrid-mbr "${new_iso_dir}/isolinux/isohdpfx.bin" \
	-eltorito-alt-boot \
	-e EFI/archiso/efiboot.img \
	-no-emul-boot \
	-isohybrid-gpt-basdat \
	-output "${out_file}" \
	"${new_iso_dir}"

cleanup 0