Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply patches from Fedora's grub2 package #15

Merged
merged 3 commits into from
Jan 23, 2025
Merged
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
109 changes: 109 additions & 0 deletions 0004-Rework-linux-command.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matthew Garrett <[email protected]>
Date: Sun, 9 Aug 2015 16:12:39 -0700
Subject: [PATCH] Rework linux command

We want a single buffer that contains the entire kernel image in order to
perform a TPM measurement. Allocate one and copy the entire kernel into it
before pulling out the individual blocks later on.

Signed-off-by: Matthew Garrett <[email protected]>
---
grub-core/loader/i386/linux.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 977757f2cc9..10f967f2563 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -661,13 +661,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
{
grub_file_t file = 0;
struct linux_i386_kernel_header lh;
+ grub_uint8_t *linux_params_ptr;
grub_uint8_t setup_sects;
- grub_size_t real_size, prot_size, prot_file_size;
+ grub_size_t real_size, prot_size, prot_file_size, kernel_offset;
grub_ssize_t len;
int i;
grub_size_t align, min_align;
int relocatable;
grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR;
+ grub_uint8_t *kernel = NULL;

grub_dl_ref (my_mod);

@@ -681,7 +683,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (! file)
goto fail;

- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+ len = grub_file_size (file);
+ kernel = grub_malloc (len);
+ if (!kernel)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
+ goto fail;
+ }
+
+ if (grub_file_read (file, kernel, len) != len)
{
if (!grub_errno)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -689,6 +699,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}

+ grub_memcpy (&lh, kernel, sizeof (lh));
+ kernel_offset = sizeof (lh);
+
if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
{
grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
@@ -796,13 +809,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
/* We've already read lh so there is no need to read it second time. */
len -= sizeof(lh);

- if ((len > 0) &&
- (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len))
+ linux_params_ptr = (void *)&linux_params;
+ if (len > 0)
{
- if (!grub_errno)
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
- argv[0]);
- goto fail;
+ grub_memcpy (linux_params_ptr + sizeof (lh), kernel + kernel_offset, len);
+ kernel_offset += len;
}

linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
@@ -865,7 +876,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),

/* The other parameters are filled when booting. */

- grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
+ kernel_offset = real_size + GRUB_DISK_SECTOR_SIZE;

grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
(unsigned) real_size, (unsigned) prot_size);
@@ -1019,9 +1030,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
}

len = prot_file_size;
- if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno)
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
- argv[0]);
+ grub_memcpy (prot_mode_mem, kernel + kernel_offset, len);

if (grub_errno == GRUB_ERR_NONE)
{
@@ -1032,6 +1041,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),

fail:

+ grub_free (kernel);
+
if (file)
grub_file_close (file);

99 changes: 99 additions & 0 deletions 0005-Rework-linux16-command.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matthew Garrett <[email protected]>
Date: Sun, 9 Aug 2015 16:20:58 -0700
Subject: [PATCH] Rework linux16 command

We want a single buffer that contains the entire kernel image in order to
perform a TPM measurement. Allocate one and copy the entire kernel int it
before pulling out the individual blocks later on.

Signed-off-by: Matthew Garrett <[email protected]>
---
grub-core/loader/i386/pc/linux.c | 33 +++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
index 4adeee9ae00..600530a742b 100644
--- a/grub-core/loader/i386/pc/linux.c
+++ b/grub-core/loader/i386/pc/linux.c
@@ -124,13 +124,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_file_t file = 0;
struct linux_i386_kernel_header lh;
grub_uint8_t setup_sects;
- grub_size_t real_size;
+ grub_size_t real_size, kernel_offset = 0;
grub_ssize_t len;
int i;
char *grub_linux_prot_chunk;
int grub_linux_is_bzimage;
grub_addr_t grub_linux_prot_target;
grub_err_t err;
+ grub_uint8_t *kernel = NULL;

grub_dl_ref (my_mod);

@@ -144,7 +145,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (! file)
goto fail;

- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+ len = grub_file_size (file);
+ kernel = grub_malloc (len);
+ if (!kernel)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
+ goto fail;
+ }
+
+ if (grub_file_read (file, kernel, len) != len)
{
if (!grub_errno)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -152,6 +161,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}

+ grub_memcpy (&lh, kernel, sizeof (lh));
+ kernel_offset = sizeof (lh);
+
if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
{
grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
@@ -320,13 +332,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_memmove (grub_linux_real_chunk, &lh, sizeof (lh));

len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh);
- if (grub_file_read (file, grub_linux_real_chunk + sizeof (lh), len) != len)
- {
- if (!grub_errno)
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
- argv[0]);
- goto fail;
- }
+ grub_memcpy (grub_linux_real_chunk + sizeof (lh), kernel + kernel_offset,
+ len);
+ kernel_offset += len;

if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE)
|| grub_le_to_cpu16 (lh.version) < 0x0200)
@@ -364,9 +372,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
}

len = grub_linux16_prot_size;
- if (grub_file_read (file, grub_linux_prot_chunk, len) != len && !grub_errno)
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
- argv[0]);
+ grub_memcpy (grub_linux_prot_chunk, kernel + kernel_offset, len);
+ kernel_offset += len;

if (grub_errno == GRUB_ERR_NONE)
{
@@ -376,6 +383,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),

fail:

+ grub_free (kernel);
+
if (file)
grub_file_close (file);

176 changes: 176 additions & 0 deletions 0007-IBM-client-architecture-CAS-reboot-support.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paulo Flabiano Smorigo <[email protected]>
Date: Thu, 20 Sep 2012 18:07:39 -0300
Subject: [PATCH] IBM client architecture (CAS) reboot support

This is an implementation of IBM client architecture (CAS) reboot for GRUB.

There are cases where the POWER firmware must reboot in order to support
specific features requested by a kernel. The kernel calls
ibm,client-architecture-support and it may either return or reboot with
the new feature set. eg:

Calling ibm,client-architecture-support.../
Elapsed time since release of system processors: 70959 mins 50 secs
Welcome to GRUB!

Instead of return to the GRUB menu, it will check if the flag for CAS
reboot is set. If so, grub will automatically boot the last booted
kernel using the same parameters

Signed-off-by: Paulo Flabiano Smorigo <[email protected]>
[[email protected]: commit message rewrap]
Signed-off-by: Robbie Harwood <[email protected]>
---
grub-core/kern/ieee1275/openfw.c | 63 ++++++++++++++++++++++++++++++++++++++++
grub-core/normal/main.c | 19 ++++++++++++
grub-core/script/execute.c | 7 +++++
include/grub/ieee1275/ieee1275.h | 2 ++
4 files changed, 91 insertions(+)

diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
index 11b2beb2ff2..e2ecc65d2d8 100644
--- a/grub-core/kern/ieee1275/openfw.c
+++ b/grub-core/kern/ieee1275/openfw.c
@@ -591,3 +591,66 @@ grub_ieee1275_get_boot_dev (void)

return bootpath;
}
+
+/* Check if it's a CAS reboot. If so, set the script to be executed. */
+int
+grub_ieee1275_cas_reboot (char *script)
+{
+ grub_uint32_t ibm_ca_support_reboot;
+ grub_uint32_t ibm_fw_nbr_reboots;
+ char property_value[10];
+ grub_ssize_t actual;
+ grub_ieee1275_ihandle_t options;
+
+ if (grub_ieee1275_finddevice ("/options", &options) < 0)
+ return -1;
+
+ /* Check two properties, one is enough to get cas reboot value */
+ ibm_ca_support_reboot = 0;
+ if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
+ "ibm,client-architecture-support-reboot",
+ &ibm_ca_support_reboot,
+ sizeof (ibm_ca_support_reboot),
+ &actual) >= 0)
+ grub_dprintf("ieee1275", "ibm,client-architecture-support-reboot: %u\n",
+ ibm_ca_support_reboot);
+
+ ibm_fw_nbr_reboots = 0;
+ if (grub_ieee1275_get_property (options, "ibm,fw-nbr-reboots",
+ property_value, sizeof (property_value),
+ &actual) >= 0)
+ {
+ property_value[sizeof (property_value) - 1] = 0;
+ ibm_fw_nbr_reboots = (grub_uint8_t) grub_strtoul (property_value, 0, 10);
+ grub_dprintf("ieee1275", "ibm,fw-nbr-reboots: %u\n", ibm_fw_nbr_reboots);
+ }
+
+ if (ibm_ca_support_reboot || ibm_fw_nbr_reboots)
+ {
+ if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual))
+ {
+ if (actual > 1024)
+ script = grub_realloc (script, actual + 1);
+ grub_ieee1275_get_property (options, "boot-last-label", script, actual,
+ &actual);
+ return 0;
+ }
+ }
+
+ grub_ieee1275_set_boot_last_label ("");
+
+ return -1;
+}
+
+int grub_ieee1275_set_boot_last_label (const char *text)
+{
+ grub_ieee1275_ihandle_t options;
+ grub_ssize_t actual;
+
+ grub_dprintf("ieee1275", "set boot_last_label (size: %u)\n", grub_strlen(text));
+ if (! grub_ieee1275_finddevice ("/options", &options) &&
+ options != (grub_ieee1275_ihandle_t) -1)
+ grub_ieee1275_set_property (options, "boot-last-label", text,
+ grub_strlen (text), &actual);
+ return 0;
+}
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index bd44310005d..d3f53d93d87 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -34,6 +34,9 @@
#include <grub/charset.h>
#include <grub/script_sh.h>
#include <grub/bufio.h>
+#ifdef GRUB_MACHINE_IEEE1275
+#include <grub/ieee1275/ieee1275.h>
+#endif

GRUB_MOD_LICENSE ("GPLv3+");

@@ -276,6 +279,22 @@ grub_normal_execute (const char *config, int nested, int batch)
{
menu = read_config_file (config);

+#ifdef GRUB_MACHINE_IEEE1275
+ int boot;
+ boot = 0;
+ char *script;
+ script = grub_malloc (1024);
+ if (! grub_ieee1275_cas_reboot (script))
+ {
+ char *dummy[1] = { NULL };
+ if (! grub_script_execute_sourcecode (script))
+ boot = 1;
+ }
+ grub_free (script);
+ if (boot)
+ grub_command_execute ("boot", 0, 0);
+#endif
+
/* Ignore any error. */
grub_errno = GRUB_ERR_NONE;
}
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index 14ff09094f0..dab8fd2aeb0 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -28,6 +28,9 @@
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/verify.h>
+#ifdef GRUB_MACHINE_IEEE1275
+#include <grub/ieee1275/ieee1275.h>
+#endif

/* Max digits for a char is 3 (0xFF is 255), similarly for an int it
is sizeof (int) * 3, and one extra for a possible -ve sign. */
@@ -883,6 +886,10 @@ grub_script_execute_sourcecode (const char *source)
grub_err_t ret = 0;
struct grub_script *parsed_script;

+#ifdef GRUB_MACHINE_IEEE1275
+ grub_ieee1275_set_boot_last_label (source);
+#endif
+
while (source)
{
char *line;
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
index dddb385149e..4f6e6aaa098 100644
--- a/include/grub/ieee1275/ieee1275.h
+++ b/include/grub/ieee1275/ieee1275.h
@@ -251,6 +251,8 @@ int EXPORT_FUNC(grub_ieee1275_devalias_next) (struct grub_ieee1275_devalias *ali
void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias);
void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath,
struct grub_ieee1275_devalias *alias);
+int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script);
+int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text);

char *EXPORT_FUNC(grub_ieee1275_get_boot_dev) (void);

Loading