Skip to content
This repository has been archived by the owner on Sep 18, 2020. It is now read-only.

build_library: support uefi boot from iso #551

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 47 additions & 25 deletions build_library/grub.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Main GRUB config

# figure out the root
if [ "$grub_platform" = "efi" ]; then
if [ -e "($cmddevice)/isolinux/efi.img" ]; then
set isoboot="1"
fi

# on efi, $cmddevice has the disk grub was invoked from.
set root="$cmddevice"
else
search --fs-uuid @@ESP_FSID@@ --set root --hint "$root"
fi

# Set the prefix back to the correct value after we're done with memdisk
set prefix=($root)/coreos/grub

Expand Down Expand Up @@ -57,23 +69,25 @@ if [ "$net_default_server" != "" ]; then
fi

# Search for the OEM partition, load additional configuration if found.
if [ "$secure_boot" = "0" ]; then
if [ "$secure_boot" = "0" -a -z "$isoboot" ]; then
Copy link
Contributor

@marineam marineam Jun 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this form of and actually work in grub? I know in the past we've switched to a nested if because and didn't work but that was probably using a different syntax.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you confirm that this syntax is properly supported by grub?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-a is already used other places in this config, like line 77 below

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that must work then. Must have been && that isn't valid.

search --no-floppy --set oem --part-label OEM --hint "$root"
if [ -n "$oem" -a -f "($oem)/grub.cfg" ]; then
source "($oem)/grub.cfg"
fi
fi

# Determine if this is a first boot.
search --no-floppy --set first_boot \
--disk-uuid 00000000-0000-0000-0000-000000000001
if [ -n "$first_boot" ]; then
# Note we explicitly request the disk-guid randomization, first_boot only triggers ignition.
set first_boot="coreos.first_boot=1 coreos.randomize_disk_guid=00000000-0000-0000-0000-000000000001"
fi

if [ -n "$oem_id" ]; then
set oem_id="coreos.oem.id=$oem_id"
if [ -z "$isoboot" ]; then
search --no-floppy --set first_boot \
--disk-uuid 00000000-0000-0000-0000-000000000001
if [ -n "$first_boot" ]; then
# Note we explicitly request the disk-guid randomization, first_boot only triggers ignition.
set first_boot="coreos.first_boot=1 coreos.randomize_disk_guid=00000000-0000-0000-0000-000000000001"
fi

if [ -n "$oem_id" ]; then
set oem_id="coreos.oem.id=$oem_id"
fi
fi

# If no specific console has been set by the OEM then select based on
Expand Down Expand Up @@ -107,19 +121,27 @@ fi
# Assemble the options applicable to all the kernels below
set linux_cmdline="rootflags=rw mount.usrflags=ro consoleblank=0 $linux_root $linux_console $first_boot $oem_id $linux_append"

menuentry "CoreOS default" --id=coreos {
gptprio.next -d usr -u usr_uuid
if [ "$usr_uuid" = "7130c94a-213a-4e5a-8e26-6cce9662f132" ]; then
linux$suf /coreos/vmlinuz-a @@MOUNTUSR@@=PARTUUID=$usr_uuid $linux_cmdline
else
linux$suf /coreos/vmlinuz-b @@MOUNTUSR@@=PARTUUID=$usr_uuid $linux_cmdline
fi
}

menuentry "CoreOS USR-A" --id=coreos-a {
linux$suf /coreos/vmlinuz-a @@MOUNTUSR@@=PARTLABEL=USR-A $linux_cmdline
}
if [ -z "$isoboot" ]; then
menuentry "CoreOS default" --id=coreos {
gptprio.next -d usr -u usr_uuid
if [ "$usr_uuid" = "7130c94a-213a-4e5a-8e26-6cce9662f132" ]; then
linux$suf /coreos/vmlinuz-a @@MOUNTUSR@@=PARTUUID=$usr_uuid $linux_cmdline
else
linux$suf /coreos/vmlinuz-b @@MOUNTUSR@@=PARTUUID=$usr_uuid $linux_cmdline
fi
}

menuentry "CoreOS USR-A" --id=coreos-a {
linux$suf /coreos/vmlinuz-a @@MOUNTUSR@@=PARTLABEL=USR-A $linux_cmdline
}

menuentry "CoreOS USR-B" --id=coreos-b {
linux$suf /coreos/vmlinuz-b @@MOUNTUSR@@=PARTLABEL=USR-B $linux_cmdline
}
else
menuentry "CoreOS default" --id=coreos {
linux$suf /coreos/vmlinuz coreos.autologin= $linux_console
initrd$suf /coreos/cpio.gz
}
fi

menuentry "CoreOS USR-B" --id=coreos-b {
linux$suf /coreos/vmlinuz-b @@MOUNTUSR@@=PARTLABEL=USR-B $linux_cmdline
}
14 changes: 7 additions & 7 deletions build_library/grub_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ case "${FLAGS_target}" in
CORE_NAME="core.img"
;;
x86_64-efi)
CORE_MODULES+=( serial linuxefi efi_gop getenv smbios efinet verify http )
CORE_MODULES+=( serial linuxefi efi_gop getenv smbios efinet verify http iso9660 )
CORE_NAME="core.efi"
;;
x86_64-xen)
CORE_NAME="core.elf"
;;
arm64-efi)
CORE_MODULES+=( serial efi_gop getenv smbios efinet verify http )
CORE_MODULES+=( serial linux efi_gop getenv smbios efinet verify http iso9660 )
CORE_NAME="core.efi"
BOARD_GRUB=1
;;
Expand Down Expand Up @@ -134,19 +134,16 @@ for file in "${GRUB_SRC}"/*{.lst,.mod}; do
done

info "Generating ${GRUB_DIR}/load.cfg"
# Include a small initial config in the core image to search for the ESP
# by filesystem ID in case the platform doesn't provide the boot disk.
# The existing $root value is given as a hint so it is searched first.
ESP_FSID=$(sudo grub-probe -t fs_uuid -d "${LOOP_DEV}p1")
# Include a small initial config to set prefix and dump variables.
sudo_clobber "${ESP_DIR}/${GRUB_DIR}/load.cfg" <<EOF
search.fs_uuid ${ESP_FSID} root \$root
set prefix=(memdisk)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other cleanup news, prefix is already set to memdisk at this point (implied by calling mkimage with the memdisk option) so this line isn't really needed any more.

set
EOF

# Generate a memdisk containing the appropriately generated grub.cfg. Doing
# this because we need conflicting default behaviors between verity and
# non-verity images.
ESP_FSID=$(sudo grub-probe -t fs_uuid -d "${LOOP_DEV}p1")
GRUB_TEMP_DIR=$(mktemp -d)
if [[ ! -f "${ESP_DIR}/coreos/grub/grub.cfg.tar" ]]; then
info "Generating grub.cfg memdisk"
Expand All @@ -162,6 +159,9 @@ if [[ ! -f "${ESP_DIR}/coreos/grub/grub.cfg.tar" ]]; then
sed 's/@@MOUNTUSR@@/mount.usr/' > "${GRUB_TEMP_DIR}/grub.cfg"
fi

# fix up ESP UUID for PC boot. EFI boot will be able to provide the disk to grub.
sed --in-place --expression "s/@@ESP_FSID@@/${ESP_FSID}/" "${GRUB_TEMP_DIR}/grub.cfg"

sudo tar cf "${ESP_DIR}/coreos/grub/grub.cfg.tar" \
-C "${GRUB_TEMP_DIR}" "grub.cfg"
fi
Expand Down
60 changes: 56 additions & 4 deletions build_library/vm_image_util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -570,16 +570,17 @@ _write_cpio_disk() {
}

_write_iso_disk() {
local base_dir="${VM_TMP_ROOT}/usr"
local base_dir="${VM_TMP_ROOT}"
local iso_target="${VM_TMP_DIR}/rootiso"
local dst_dir=$(_dst_dir)
local vmlinuz_name="$(_dst_name ".vmlinuz")"
local efi_img="isolinux/efi.img"

mkdir "${iso_target}"
pushd "${iso_target}" >/dev/null
mkdir isolinux syslinux coreos
_write_cpio_common "$1" "${iso_target}/coreos/cpio.gz"
cp "${base_dir}"/boot/vmlinuz "${iso_target}/coreos/vmlinuz"
cp "${base_dir}/boot/coreos/vmlinuz-a" "${iso_target}/coreos/vmlinuz"
cp -R /usr/share/syslinux/* isolinux/
cat<<EOF > isolinux/isolinux.cfg
INCLUDE /syslinux/syslinux.cfg
Expand All @@ -594,8 +595,59 @@ label coreos
kernel /coreos/vmlinuz
append initrd=/coreos/cpio.gz coreos.autologin
EOF
mkisofs -v -l -r -J -o $2 -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table .
isohybrid $2


# this weird dance is here because isolinux and isohybrid work for amd64,
# but not arm64. also, a bare FAT partition works for amd64 in QEMU/OVMF,
# but not for arm64 in QEMU/ArmVirtPkg. however, a full GPT image with an
# ESP inside *does* work for QEMU/ArmVirtPkg.
case $BOARD in
amd64-usr)
mformat -i "${efi_img}" -C -v COREOS -f 2880

mmd -i "${efi_img}" EFI
mmd -i "${efi_img}" EFI/BOOT

mcopy -i "${efi_img}" -o "${base_dir}"/boot/EFI/boot/* "::EFI/BOOT/"

mkisofs -v -l -r -J -o $2 \
-eltorito-boot isolinux/isolinux.bin \
-eltorito-catalog isolinux/boot.cat \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-eltorito-alt-boot \
-eltorito-platform efi \
-eltorito-boot "${efi_img}" \
-no-emul-boot \
.

isohybrid --uefi $2
;;
arm64-usr)
dd if=/dev/zero of="${efi_img}" bs=1MiB count=3
sgdisk --zap-all "${efi_img}"
sgdisk --largest-new=1 "${efi_img}"
sgdisk --typecode=1:EF00 "${efi_img}"
sgdisk --change-name=1:COREOS "${efi_img}"
sgdisk --verify "${efi_img}"

mformat -i "${efi_img}"@@1M -v COREOS -f 2880

mmd -i "${efi_img}"@@1M EFI
mmd -i "${efi_img}"@@1M EFI/BOOT

mcopy -i "${efi_img}"@@1M -o "${base_dir}"/boot/EFI/boot/* "::EFI/BOOT/"

mkisofs -v -l -r -J -o $2 \
-eltorito-platform efi \
-eltorito-boot "${efi_img}" \
-boot-info-table \
-no-emul-boot \
.
;;
esac

popd >/dev/null
}

Expand Down