From 6b2f82901e5a2bdcc7b97dadd9defbc18e2a2962 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 3 Nov 2021 21:09:03 -0600 Subject: efi: Add a script to build an image for testing on UEFI It is quite complicated to run U-Boot on QEMU since we have four different builds and they must use different versions of qemu and the UEFI binaries. Add a script to help. It requires U-Boot itself to be built. Once that is done you can use this script to build an image for use with qemu and optionally run it. Signed-off-by: Simon Glass --- scripts/build-efi.sh | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100755 scripts/build-efi.sh (limited to 'scripts') diff --git a/scripts/build-efi.sh b/scripts/build-efi.sh new file mode 100755 index 0000000000..bc9aeebbf4 --- /dev/null +++ b/scripts/build-efi.sh @@ -0,0 +1,193 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0+ +# +# Script to build an EFI thing suitable for booting with QEMU, possibly running +# it also. + +# This just an example. It assumes that + +# - you build U-Boot in ${ubdir}/ where is the U-Boot board config +# - /mnt/x is a directory used for mounting +# - you have access to the 'pure UEFI' builds for QEMU +# +# UEFI binaries for QEMU used for testing this script: +# +# OVMF-pure-efi.i386.fd at +# https://drive.google.com/file/d/1jWzOAZfQqMmS2_dAK2G518GhIgj9r2RY/view?usp=sharing + +# OVMF-pure-efi.x64.fd at +# https://drive.google.com/file/d/1c39YI9QtpByGQ4V0UNNQtGqttEzS-eFV/view?usp=sharing + +set -e + +usage() { + echo "Usage: $0 [-a | -p] [other opts]" 1>&2 + echo 1>&2 + echo " -a - Package up the app" 1>&2 + echo " -o - Use old EFI app build (before 32/64 split)" 1>&2 + echo " -p - Package up the payload" 1>&2 + echo " -P - Create a partition table" 1>&2 + echo " -r - Run QEMU with the image" 1>&2 + echo " -s - Run QEMU with serial only (no display)" 1>&2 + echo " -w - Use word version (32-bit)" 1>&2 + exit 1 +} + +# 32- or 64-bit EFI +bitness=64 + +# app or payload ? +type=app + +# create a partition table and put the filesystem in that (otherwise put the +# filesystem in the raw device) +part= + +# run the image with QEMU +run= + +# run QEMU without a display (U-Boot must be set to stdout=serial) +serial= + +# before the 32/64 split of the app +old= + +# Set ubdir to the build directory where you build U-Boot out-of-tree +# We avoid in-tree build because it gets confusing trying different builds +ubdir=/tmp/b/ + +while getopts "aopPrsw" opt; do + case "${opt}" in + a) + type=app + ;; + p) + type=payload + ;; + r) + run=1 + ;; + s) + serial=1 + ;; + w) + bitness=32 + ;; + o) + old=1 + ;; + P) + part=1 + ;; + *) + usage + ;; + esac +done + +run_qemu() { + extra= + if [[ "${bitness}" = "64" ]]; then + qemu=qemu-system-x86_64 + bios=OVMF-pure-efi.x64.fd + else + qemu=qemu-system-i386 + bios=OVMF-pure-efi.i386.fd + fi + if [[ -n "${serial}" ]]; then + extra="-display none -serial mon:stdio" + fi + echo "Running ${qemu}" + # Use 512MB since U-Boot EFI likes to have 256MB to play with + "${qemu}" -bios "${bios}" \ + -m 512 \ + -drive id=disk,file="${IMG}",if=none,format=raw \ + -nic none -device ahci,id=ahci \ + -device ide-hd,drive=disk,bus=ahci.0 ${extra} +} + +setup_files() { + echo "Packaging ${BUILD}" + mkdir -p $TMP + cat >$TMP/startup.nsh </dev/null + sudo mount -o loop "${IMG}" $MNT + copy_files + sudo umount $MNT +} + +# Create a partition table and put the filesystem in the first partition +# then copy in the files +setup_part() { + # Create a gpt partition table with one partition + parted "${IMG}" mklabel gpt 2>/dev/null + + # This doesn't work correctly. It creates: + # Number Start End Size File system Name Flags + # 1 1049kB 24.1MB 23.1MB boot msftdata + # Odd if the same is entered interactively it does set the FS type + parted -s -a optimal -- "${IMG}" mkpart boot fat32 1MiB 23MiB + + # Map this partition to a loop device + kp="$(sudo kpartx -av ${IMG})" + read boot_dev<<<$(grep -o 'loop.*p.' <<< "${kp}") + test "${boot_dev}" + dev="/dev/mapper/${boot_dev}" + + mkfs.vfat "${dev}" >/dev/null + + sudo mount -o loop "${dev}" $MNT + + copy_files + + # Sync here since this makes kpartx more likely to work the first time + sync + sudo umount $MNT + + # For some reason this needs a sleep or it sometimes fails, if it was + # run recently (in the last few seconds) + if ! sudo kpartx -d "${IMG}" > /dev/null; then + sleep .5 + sudo kpartx -d "${IMG}" > /dev/null || \ + echo "Failed to remove ${boot_dev}, use: sudo kpartx -d ${IMG}" + fi +} + +TMP="/tmp/efi${bitness}${type}" +MNT=/mnt/x +BUILD="efi-x86_${type}${bitness}" +IMG=try.img + +if [[ -n "${old}" && "${bitness}" = "32" ]]; then + BUILD="efi-x86_${type}" +fi + +setup_files + +qemu-img create "${IMG}" 24M >/dev/null + +if [[ -n "${part}" ]]; then + setup_part +else + setup_raw +fi + +if [[ -n "${run}" ]]; then + run_qemu +fi -- cgit v1.2.3