Skip to contentSkip to conversation

Add gummiboot boot manager alongside grub-efi

PATCH New Stefan Stanacar 1 participant 5 messages Mar 9, 2014

lore
Share & tools
lore
#0 lore raw

v2 cover Add gummiboot boot manager alongside grub-efi

(I've sent this earlier but didn't add v2 to subject, this is resend only)

Hello,

This series adds recipes for gummiboot and a class allowing it to be used as the boot loader for live/hddimg images.
Without changing EFI_PROVIDER, we have the same behaviour for EFI machines. Using EFI_PROVIDER = "gummiboot" an installed image will use gummiboot instead of grub-efi as it's boot manager.

I've tested this on FRI2, NUC and minnow (live USB boot and install from USB and boot) with EFI_PROVIDER = "gummiboot" and KERNEL_FEATURES_append = " cfg/efi-ext" in local.conf

This is a partial fix for YB#4082.

Changes in V2:
- split the first patch in two
- used ${B} instead of ${S} in gummiboot do_deploy
- change the function names in bootimg/grub-efi instead of using a
prefix

I've tested again the changes on top of master.

Cheers,
Stefan

The following changes since commit abe417e22b1b55c444460f722ca434f9d382ef87:

classes/uboot-config: ignore doc varflag (2014-03-07 15:05:09 +0000)

are available in the git repository at:

git://git.yoctoproject.org/poky-contrib stefans/gummiboot
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=stefans/gummiboot

Stefan Stanacar (4):
recipes-bsp: add gnu-efi recipe
recipes-bsp: Add gummiboot recipe bootimg/grub-efi.bbclass: allow using a different class for EFI images
classes: Add gummiboot class

 meta/classes/boot-directdisk.bbclass               |   7 +-
 meta/classes/bootimg.bbclass                       |   9 +-
 meta/classes/grub-efi.bbclass                      |  12 +--
 meta/classes/gummiboot.bbclass                     | 114 +++++++++++++++++++++
 .../gnu-efi/gnu-efi/parallel-make-archives.patch   |  48 +++++++++
 .../gnu-efi/gnu-efi/parallel-make.patch            |  22 ++++
 meta/recipes-bsp/gnu-efi/gnu-efi_3.0u.bb           |  33 ++++++
 meta/recipes-bsp/gummiboot/gummiboot_git.bb        |  25 +++++
 .../initrdscripts/files/init-install-efi.sh        |  51 ++++++---
 9 files changed, 292 insertions(+), 29 deletions(-)
 create mode 100644 meta/classes/gummiboot.bbclass
 create mode 100644 meta/recipes-bsp/gnu-efi/gnu-efi/parallel-make-archives.patch
 create mode 100644 meta/recipes-bsp/gnu-efi/gnu-efi/parallel-make.patch
 create mode 100644 meta/recipes-bsp/gnu-efi/gnu-efi_3.0u.bb
 create mode 100644 meta/recipes-bsp/gummiboot/gummiboot_git.bb
Signature · 1 line
1.8.5.3
#1 lore raw

PATCH v2 1/4 recipes-bsp: add gnu-efi recipe

gnu-efi is required by gummiboot.
Imported from meta-intel, PR dropped, no new version available.

---
 .../gnu-efi/gnu-efi/parallel-make-archives.patch   | 48 ++++++++++++++++++++++
 .../gnu-efi/gnu-efi/parallel-make.patch            | 22 ++++++++++
 meta/recipes-bsp/gnu-efi/gnu-efi_3.0u.bb           | 33 +++++++++++++++
 3 files changed, 103 insertions(+)
 create mode 100644 meta/recipes-bsp/gnu-efi/gnu-efi/parallel-make-archives.patch
 create mode 100644 meta/recipes-bsp/gnu-efi/gnu-efi/parallel-make.patch
 create mode 100644 meta/recipes-bsp/gnu-efi/gnu-efi_3.0u.bb
meta/recipes-bsp/gnu-efi/gnu-efi/parallel-make-archives.patch new file +48 -0
new file mode 100644
index 0000000..e5b47c1
@@ -0,0 +1,48 @@
+Fix parallel make failure for archives
+
+Upstream-Status: Pending
+
+The lib and gnuefi makefiles were using the lib.a() form which compiles
+and ar's as a pair instead of compiling all and then ar'ing which can
+parallelize better. This was resulting in build failures on larger values
+of -j.
+
+See http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_toc.html#TOC105
+for details.
+
+Signed-off-by: Saul Wold <[email protected]>
+Signed-off-by: Darren Hart <[email protected]>
+---
+---
+ gnuefi/Makefile |    3 ++-
+ lib/Makefile    |    3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+Index: gnu-efi-3.0/lib/Makefile
+===================================================================
+--- gnu-efi-3.0.orig/lib/Makefile
++++ gnu-efi-3.0/lib/Makefile
+@@ -66,7 +66,8 @@ all: libsubdirs libefi.a
+ libsubdirs:
+ 	for sdir in $(SUBDIRS); do mkdir -p $$sdir; done
+ 
+-libefi.a: $(patsubst %,libefi.a(%),$(OBJS))
++libefi.a: $(OBJS)
++	$(AR) rv $@ $(OBJS)
+ 
+ clean:
+ 	rm -f libefi.a *~ $(OBJS) */*.o
+Index: gnu-efi-3.0/gnuefi/Makefile
+===================================================================
+--- gnu-efi-3.0.orig/gnuefi/Makefile
++++ gnu-efi-3.0/gnuefi/Makefile
+@@ -51,7 +51,8 @@ TARGETS	= crt0-efi-$(ARCH).o libgnuefi.a
+ 
+ all:	$(TARGETS)
+ 
+-libgnuefi.a: $(patsubst %,libgnuefi.a(%),$(OBJS))
++libgnuefi.a: $(OBJS)
++	$(AR) rv $@ $(OBJS)
+ 
+ clean:
+ 	rm -f $(TARGETS) *~ *.o $(OBJS)
meta/recipes-bsp/gnu-efi/gnu-efi/parallel-make.patch new file +22 -0
new file mode 100644
index 0000000..27c94e8
@@ -0,0 +1,22 @@
+Fix parallel make failure
+
+Upstream-Status: Submitted [Maintainer directly]
+
+Add a missing dependency which resulted in a race leading to failure
+on larger values of -j.
+
+Signed-off-by: Darren Hart <[email protected]>
+
+Index: gnu-efi-3.0/Makefile
+===================================================================
+--- gnu-efi-3.0.orig/Makefile
++++ gnu-efi-3.0/Makefile
+@@ -42,6 +42,8 @@ include $(SRCDIR)/Make.defaults
+ 
+ SUBDIRS = lib gnuefi inc apps
+ 
++gnuefi: lib
++
+ all:	check_gcc $(SUBDIRS)
+ 
+ $(SUBDIRS):
meta/recipes-bsp/gnu-efi/gnu-efi_3.0u.bb new file +33 -0
new file mode 100644
index 0000000..0dbdba2
@@ -0,0 +1,33 @@
+SUMMARY = "Libraries for producing EFI binaries"
+HOMEPAGE = "http://sourceforge.net/projects/gnu-efi/"
+SECTION = "devel"
+LICENSE = "GPLv2+"
+LIC_FILES_CHKSUM = "file://debian/copyright;md5=5fb358a180f484b285b0d99acdc29666"
+
+SRC_URI = "http://downloads.sourceforge.net/gnu-efi/gnu-efi_3.0u.orig.tar.gz \
+           file://parallel-make.patch \
+           file://parallel-make-archives.patch \
+          "
+SRC_URI[md5sum] = "d15d3c700e79a1e2938544d73edc572d"
+SRC_URI[sha256sum] = "3c0d450d5829204ca05dcb3b2aae772e52c379b7c7e09146759c6315606f934e"
+
+COMPATIBLE_HOST = "(x86_64.*|i.86.*)-linux"
+
+S = "${WORKDIR}/gnu-efi-3.0"
+
+def gnu_efi_arch(d):
+    import re
+    tarch = d.getVar("TARGET_ARCH", True)
+    if re.match("i[3456789]86", tarch):
+        return "ia32"
+    return tarch
+
+EXTRA_OEMAKE = "'ARCH=${@gnu_efi_arch(d)}' 'CC=${CC}' 'AS=${AS}' 'LD=${LD}' 'AR=${AR}' \
+                'RANLIB=${RANLIB}' 'OBJCOPY=${OBJCOPY}' 'PREFIX=${prefix}'\
+                "
+
+do_install() {
+        oe_runmake install INSTALLROOT="${D}"
+}
+
+FILES_${PN} += "${libdir}/*.lds"
Signature · 1 line
1.8.5.3
#3 lore raw

PATCH v2 3/4 bootimg/grub-efi.bbclass: allow using a different class for EFI images

In reply to Stefan Stanacar

Abstract away some names so one can select using EFI_PROVIDER a different class than grub-efi for populating live images, basically allowing the use of a different bootloader than grub-efi.

---
 meta/classes/boot-directdisk.bbclass |  7 ++++---
 meta/classes/bootimg.bbclass         |  9 +++++----
 meta/classes/grub-efi.bbclass        | 12 ++++++------
 3 files changed, 15 insertions(+), 13 deletions(-)
meta/classes/boot-directdisk.bbclass +4 -3
index 42b3415..88e5c52 100644
@@ -32,7 +32,8 @@ BOOTDD_VOLUME_ID   ?= "boot"
 BOOTDD_EXTRA_SPACE ?= "16384"
 
 EFI = "${@base_contains("MACHINE_FEATURES", "efi", "1", "0", d)}"
-EFI_CLASS = "${@base_contains("MACHINE_FEATURES", "efi", "grub-efi", "", d)}"
+EFI_PROVIDER ?= "grub-efi"
+EFI_CLASS = "${@base_contains("MACHINE_FEATURES", "efi", "${EFI_PROVIDER}", "", d)}"
 
 # Include legacy boot if MACHINE_FEATURES includes "pcbios" or if it does not
 # contain "efi". This way legacy is supported by default if neither is
@@ -87,7 +88,7 @@ build_boot_dd() {
 		syslinux_hddimg_populate $HDDDIR
 	fi
 	if [ "${EFI}" = "1" ]; then
-		grubefi_hddimg_populate $HDDDIR
+		efi_hddimg_populate $HDDDIR
 	fi
 
 	if [ "${IS_VMDK}" = "true" ]; then
@@ -154,7 +155,7 @@ python do_bootdirectdisk() {
     if d.getVar("PCBIOS", True) == "1":
         bb.build.exec_func('build_syslinux_cfg', d)
     if d.getVar("EFI", True) == "1":
-        bb.build.exec_func('build_grub_cfg', d)
+        bb.build.exec_func('build_efi_cfg', d)
     bb.build.exec_func('build_boot_dd', d)
 }
 
meta/classes/bootimg.bbclass +5 -4
index c370bd6..b13eef9 100644
@@ -42,7 +42,8 @@ BOOTIMG_VOLUME_ID   ?= "boot"
 BOOTIMG_EXTRA_SPACE ?= "512"
 
 EFI = "${@base_contains("MACHINE_FEATURES", "efi", "1", "0", d)}"
-EFI_CLASS = "${@base_contains("MACHINE_FEATURES", "efi", "grub-efi", "", d)}"
+EFI_PROVIDER ?= "grub-efi"
+EFI_CLASS = "${@base_contains("MACHINE_FEATURES", "efi", "${EFI_PROVIDER}", "", d)}"
 
 # Include legacy boot if MACHINE_FEATURES includes "pcbios" or if it does not
 # contain "efi". This way legacy is supported by default if neither is
@@ -89,7 +90,7 @@ build_iso() {
 		syslinux_iso_populate ${ISODIR}
 	fi
 	if [ "${EFI}" = "1" ]; then
-		grubefi_iso_populate ${ISODIR}
+		efi_iso_populate ${ISODIR}
 		build_fat_img ${EFIIMGDIR} ${ISODIR}/efi.img
 	fi
 
@@ -206,7 +207,7 @@ build_hddimg() {
 			syslinux_hddimg_populate ${HDDDIR}
 		fi
 		if [ "${EFI}" = "1" ]; then
-			grubefi_hddimg_populate ${HDDDIR}
+			efi_hddimg_populate ${HDDDIR}
 		fi
 
 		build_fat_img ${HDDDIR} ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.hddimg
@@ -227,7 +228,7 @@ python do_bootimg() {
     if d.getVar("PCBIOS", True) == "1":
         bb.build.exec_func('build_syslinux_cfg', d)
     if d.getVar("EFI", True) == "1":
-        bb.build.exec_func('build_grub_cfg', d)
+        bb.build.exec_func('build_efi_cfg', d)
     bb.build.exec_func('build_hddimg', d)
     bb.build.exec_func('build_iso', d)
 }
meta/classes/grub-efi.bbclass +6 -6
index 71bd00f..5c80c17 100644
@@ -26,7 +26,7 @@ GRUB_OPTS ?= "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"
 
 EFIDIR = "/EFI/BOOT"
 
-grubefi_populate() {
+efi_populate() {
 	# DEST must be the root of the image so that EFIDIR is not
 	# nested under a top level directory.
 	DEST=$1
@@ -42,9 +42,9 @@ grubefi_populate() {
 	install -m 0644 ${GRUBCFG} ${DEST}${EFIDIR}
 }
 
-grubefi_iso_populate() {
+efi_iso_populate() {
 	iso_dir=$1
-	grubefi_populate $iso_dir
+	efi_populate $iso_dir
 	# Build a EFI directory to create efi.img
 	mkdir -p ${EFIIMGDIR}/${EFIDIR}
 	cp $iso_dir/${EFIDIR}/* ${EFIIMGDIR}${EFIDIR}
@@ -55,11 +55,11 @@ grubefi_iso_populate() {
 	fi
 }
 
-grubefi_hddimg_populate() {
-	grubefi_populate $1
+efi_hddimg_populate() {
+	efi_populate $1
 }
 
-python build_grub_cfg() {
+python build_efi_cfg() {
     import sys
 
     workdir = d.getVar('WORKDIR', True)
Signature · 1 line
1.8.5.3
#2 lore raw

PATCH v2 2/4 recipes-bsp: Add gummiboot recipe

In reply to Stefan Stanacar

gummiboot is a simple UEFI boot manager.

Recipe imported from meta-intel with these changes:
- drop PR and update configure options
- upgraded to latest version

A couple of notes:
- If you wish you can install the gummiboot package on the target and
use 'gummiboot install' to add the payload to the ESP (see gummiboot --help, just make sure the ESP partition has the boot flag on as gummiboot won't accept it otherwise). However the point of this recipe is to be used by bootimg.bbclass and generate images with gummiboot instead of grub-efi.
- You need a kernel which has CONFIG_EFI_STUB=y at least
- The default linux-yocto kernel config does not enable that, easiest way
to enable is to build with KERNEL_FEATURES_append = " cfg/efi-ext" in local.conf

---
 meta/recipes-bsp/gummiboot/gummiboot_git.bb | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 meta/recipes-bsp/gummiboot/gummiboot_git.bb
meta/recipes-bsp/gummiboot/gummiboot_git.bb new file +25 -0
new file mode 100644
index 0000000..5868a23
@@ -0,0 +1,25 @@
+SUMMARY = "Gummiboot is a simple UEFI boot manager which executes configured EFI images."
+HOMEPAGE = "http://freedesktop.org/wiki/Software/gummiboot"
+
+LICENSE = "LGPLv2.1"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=4fbd65380cdd255951079008b364516c"
+
+DEPENDS = "gnu-efi util-linux"
+
+inherit autotools
+inherit deploy
+
+PV = "43+git${SRCPV}"
+SRCREV = "4062c51075ba054d4949c714fe06123f9ad3097d"
+SRC_URI = "git://anongit.freedesktop.org/gummiboot"
+
+S = "${WORKDIR}/git"
+
+EXTRA_OECONF = "--disable-manpages --with-efi-includedir=${STAGING_INCDIR} \
+                --with-efi-ldsdir=${STAGING_LIBDIR} \
+                --with-efi-libdir=${STAGING_LIBDIR}"
+
+do_deploy () {
+        install ${B}/gummiboot*.efi ${DEPLOYDIR}
+}
+addtask deploy before do_build after do_compile
Signature · 1 line
1.8.5.3
#4 lore raw

PATCH v2 4/4 classes: Add gummiboot class

In reply to Stefan Stanacar

Adds a gummiboot class similar to grub-efi class and makes the necessary changes so it can be used for live/hddimg images as well.

One can set EFI_PROVIDER = "gummiboot" in local.conf to use gummiboot instead of grub-efi. Gummiboot requires some kernel options that are not enabled by default, so one has to build with KERNEL_FEATURES_append = " cfg/efi-ext".

The install scripts have been updated too, keeping the old behaviour around,
but accounting for the new boot loader config files (if they exist).
It can be argued that the installer and bootimg are a bit wierd and not necessarily correct, but I wanted to have the exact same behviour with gummiboot.
With the default EFI_PROVIDER = "grub-efi" nothing changes, everthing should be just as before.

I've tested live boot, install and normal boot on:
- FRI2
- genericx86-64 on NUC
with:
EFI_PROVIDER = "gummiboot" KERNEL_FEATURES_append = " cfg/efi-ext"
in local.conf.

---
 meta/classes/gummiboot.bbclass                     | 114 +++++++++++++++++++++
 .../initrdscripts/files/init-install-efi.sh        |  51 ++++++---
 2 files changed, 149 insertions(+), 16 deletions(-)
 create mode 100644 meta/classes/gummiboot.bbclass
meta/classes/gummiboot.bbclass new file +114 -0
new file mode 100644
index 0000000..0214652
@@ -0,0 +1,114 @@
+# Copyright (C) 2014 Intel Corporation
+#
+# Released under the MIT license (see COPYING.MIT)
+
+# gummiboot.bbclass - equivalent of grub-efi.bbclass
+# Set EFI_PROVIDER = "gummiboot" to use gummiboot on your live images instead of grub-efi
+# (images built by bootimage.bbclass or boot-directdisk.bbclass)
+
+do_bootimg[depends] += "gummiboot:do_deploy"
+do_bootdirectdisk[depends] += "gummiboot:do_deploy"
+
+EFIDIR = "/EFI/BOOT"
+
+GUMMIBOOT_CFG ?= "${S}/loader.conf"
+GUMMIBOOT_ENTRIES ?= ""
+GUMMIBOOT_TIMEOUT ?= "10"
+
+efi_populate() {
+        DEST=$1
+
+        EFI_IMAGE="gummibootia32.efi"
+        DEST_EFI_IMAGE="bootia32.efi"
+        if [ "${TARGET_ARCH}" = "x86_64" ]; then
+            EFI_IMAGE="gummibootx64.efi"
+            DEST_EFI_IMAGE="bootx64.efi"
+        fi
+
+        install -d ${DEST}${EFIDIR}
+        # gummiboot requires these paths for configuration files
+        # they are not customizable so no point in new vars
+        install -d ${DEST}/loader
+        install -d ${DEST}/loader/entries
+        install -m 0644 ${DEPLOY_DIR_IMAGE}/${EFI_IMAGE} ${DEST}${EFIDIR}/${DEST_EFI_IMAGE}
+        install -m 0644 ${GUMMIBOOT_CFG} ${DEST}/loader/loader.conf
+        for i in ${GUMMIBOOT_ENTRIES}; do
+            install -m 0644 ${i} ${DEST}/loader/entries
+        done
+}
+
+efi_iso_populate() {
+        iso_dir=$1
+        efi_populate $iso_dir
+        mkdir -p ${EFIIMGDIR}/${EFIDIR}
+        cp $iso_dir/${EFIDIR}/* ${EFIIMGDIR}${EFIDIR}
+        cp $iso_dir/vmlinuz ${EFIIMGDIR}
+        echo "${DEST_EFI_IMAGE}" > ${EFIIMGDIR}/startup.nsh
+        if [ -f "$iso_dir/initrd" ] ; then
+            cp $iso_dir/initrd ${EFIIMGDIR}
+        fi
+}
+
+efi_hddimg_populate() {
+        efi_populate $1
+}
+
+python build_efi_cfg() {
+    s = d.getVar("S", True)
+    labels = d.getVar('LABELS', True)
+    if not labels:
+        bb.debug(1, "LABELS not defined, nothing to do")
+        return
+
+    if labels == []:
+        bb.debug(1, "No labels, nothing to do")
+        return
+
+    cfile = d.getVar('GUMMIBOOT_CFG', True)
+    try:
+         cfgfile = open(cfile, 'w')
+    except OSError:
+        raise bb.build.funcFailed('Unable to open %s' % (cfile))
+
+    cfgfile.write('# Automatically created by OE\n')
+    cfgfile.write('default %s\n' % (labels.split()[0]))
+    timeout = d.getVar('GUMMIBOOT_TIMEOUT', True)
+    if timeout:
+        cfgfile.write('timeout %s\n' % timeout)
+    else:
+        cfgfile.write('timeout 10\n')
+    cfgfile.close()
+
+    for label in labels.split():
+        localdata = d.createCopy()
+
+        overrides = localdata.getVar('OVERRIDES', True)
+        if not overrides:
+            raise bb.build.FuncFailed('OVERRIDES not defined')
+
+        entryfile = "%s/%s.conf" % (s, label)
+        d.appendVar("GUMMIBOOT_ENTRIES", " " + entryfile)
+        try:
+            entrycfg = open(entryfile, "w")
+        except OSError:
+            raise bb.build.funcFailed('Unable to open %s' % (entryfile))
+        localdata.setVar('OVERRIDES', label + ':' + overrides)
+        bb.data.update_data(localdata)
+
+        entrycfg.write('title %s\n' % label)
+        entrycfg.write('linux /vmlinuz\n')
+
+        append = localdata.getVar('APPEND', True)
+        initrd = localdata.getVar('INITRD', True)
+
+        if initrd:
+            entrycfg.write('initrd /initrd\n')
+        lb = label
+        if label == "install":
+            lb = "install-efi"
+        entrycfg.write('options LABEL=%s ' % lb)
+        if append:
+            entrycfg.write('%s' % append)
+        entrycfg.write('\n')
+        entrycfg.close()
+}
meta/recipes-core/initrdscripts/files/init-install-efi.sh +35 -16

64 lines not on this page · raw message

Signature · 1 line
1.8.5.3