Commit 0c6d2a74 authored by Rocky Automation's avatar Rocky Automation 📺
Browse files

import grub2-2.02-142.el8

parent cd66cd9c
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@linux.ibm.com>
Date: Sun, 15 Mar 2020 12:37:10 -0400
Subject: [PATCH] ibmvtpm: Add support for trusted boot using a vTPM 2.0
Add support for trusted boot using a vTPM 2.0 on the IBM IEEE1275
PowerPC platform. With this patch grub now measures text and binary data
into the TPM's PCRs 8 and 9 in the same way as the x86_64 platform
does.
This patch requires Daniel Axtens's patches for claiming more memory.
For vTPM support to work on PowerVM, system driver levels 1010.30
or 1020.00 are required.
Note: Previous versions of firmware levels with the 2hash-ext-log
API call have a bug that, once this API call is invoked, has the
effect of disabling the vTPM driver under Linux causing an error
message to be displayed in the Linux kernel log. Those users will
have to update their machines to the firmware levels mentioned
above.
Cc: Eric Snowberg <eric.snowberg@oracle.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
grub-core/Makefile.core.def | 7 ++
grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++++++++++
include/grub/ieee1275/ieee1275.h | 3 +
3 files changed, 162 insertions(+)
create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index ef06f8c95a..b11f74e6b2 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1104,6 +1104,13 @@ module = {
enable = powerpc_ieee1275;
};
+module = {
+ name = tpm;
+ common = commands/tpm.c;
+ ieee1275 = commands/ieee1275/ibmvtpm.c;
+ enable = powerpc_ieee1275;
+};
+
module = {
name = terminal;
common = commands/terminal.c;
diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
new file mode 100644
index 0000000000..e68b8448bc
--- /dev/null
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
@@ -0,0 +1,152 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2021 Free Software Foundation, Inc.
+ * Copyright (C) 2021 IBM Corporation
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * IBM vTPM support code.
+ */
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/tpm.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+static grub_ieee1275_ihandle_t tpm_ihandle;
+static grub_uint8_t tpm_version;
+
+#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t)0)
+
+static void
+tpm_get_tpm_version (void)
+{
+ grub_ieee1275_phandle_t vtpm;
+ char buffer[20];
+
+ if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) &&
+ !grub_ieee1275_get_property (vtpm, "compatible", buffer,
+ sizeof (buffer), NULL) &&
+ !grub_strcmp (buffer, "IBM,vtpm20"))
+ tpm_version = 2;
+}
+
+static grub_err_t
+tpm_init (void)
+{
+ static int init_success = 0;
+
+ if (!init_success)
+ {
+ if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0) {
+ tpm_ihandle = IEEE1275_IHANDLE_INVALID;
+ return GRUB_ERR_UNKNOWN_DEVICE;
+ }
+
+ init_success = 1;
+
+ tpm_get_tpm_version ();
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static int
+ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex,
+ grub_uint32_t eventtype,
+ const char *description,
+ grub_size_t description_size,
+ void *buf, grub_size_t size)
+{
+ struct tpm_2hash_ext_log
+ {
+ struct grub_ieee1275_common_hdr common;
+ grub_ieee1275_cell_t method;
+ grub_ieee1275_cell_t ihandle;
+ grub_ieee1275_cell_t size;
+ grub_ieee1275_cell_t buf;
+ grub_ieee1275_cell_t description_size;
+ grub_ieee1275_cell_t description;
+ grub_ieee1275_cell_t eventtype;
+ grub_ieee1275_cell_t pcrindex;
+ grub_ieee1275_cell_t catch_result;
+ grub_ieee1275_cell_t rc;
+ }
+ args;
+
+ INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2);
+ args.method = (grub_ieee1275_cell_t) "2hash-ext-log";
+ args.ihandle = tpm_ihandle;
+ args.pcrindex = pcrindex;
+ args.eventtype = eventtype;
+ args.description = (grub_ieee1275_cell_t) description;
+ args.description_size = description_size;
+ args.buf = (grub_ieee1275_cell_t) buf;
+ args.size = (grub_ieee1275_cell_t) size;
+
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+ return -1;
+
+ /*
+ * catch_result is set if firmware does not support 2hash-ext-log
+ * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure
+ */
+ if ((args.catch_result) || args.rc == GRUB_IEEE1275_CELL_FALSE)
+ return -1;
+
+ return 0;
+}
+
+static grub_err_t
+tpm2_log_event (unsigned char *buf,
+ grub_size_t size, grub_uint8_t pcr,
+ const char *description)
+{
+ static int error_displayed = 0;
+ int err;
+
+ err = ibmvtpm_2hash_ext_log (pcr, EV_IPL,
+ description,
+ grub_strlen(description) + 1,
+ buf, size);
+ if (err && !error_displayed)
+ {
+ error_displayed++;
+ return grub_error (GRUB_ERR_BAD_DEVICE,
+ "2HASH-EXT-LOG failed: Firmware is likely too old.\n");
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
+ const char *description)
+{
+ grub_err_t err = tpm_init();
+
+ /* Absence of a TPM isn't a failure. */
+ if (err != GRUB_ERR_NONE)
+ return GRUB_ERR_NONE;
+
+ grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n",
+ pcr, size, description);
+
+ if (tpm_version == 2)
+ return tpm2_log_event (buf, size, pcr, description);
+
+ return GRUB_ERR_NONE;
+}
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
index 131808d619..87b9f95d34 100644
--- a/include/grub/ieee1275/ieee1275.h
+++ b/include/grub/ieee1275/ieee1275.h
@@ -24,6 +24,9 @@
#include <grub/types.h>
#include <grub/machine/ieee1275.h>
+#define GRUB_IEEE1275_CELL_FALSE ((grub_ieee1275_cell_t) 0)
+#define GRUB_IEEE1275_CELL_TRUE ((grub_ieee1275_cell_t) -1)
+
struct grub_ieee1275_mem_region
{
unsigned int start;
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
Date: Fri, 11 Feb 2022 16:34:23 -0500
Subject: [PATCH] ibmvtpm: Backport ibmvtpm support to grub 2.02
Backport ibmvtpm support to grub 2.02 by making as few changes to the
source as possible and building it into the core.
Since ibmvtpm support is built into grub 2.02 do not print the error
message we would typically print if it was a module and the user had
a choice to not use vTPM support if there was no vTPM by avoiding
to use the module.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
grub-core/Makefile.core.def | 8 +-------
grub-core/commands/ieee1275/ibmvtpm.c | 13 ++++++++++---
include/grub/tpm.h | 2 +-
3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index b11f74e6b2..637d7203e3 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -298,6 +298,7 @@ kernel = {
powerpc_ieee1275 = kern/powerpc/cache.S;
powerpc_ieee1275 = kern/powerpc/dl.c;
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
+ powerpc_ieee1275 = commands/ieee1275/ibmvtpm.c;
sparc64_ieee1275 = kern/sparc64/cache.S;
sparc64_ieee1275 = kern/sparc64/dl.c;
@@ -1104,13 +1105,6 @@ module = {
enable = powerpc_ieee1275;
};
-module = {
- name = tpm;
- common = commands/tpm.c;
- ieee1275 = commands/ieee1275/ibmvtpm.c;
- enable = powerpc_ieee1275;
-};
-
module = {
name = terminal;
common = commands/terminal.c;
diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
index e68b8448bc..728b2cbdcd 100644
--- a/grub-core/commands/ieee1275/ibmvtpm.c
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
@@ -115,7 +115,8 @@ tpm2_log_event (unsigned char *buf,
grub_size_t size, grub_uint8_t pcr,
const char *description)
{
- static int error_displayed = 0;
+ /* Do not print error since vTPM support is built-in */
+ static int error_displayed = 1;
int err;
err = ibmvtpm_2hash_ext_log (pcr, EV_IPL,
@@ -132,8 +133,8 @@ tpm2_log_event (unsigned char *buf,
return GRUB_ERR_NONE;
}
-grub_err_t
-grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
+static grub_err_t
+_grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
const char *description)
{
grub_err_t err = tpm_init();
@@ -150,3 +151,9 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
return GRUB_ERR_NONE;
}
+
+grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size,
+ grub_uint8_t pcr, const char *description)
+{
+ return _grub_tpm_measure(buf, size, pcr, description);
+}
diff --git a/include/grub/tpm.h b/include/grub/tpm.h
index ce52be4ff7..52af2b8448 100644
--- a/include/grub/tpm.h
+++ b/include/grub/tpm.h
@@ -69,7 +69,7 @@ typedef struct {
grub_err_t EXPORT_FUNC(grub_tpm_measure) (unsigned char *buf, grub_size_t size,
grub_uint8_t pcr, const char *kind,
const char *description);
-#if defined (GRUB_MACHINE_EFI)
+#if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_IEEE1275)
grub_err_t grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf,
PassThroughToTPM_OutputParamBlock *outbuf);
grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size,
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 8 Apr 2022 12:35:28 +1000
Subject: [PATCH] powerpc: do CAS in a more compatible way
I wrongly assumed that the most compatible way to perform CAS
negotiation was to only set the minimum number of vectors required
to ask for more memory. It turns out that this messes up booting
if the minimum VP capacity would be less than the default 10% in
vector 4.
Linux configures the minimum capacity to be 1%, so copy it for that
and for vector 3 which we now need to specify as well.
Signed-off-by: Daniel Axtens <dja@axtens.net>
(cherry picked from commit e6f02ad4e75cd995a8ee2954d28949c415b6cbfe)
(cherry picked from commit 9f825ebc319c56ca503741e6dc1a0f27ff36fe2d)
---
grub-core/kern/ieee1275/init.c | 54 ++++++++++++++++++++++++------------------
1 file changed, 31 insertions(+), 23 deletions(-)
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index adf4bd5a88..1414695cc6 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -294,33 +294,37 @@ grub_ieee1275_total_mem (grub_uint64_t *total)
/* Based on linux - arch/powerpc/kernel/prom_init.c */
struct option_vector2 {
- grub_uint8_t byte1;
- grub_uint16_t reserved;
- grub_uint32_t real_base;
- grub_uint32_t real_size;
- grub_uint32_t virt_base;
- grub_uint32_t virt_size;
- grub_uint32_t load_base;
- grub_uint32_t min_rma;
- grub_uint32_t min_load;
- grub_uint8_t min_rma_percent;
- grub_uint8_t max_pft_size;
+ grub_uint8_t byte1;
+ grub_uint16_t reserved;
+ grub_uint32_t real_base;
+ grub_uint32_t real_size;
+ grub_uint32_t virt_base;
+ grub_uint32_t virt_size;
+ grub_uint32_t load_base;
+ grub_uint32_t min_rma;
+ grub_uint32_t min_load;
+ grub_uint8_t min_rma_percent;
+ grub_uint8_t max_pft_size;
} __attribute__((packed));
struct pvr_entry {
- grub_uint32_t mask;
- grub_uint32_t entry;
+ grub_uint32_t mask;
+ grub_uint32_t entry;
};
struct cas_vector {
- struct {
- struct pvr_entry terminal;
- } pvr_list;
- grub_uint8_t num_vecs;
- grub_uint8_t vec1_size;
- grub_uint8_t vec1;
- grub_uint8_t vec2_size;
- struct option_vector2 vec2;
+ struct {
+ struct pvr_entry terminal;
+ } pvr_list;
+ grub_uint8_t num_vecs;
+ grub_uint8_t vec1_size;
+ grub_uint8_t vec1;
+ grub_uint8_t vec2_size;
+ struct option_vector2 vec2;
+ grub_uint8_t vec3_size;
+ grub_uint16_t vec3;
+ grub_uint8_t vec4_size;
+ grub_uint16_t vec4;
} __attribute__((packed));
/* Call ibm,client-architecture-support to try to get more RMA.
@@ -341,13 +345,17 @@ grub_ieee1275_ibm_cas (void)
} args;
struct cas_vector vector = {
.pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
- .num_vecs = 2 - 1,
+ .num_vecs = 4 - 1,
.vec1_size = 0,
.vec1 = 0x80, /* ignore */
.vec2_size = 1 + sizeof(struct option_vector2) - 2,
.vec2 = {
0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48
},
+ .vec3_size = 2 - 1,
+ .vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied
+ .vec4_size = 2 - 1,
+ .vec4 = 0x0001, // set required minimum capacity % to the lowest value
};
INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
@@ -360,7 +368,7 @@ grub_ieee1275_ibm_cas (void)
args.ihandle = root;
args.cas_addr = (grub_ieee1275_cell_t)&vector;
- grub_printf("Calling ibm,client-architecture-support...");
+ grub_printf("Calling ibm,client-architecture-support from grub...");
IEEE1275_CALL_ENTRY_FN (&args);
grub_printf("done\n");
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 24 Mar 2022 14:34:32 +1100
Subject: [PATCH] powerpc: prefix detection: support device names with commas
Frustratingly, the device name itself can contain an embedded comma:
e.g /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b
So my previous approach was wrong: we cannot rely upon the presence
of a comma to say that a partition has been specified!
It turns out for prefixes like (,gpt2)/grub2 we really want to make
up a full (device,partition)/patch prefix, because root discovery code
in 10_linux will reset the root variable and use search to fill it again.
If you have run grub-install, you probably don't have search built in,
and if you don't have prefix containing (device,partition), grub will
construct ($root)$prefix/powerpc-ieee1275/search.mod - but because $root
has just been changed, this will no longer work, and the boot will fail!
Retain the gist of the logic, but instead of looking for a comma, look for
a leading '('. This matches the earlier code better anyway.
There's certainly a better fix to be had. But any time you chose to build
with a bare prefix like '/grub2', you're almost certainly going to build in
search anyway, so this will do.
Signed-off-by: Daniel Axtens <dja@axtens.net>
(cherry picked from commit 80b6eb5e55e6d1a4c9896361e61de31c29e6939d)
(cherry picked from commit f3df9f1c2335df22d020e80583d932e254594f0e)
---
grub-core/kern/main.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
index 40a709117f..abbf8af9e6 100644
--- a/grub-core/kern/main.c
+++ b/grub-core/kern/main.c
@@ -241,14 +241,29 @@ grub_set_prefix_and_root (void)
what sorts of paths represent disks with partition tables and those
without partition tables.
- So we act unless there is a comma in the device, which would indicate
- a partition has already been specified.
+ - Frustratingly, the device name itself can contain an embedded comma:
+ /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b
+ So we cannot even rely upon the presence of a comma to say that a
+ partition has been specified!
- (If we only have a path, the code in normal to discover config files
- will try both without partitions and then with any partitions so we
- will cover both CDs and HDs.)
+ If we only have a path in $prefix, the code in normal to discover
+ config files will try all disks, both without partitions and then with
+ any partitions so we will cover both CDs and HDs.
+
+ However, it doesn't then set the prefix to be something like
+ (discovered partition)/path, and so it is fragile against runtime
+ changes to $root. For example some of the stuff done in 10_linux to
+ reload $root sets root differently and then uses search to find it
+ again. If the search module is not built in, when we change root, grub
+ will look in (new root)/path/powerpc-ieee1275, that won't work, and we
+ will not be able to load the search module and the boot will fail.
+
+ This is particularly likely to hit us in the grub-install
+ (,msdos2)/grub2 case, so we act unless the supplied prefix starts with
+ '(', which would likely indicate a partition has already been
+ specified.
*/
- if (grub_strchr (device, ',') == NULL)
+ if (prefix && prefix[0] != '(')
grub_env_set ("prefix", path);
else
#endif
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Diego Domingos <diegdo@br.ibm.com>
Date: Thu, 24 Mar 2022 13:14:42 -0400
Subject: [PATCH] make ofdisk_retries optional
The feature Retry on Fail added to GRUB can cause a LPM to take
longer if the SAN is slow.
When a LPM to external site occur, the path of the disk can change
and thus the disk search function on grub can take some time since
it is used as a hint. This can cause the Retry on Fail feature to
try to access the disk 20x times (since this is hardcoded number)
and, if the SAN is slow, the boot time can increase a lot.
In some situations not acceptable.
The following patch enables a configuration at user space of the
maximum number of retries we want for this feature.
The variable ofdisk_retries should be set using grub2-editenv
and will be checked by retry function. If the variable is not set,
so the default number of retries will be used instead.
---
include/grub/ieee1275/ofdisk.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h
index 7d2d540930..0074d55eee 100644
--- a/include/grub/ieee1275/ofdisk.h
+++ b/include/grub/ieee1275/ofdisk.h
@@ -25,7 +25,12 @@ extern void grub_ofdisk_fini (void);
#define MAX_RETRIES 20
-#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) unsigned retry_i=0;for(retry_i=0; retry_i < MAX_RETRIES; retry_i++){ \
+#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) \
+ unsigned max_retries = MAX_RETRIES; \
+ if(grub_env_get("ofdisk_retries") != NULL) \
+ max_retries = grub_strtoul(grub_env_get("ofdisk_retries"), 0, 10)+1; \
+ grub_dprintf("ofdisk","MAX_RETRIES set to %u\n",max_retries); \
+ unsigned retry_i=0;for(retry_i=0; retry_i < max_retries; retry_i++){ \
if(!grub_ieee1275_open(device, last_ihandle)) \
break; \
grub_dprintf("ofdisk","Opening disk %s failed. Retrying...\n",device); }
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Thu, 28 Apr 2022 21:53:36 +0100
Subject: [PATCH] loader/efi/chainloader: grub_load_and_start_image doesn't
load and start
grub_load_and_start_image only loads an image - it still requires the
caller to start it. This renames it to grub_load_image.
It's called from 2 places:
- grub_cmd_chainloader when not using the shim protocol.
- grub_secureboot_chainloader_boot if handle_image returns an error.
In this case, the image is loaded and then nothing else happens which
seems strange. I assume the intention is that it falls back to LoadImage
and StartImage if handle_image fails, so I've made it do that.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
(cherry picked from commit b4d70820a65c00561045856b7b8355461a9545f6)
(cherry picked from commit 05b16a6be50b1910609740a66b561276fa490538)
(cherry picked from commit 16486a34f3aa41a94e334e86db1a1e21e9b0a45f)
---
grub-core/loader/efi/chainloader.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 29663f7180..d75d345003 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -835,7 +835,7 @@ grub_secureboot_chainloader_unload (void)
}
static grub_err_t
-grub_load_and_start_image(void *boot_image)
+grub_load_image(void *boot_image)
{
grub_efi_boot_services_t *b;
grub_efi_status_t status;
@@ -877,13 +877,23 @@ grub_load_and_start_image(void *boot_image)
static grub_err_t
grub_secureboot_chainloader_boot (void)
{
+ grub_efi_boot_services_t *b;
int rc;
+
rc = handle_image ((void *)(unsigned long)address, fsize);
if (rc == 0)
{
- grub_load_and_start_image((void *)(unsigned long)address);
+ /* We weren't able to attempt to execute the image, so fall back
+ * to LoadImage / StartImage.
+ */
+ rc = grub_load_image((void *)(unsigned long)address);
+ if (rc == 0)
+ grub_chainloader_boot ();
}
+ b = grub_efi_system_table->boot_services;