summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2021-11-03 21:09:03 -0600
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2021-11-07 18:36:55 +0100
commit6b2f82901e5a2bdcc7b97dadd9defbc18e2a2962 (patch)
treed35013e9416d5f96fb9bba1158771255d7f25b7a /scripts
parent7fc93cae4903c5332b8ae94e1517f7c79f250a4d (diff)
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 <sjg@chromium.org>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/build-efi.sh193
1 files changed, 193 insertions, 0 deletions
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}/<name> where <name> 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 <<EOF
+fs0:u-boot-${type}.efi
+EOF
+ sudo cp ${ubdir}/${BUILD}/u-boot-${type}.efi $TMP
+
+ # Can copy in other files here:
+ #sudo cp ${ubdir}/$BUILD/image.bin $TMP/chromeos.rom
+ #sudo cp /boot/vmlinuz-5.4.0-77-generic $TMP/vmlinuz
+}
+
+# Copy files into the filesystem
+copy_files() {
+ sudo cp $TMP/* $MNT
+}
+
+# Create a filesystem on a raw device and copy in the files
+setup_raw() {
+ mkfs.vfat "${IMG}" >/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