From 4c4771d498e643899d768f102c0bc6f49fe3e7be Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Fri, 8 Mar 2024 09:32:28 +0000 Subject: [PATCH 01/26] look for grub.cfg on efi where the app was found Signed-off-by: Qiumiao Zhang --- 0019-Add-fw_path-variable-revised.patch | 81 +++++++++++++++++++ ...ix-when-fallback-searching-for-grub-.patch | 41 ++++++++++ grub.patches | 2 + grub2.spec | 8 +- 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 0019-Add-fw_path-variable-revised.patch create mode 100644 0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch diff --git a/0019-Add-fw_path-variable-revised.patch b/0019-Add-fw_path-variable-revised.patch new file mode 100644 index 0000000..a8491e8 --- /dev/null +++ b/0019-Add-fw_path-variable-revised.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Wed, 19 Sep 2012 21:22:55 -0300 +Subject: [PATCH] Add fw_path variable (revised) + +This patch makes grub look for its config file on efi where the app was +found. It was originally written by Matthew Garrett, and adapted to fix the +"No modules are loaded on grub2 network boot" issue: + +https://bugzilla.redhat.com/show_bug.cgi?id=857936 + +Signed-off-by: Paulo Flabiano Smorigo +Signed-off-by: Robbie Harwood +--- + grub-core/kern/main.c | 13 ++++++------- + grub-core/normal/main.c | 25 ++++++++++++++++++++++++- + 2 files changed, 30 insertions(+), 8 deletions(-) + +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index 73967e2f5b0..d1de9fa6873 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -128,16 +128,15 @@ grub_set_prefix_and_root (void) + + grub_machine_get_bootlocation (&fwdevice, &fwpath); + +- if (fwdevice) ++ if (fwdevice && fwpath) + { +- char *cmdpath; ++ char *fw_path; + +- cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : ""); +- if (cmdpath) ++ fw_path = grub_xasprintf ("(%s)/%s", fwdevice, fwpath); ++ if (fw_path) + { +- grub_env_set ("cmdpath", cmdpath); +- grub_env_export ("cmdpath"); +- grub_free (cmdpath); ++ grub_env_set ("fw_path", fw_path); ++ grub_free (fw_path); + } + } + +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 70614de1565..62571e6dfcc 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -339,7 +339,30 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + /* Guess the config filename. It is necessary to make CONFIG static, + so that it won't get broken by longjmp. */ + char *config; +- const char *prefix; ++ const char *prefix, *fw_path; ++ ++ fw_path = grub_env_get ("fw_path"); ++ if (fw_path) ++ { ++ config = grub_xasprintf ("%s/grub.cfg", fw_path); ++ if (config) ++ { ++ grub_file_t file; ++ ++ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); ++ if (file) ++ { ++ grub_file_close (file); ++ grub_enter_normal_mode (config); ++ } ++ else ++ { ++ /* Ignore all errors. */ ++ grub_errno = 0; ++ } ++ grub_free (config); ++ } ++ } + + prefix = grub_env_get ("prefix"); + if (prefix) diff --git a/0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch b/0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch new file mode 100644 index 0000000..6b1580b --- /dev/null +++ b/0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Fedora Ninjas +Date: Wed, 19 Feb 2014 15:58:43 -0500 +Subject: [PATCH] use fw_path prefix when fallback searching for grub config + +When PXE booting via UEFI firmware, grub was searching for grub.cfg +in the fw_path directory where the grub application was found. If +that didn't exist, a fallback search would look for config file names +based on MAC and IP address. However, the search would look in the +prefix directory which may not be the same fw_path. This patch +changes that behavior to use the fw_path directory for the fallback +search. Only if fw_path is NULL will the prefix directory be searched. + +Signed-off-by: Mark Salter +--- + grub-core/normal/main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 7ca2e5400b1..02577502116 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -347,7 +347,7 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + char *config; + const char *prefix, *fw_path; + +- fw_path = grub_env_get ("fw_path"); ++ prefix = fw_path = grub_env_get ("fw_path"); + if (fw_path) + { + config = grub_xasprintf ("%s/grub.cfg", fw_path); +@@ -370,7 +370,8 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + } + } + +- prefix = grub_env_get ("prefix"); ++ if (! prefix) ++ prefix = grub_env_get ("prefix"); + if (prefix) + { + grub_size_t config_len; diff --git a/grub.patches b/grub.patches index 5b690a9..176b486 100644 --- a/grub.patches +++ b/grub.patches @@ -206,5 +206,7 @@ Patch205: disable-some-unsupported-filesystems.patch Patch206: remove-the-items-of-unsupported-filesystems-in-fs.ls.patch Patch207: backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch Patch208: modify-klist-in-10_linux.in.patch +Patch209: 0019-Add-fw_path-variable-revised.patch +Patch210: 0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch #Patch208: add-TPCM-support-with-ipmi-channel.patch #Patch209: skip-verification-when-not-loading-grub.cfg.patch diff --git a/grub2.spec b/grub2.spec index 0ad5992..788a643 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 2 +Release: 3 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -449,6 +449,12 @@ fi %{_datadir}/man/man* %changelog +* Fri Mar 8 2024 zhangqiumiao - 1:2.12-3 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:look for grub.cfg on efi where the app was found + * Thu Mar 7 2024 zhangqiumiao - 1:2.12-2 - Type:bugfix - CVE:NA -- Gitee From e07518a0fb083b68bc4dbf4ea3b2eb6bcbe7c5f6 Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Mon, 11 Mar 2024 08:45:49 +0000 Subject: [PATCH 02/26] Don't require a password to boot entries generated by grub-mkconfig Signed-off-by: Qiumiao Zhang --- ...n-t-say-GNU-Linux-in-generated-menus.patch | 39 +++ ...password-to-boot-entries-generated-b.patch | 28 ++ ...-before-grub.cfg-on-tftp-config-file.patch | 127 +++++++ ...CLASS-in-10_linux-from-etc-os-releas.patch | 29 ++ 0032-Try-prefix-if-fw_path-doesn-t-work.patch | 222 +++++++++++++ ...fig-construct-titles-that-look-like-.patch | 73 ++++ ...ly-grub2-password-config-tool-985962.patch | 246 ++++++++++++++ grub.patches | 10 +- ...rd-prompts-to-enter-the-current-pass.patch | 313 ++++++++++++++++++ grub2.spec | 8 +- 10 files changed, 1093 insertions(+), 2 deletions(-) create mode 100644 0024-Don-t-say-GNU-Linux-in-generated-menus.patch create mode 100644 0026-Don-t-require-a-password-to-boot-entries-generated-b.patch create mode 100644 0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch create mode 100644 0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch create mode 100644 0032-Try-prefix-if-fw_path-doesn-t-work.patch create mode 100644 0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch create mode 100644 0035-Add-friendly-grub2-password-config-tool-985962.patch create mode 100644 grub2-set-password-prompts-to-enter-the-current-pass.patch diff --git a/0024-Don-t-say-GNU-Linux-in-generated-menus.patch b/0024-Don-t-say-GNU-Linux-in-generated-menus.patch new file mode 100644 index 0000000..c55801f --- /dev/null +++ b/0024-Don-t-say-GNU-Linux-in-generated-menus.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 14 Mar 2011 14:27:42 -0400 +Subject: [PATCH] Don't say "GNU/Linux" in generated menus. + +--- + util/grub.d/10_linux.in | 2 +- + util/grub.d/20_linux_xen.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index ae487a7..7b51a38 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -29,7 +29,7 @@ export TEXTDOMAINDIR="@localedir@" + CLASS="--class gnu-linux --class gnu --class os" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +- OS=GNU/Linux ++ OS="$(sed 's, release .*$,,g' /etc/system-release)" + else + OS="${GRUB_DISTRIBUTOR}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" +diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index 4cc03a7..87ecb1e 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -37,7 +37,7 @@ fi + CLASS="--class gnu-linux --class gnu --class os --class xen" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +- OS=GNU/Linux ++ OS="$(sed 's, release .*$,,g' /etc/system-release)" + os=linux + else + OS="${GRUB_DISTRIBUTOR}" +-- +2.33.0 + diff --git a/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch b/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch new file mode 100644 index 0000000..ac9475e --- /dev/null +++ b/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 11 Feb 2014 11:14:50 -0500 +Subject: [PATCH] Don't require a password to boot entries generated by + grub-mkconfig. + +When we set a password, we just want that to mean you can't /edit/ an entry. + +Resolves: rhbz#1030176 + +Signed-off-by: Peter Jones +--- + util/grub.d/10_linux.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 4a499c53a61..cf8d1186981 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -26,7 +26,7 @@ datarootdir="@datarootdir@" + export TEXTDOMAIN=@PACKAGE@ + export TEXTDOMAINDIR="@localedir@" + +-CLASS="--class gnu-linux --class gnu --class os" ++CLASS="--class gnu-linux --class gnu --class os --unrestricted" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then + OS="$(sed 's, release .*$,,g' /etc/system-release)" diff --git a/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch b/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch new file mode 100644 index 0000000..ab49bb1 --- /dev/null +++ b/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch @@ -0,0 +1,127 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 8 Jul 2019 17:33:22 +0200 +Subject: [PATCH] Try mac/guid/etc before grub.cfg on tftp config files. + +Signed-off-by: Peter Jones +--- + grub-core/normal/main.c | 97 ++++++++++++++++++++++++++----------------------- + 1 file changed, 51 insertions(+), 46 deletions(-) + +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 02577502116..880d0ebd454 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -345,61 +345,66 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + /* Guess the config filename. It is necessary to make CONFIG static, + so that it won't get broken by longjmp. */ + char *config; +- const char *prefix, *fw_path; +- +- prefix = fw_path = grub_env_get ("fw_path"); +- if (fw_path) +- { +- config = grub_xasprintf ("%s/grub.cfg", fw_path); +- if (config) +- { +- grub_file_t file; +- +- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); +- if (file) +- { +- grub_file_close (file); +- grub_enter_normal_mode (config); +- } +- else +- { +- /* Ignore all errors. */ +- grub_errno = 0; +- } +- grub_free (config); +- } +- } ++ const char *prefix; ++ const char *net_search_cfg; ++ int disable_net_search = 0; + ++ prefix = grub_env_get ("fw_path"); + if (! prefix) + prefix = grub_env_get ("prefix"); ++ ++ net_search_cfg = grub_env_get ("feature_net_search_cfg"); ++ if (net_search_cfg && net_search_cfg[0] == 'n') ++ disable_net_search = 1; ++ + if (prefix) + { +- grub_size_t config_len; +- int disable_net_search = 0; +- const char *net_search_cfg; +- +- config_len = grub_strlen (prefix) + +- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); +- config = grub_malloc (config_len); +- +- if (!config) +- goto quit; +- +- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); +- +- net_search_cfg = grub_env_get ("feature_net_search_cfg"); +- if (net_search_cfg && net_search_cfg[0] == 'n') +- disable_net_search = 1; +- + if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && + !disable_net_search) +- grub_net_search_config_file (config); ++ { ++ grub_size_t config_len; ++ config_len = grub_strlen (prefix) + ++ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); ++ config = grub_malloc (config_len); + +- grub_enter_normal_mode (config); +- grub_free (config); +- } ++ if (! config) ++ goto quit; ++ ++ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); ++ ++ grub_net_search_configfile (config); ++ ++ grub_enter_normal_mode (config); ++ grub_free (config); ++ config = NULL; ++ } ++ ++ if (!config) ++ { ++ config = grub_xasprintf ("%s/grub.cfg", prefix); ++ if (config) ++ { ++ grub_file_t file; ++ ++ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); ++ if (file) ++ { ++ grub_file_close (file); ++ grub_enter_normal_mode (config); ++ } ++ else ++ { ++ /* Ignore all errors. */ ++ grub_errno = 0; ++ } ++ grub_free (config); ++ } ++ } ++ } + else +- grub_enter_normal_mode (0); ++ { ++ grub_enter_normal_mode (0); ++ } + } + else + grub_enter_normal_mode (argv[0]); diff --git a/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch b/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch new file mode 100644 index 0000000..245faf7 --- /dev/null +++ b/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 4 Sep 2014 14:23:23 -0400 +Subject: [PATCH] Generate OS and CLASS in 10_linux from /etc/os-release + +This makes us use pretty names in the titles we generate in +grub2-mkconfig when GRUB_DISTRIBUTOR isn't set. + +Resolves: rhbz#996794 + +Signed-off-by: Peter Jones +--- + util/grub.d/10_linux.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index cf8d1186981..5f6d3c8d52d 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -29,7 +29,8 @@ export TEXTDOMAINDIR="@localedir@" + CLASS="--class gnu-linux --class gnu --class os --unrestricted" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +- OS="$(sed 's, release .*$,,g' /etc/system-release)" ++ OS="$(eval $(grep PRETTY_NAME /etc/os-release) ; echo ${PRETTY_NAME})" ++ CLASS="--class $(eval $(grep '^ID_LIKE=\|^ID=' /etc/os-release) ; [ -n "${ID_LIKE}" ] && echo ${ID_LIKE} || echo ${ID}) ${CLASS}" + else + OS="${GRUB_DISTRIBUTOR}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" diff --git a/0032-Try-prefix-if-fw_path-doesn-t-work.patch b/0032-Try-prefix-if-fw_path-doesn-t-work.patch new file mode 100644 index 0000000..54a876b --- /dev/null +++ b/0032-Try-prefix-if-fw_path-doesn-t-work.patch @@ -0,0 +1,222 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 9 Jul 2019 10:35:16 +0200 +Subject: [PATCH] Try $prefix if $fw_path doesn't work. + +Related: rhbz#1148652 + +Signed-off-by: Peter Jones +--- + grub-core/kern/ieee1275/init.c | 28 +++++---- + grub-core/net/net.c | 2 +- + grub-core/normal/main.c | 134 ++++++++++++++++++++--------------------- + 3 files changed, 82 insertions(+), 82 deletions(-) + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index e71d1584164..0cd2a627231 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -127,23 +127,25 @@ grub_machine_get_bootlocation (char **device, char **path) + grub_free (canon); + } + else +- *device = grub_ieee1275_encode_devname (bootpath); +- grub_free (type); +- +- filename = grub_ieee1275_get_filename (bootpath); +- if (filename) + { +- char *lastslash = grub_strrchr (filename, '\\'); +- +- /* Truncate at last directory. */ +- if (lastslash) ++ filename = grub_ieee1275_get_filename (bootpath); ++ if (filename) + { +- *lastslash = '\0'; +- grub_translate_ieee1275_path (filename); ++ char *lastslash = grub_strrchr (filename, '\\'); + +- *path = filename; +- } ++ /* Truncate at last directory. */ ++ if (lastslash) ++ { ++ *lastslash = '\0'; ++ grub_translate_ieee1275_path (filename); ++ ++ *path = filename; ++ } ++ } ++ *device = grub_ieee1275_encode_devname (bootpath); + } ++ ++ grub_free (type); + grub_free (bootpath); + } + +diff --git a/grub-core/net/net.c b/grub-core/net/net.c +index 4d3eb5c1a52..0ef148f4adc 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -1869,7 +1869,7 @@ grub_net_search_config_file (char *config) + /* Remove the remaining minus sign at the end. */ + config[config_len] = '\0'; + +- return GRUB_ERR_NONE; ++ return GRUB_ERR_FILE_NOT_FOUND; + } + + static struct grub_preboot *fini_hnd; +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 880d0ebd454..d5df4f815b0 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -335,81 +335,79 @@ grub_enter_normal_mode (const char *config) + grub_boot_time ("Exiting normal mode"); + } + ++static grub_err_t ++grub_try_normal (const char *variable) ++{ ++ char *config; ++ const char *prefix; ++ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; ++ const char *net_search_cfg; ++ int disable_net_search = 0; ++ ++ prefix = grub_env_get (variable); ++ if (!prefix) ++ return GRUB_ERR_FILE_NOT_FOUND; ++ ++ net_search_cfg = grub_env_get ("feature_net_search_cfg"); ++ if (net_search_cfg && net_search_cfg[0] == 'n') ++ disable_net_search = 1; ++ ++ if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && ++ !disable_net_search) ++ { ++ grub_size_t config_len; ++ config_len = grub_strlen (prefix) + ++ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); ++ config = grub_malloc (config_len); ++ ++ if (! config) ++ return GRUB_ERR_FILE_NOT_FOUND; ++ ++ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); ++ err = grub_net_search_config_file (config); ++ } ++ ++ if (err != GRUB_ERR_NONE) ++ { ++ config = grub_xasprintf ("%s/grub.cfg", prefix); ++ if (config) ++ { ++ grub_file_t file; ++ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); ++ if (file) ++ { ++ grub_file_close (file); ++ err = GRUB_ERR_NONE; ++ } ++ } ++ } ++ ++ if (err == GRUB_ERR_NONE) ++ grub_enter_normal_mode (config); ++ ++ grub_errno = 0; ++ grub_free (config); ++ return err; ++} ++ + /* Enter normal mode from rescue mode. */ + static grub_err_t + grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- if (argc == 0) +- { +- /* Guess the config filename. It is necessary to make CONFIG static, +- so that it won't get broken by longjmp. */ +- char *config; +- const char *prefix; +- const char *net_search_cfg; +- int disable_net_search = 0; +- +- prefix = grub_env_get ("fw_path"); +- if (! prefix) +- prefix = grub_env_get ("prefix"); +- +- net_search_cfg = grub_env_get ("feature_net_search_cfg"); +- if (net_search_cfg && net_search_cfg[0] == 'n') +- disable_net_search = 1; +- +- if (prefix) +- { +- if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && +- !disable_net_search) +- { +- grub_size_t config_len; +- config_len = grub_strlen (prefix) + +- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); +- config = grub_malloc (config_len); +- +- if (! config) +- goto quit; +- +- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); +- +- grub_net_search_configfile (config); +- +- grub_enter_normal_mode (config); +- grub_free (config); +- config = NULL; +- } +- +- if (!config) +- { +- config = grub_xasprintf ("%s/grub.cfg", prefix); +- if (config) +- { +- grub_file_t file; +- +- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); +- if (file) +- { +- grub_file_close (file); +- grub_enter_normal_mode (config); +- } +- else +- { +- /* Ignore all errors. */ +- grub_errno = 0; +- } +- grub_free (config); +- } +- } +- } +- else +- { +- grub_enter_normal_mode (0); +- } +- } +- else ++ if (argc) + grub_enter_normal_mode (argv[0]); ++ else ++ { ++ /* Guess the config filename. */ ++ grub_err_t err; ++ err = grub_try_normal ("fw_path"); ++ if (err == GRUB_ERR_FILE_NOT_FOUND) ++ err = grub_try_normal ("prefix"); ++ if (err == GRUB_ERR_FILE_NOT_FOUND) ++ grub_enter_normal_mode (0); ++ } + +-quit: + return 0; + } + diff --git a/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch b/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch new file mode 100644 index 0000000..9a5235d --- /dev/null +++ b/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 28 Apr 2015 11:15:03 -0400 +Subject: [PATCH] Make grub2-mkconfig construct titles that look like the ones + we want elsewhere. + +Resolves: rhbz#1215839 + +Signed-off-by: Peter Jones + +--- + util/grub.d/10_linux.in | 34 +++++++++++++++++++++++++++------- + 1 file changed, 27 insertions(+), 7 deletions(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 6e5e3d7..1a4c846 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -88,6 +88,32 @@ case x"$GRUB_FS" in + ;; + esac + ++mktitle () ++{ ++ local title_type ++ local version ++ local OS_NAME ++ local OS_VERS ++ ++ title_type=$1 && shift ++ version=$1 && shift ++ ++ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})" ++ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})" ++ ++ case $title_type in ++ recovery) ++ title=$(printf '%s (%s) %s (recovery mode)' \ ++ "${OS_NAME}" "${version}" "${OS_VERS}") ++ ;; ++ *) ++ title=$(printf '%s (%s) %s' \ ++ "${OS_NAME}" "${version}" "${OS_VERS}") ++ ;; ++ esac ++ echo -n ${title} ++} ++ + if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then + LINUX_ROOT_DEVICE="" + fi +@@ -126,17 +152,11 @@ linux_entry () + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi + if [ x$type != xsimple ] ; then +- case $type in +- recovery) +- title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;; +- *) +- title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;; +- esac ++ title=$(mktitle "$type" "$version") + if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then + replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" + quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" + title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" +- grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")" + fi + echo "menuentry '$(echo "$title" | grub_quote)' $(print_hotkey) ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" + hotkey=$(incr_hotkey) +-- +2.33.0 + diff --git a/0035-Add-friendly-grub2-password-config-tool-985962.patch b/0035-Add-friendly-grub2-password-config-tool-985962.patch new file mode 100644 index 0000000..9d1c858 --- /dev/null +++ b/0035-Add-friendly-grub2-password-config-tool-985962.patch @@ -0,0 +1,246 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Robert Marshall +Date: Thu, 25 Jun 2015 11:13:11 -0400 +Subject: [PATCH] Add friendly grub2 password config tool (#985962) + +Provided a tool for users to reset the grub2 root user password +without having to alter the grub.cfg. The hashed password now +lives in a root-only-readable configuration file. + +Resolves: rhbz#985962 + +Signed-off-by: Robert Marshall +[pjones: fix the efidir in grub-setpassword and rename tool] +Signed-off-by: Peter Jones +[luto: fix grub-setpassword -o's output path] +Andy Lutomirski +--- + Makefile.util.def | 13 ++++ + configure.ac | 1 + + docs/man/grub-set-password.h2m | 2 + + util/grub-mkconfig.in | 2 + + util/grub-set-password.in | 128 +++++++++++++++++++++++++++++++++ + util/grub.d/01_users.in | 11 +++ + 6 files changed, 157 insertions(+) + create mode 100644 docs/man/grub-set-password.h2m + create mode 100644 util/grub-set-password.in + create mode 100644 util/grub.d/01_users.in + +diff --git a/Makefile.util.def b/Makefile.util.def +index b384e16..b916c19 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -465,6 +465,12 @@ script = { + installdir = grubconf; + }; + ++script = { ++ name = '01_users'; ++ common = util/grub.d/01_users.in; ++ installdir = grubconf; ++}; ++ + script = { + name = '05_crypttab'; + common = util/grub.d/05_crypttab.in; +@@ -763,6 +769,13 @@ script = { + installdir = sbin; + }; + ++script = { ++ name = grub-set-password; ++ common = util/grub-set-password.in; ++ mansection = 8; ++ installdir = sbin; ++}; ++ + script = { + name = grub-zipl-setup; + installdir = sbin; +diff --git a/configure.ac b/configure.ac +index 942db8f..8878e91 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -78,6 +78,7 @@ grub_TRANSFORM([grub-mkrescue]) + grub_TRANSFORM([grub-probe]) + grub_TRANSFORM([grub-protect]) + grub_TRANSFORM([grub-reboot]) ++grub_TRANSFORM([grub-set-password]) + grub_TRANSFORM([grub-script-check]) + grub_TRANSFORM([grub-set-default]) + grub_TRANSFORM([grub-sparc64-setup]) +diff --git a/docs/man/grub-set-password.h2m b/docs/man/grub-set-password.h2m +new file mode 100644 +index 0000000..10ee82f +--- /dev/null ++++ b/docs/man/grub-set-password.h2m +@@ -0,0 +1,2 @@ ++[NAME] ++grub-set-password \- generate the user.cfg file containing the hashed grub bootloader password +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index 4b3510a..f8ec65b 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -332,6 +332,8 @@ for i in "${grub_mkconfig_dir}"/* ; do + *~) ;; + # emacsen autosave files. FIXME: support other editors + */\#*\#) ;; ++ # rpm config files of yore. ++ *.rpmsave|*.rpmnew|*.rpmorig) ;; + *) + if grub_file_is_not_garbage "$i" && test -x "$i" ; then + echo +diff --git a/util/grub-set-password.in b/util/grub-set-password.in +new file mode 100644 +index 0000000..c0b5ebb +--- /dev/null ++++ b/util/grub-set-password.in +@@ -0,0 +1,128 @@ ++#!/bin/sh -e ++ ++EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') ++if [ -d /sys/firmware/efi/efivars/ ]; then ++ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` ++else ++ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` ++fi ++ ++PACKAGE_VERSION="@PACKAGE_VERSION@" ++PACKAGE_NAME="@PACKAGE_NAME@" ++self=`basename $0` ++bindir="@bindir@" ++grub_mkpasswd="${bindir}/@grub_mkpasswd_pbkdf2@" ++ ++# Usage: usage ++# Print the usage. ++usage () { ++ cat < put user.cfg in a user-selected directory ++ ++Report bugs at https://bugzilla.redhat.com. ++EOF ++} ++ ++argument () { ++ opt=$1 ++ shift ++ ++ if test $# -eq 0; then ++ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 ++ exit 1 ++ fi ++ echo $1 ++} ++ ++# Ensure that it's the root user running this script ++if [ "${EUID}" -ne 0 ]; then ++ echo "The grub bootloader password may only be set by root." ++ usage ++ exit 2 ++fi ++ ++# Check the arguments. ++while test $# -gt 0 ++do ++ option=$1 ++ shift ++ ++ case "$option" in ++ -h | --help) ++ usage ++ exit 0 ;; ++ -v | --version) ++ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" ++ exit 0 ;; ++ -o | --output) ++ OUTPUT_PATH=`argument $option "$@"`; shift ;; ++ --output=*) ++ OUTPUT_PATH=`echo "$option" | sed 's/--output=//'` ;; ++ -o=*) ++ OUTPUT_PATH=`echo "$option" | sed 's/-o=//'` ;; ++ esac ++done ++ ++# set user input or default path for user.cfg file ++if [ -z "${OUTPUT_PATH}" ]; then ++ OUTPUT_PATH="${grubdir}" ++fi ++ ++if [ ! -d "${OUTPUT_PATH}" ]; then ++ echo "${OUTPUT_PATH} does not exist." ++ usage ++ exit 2; ++fi ++ ++ttyopt=$(stty -g) ++fixtty() { ++ stty ${ttyopt} ++} ++ ++trap fixtty EXIT ++stty -echo ++ ++# prompt & confirm new grub2 root user password ++echo -n "Enter password: " ++read PASSWORD ++echo ++echo -n "Confirm password: " ++read PASSWORD_CONFIRM ++echo ++stty ${ttyopt} ++ ++getpass() { ++ local P0 ++ local P1 ++ P0="$1" && shift ++ P1="$1" && shift ++ ++ ( echo ${P0} ; echo ${P1} ) | \ ++ LC_ALL=C ${grub_mkpasswd} | \ ++ grep -v '[eE]nter password:' | \ ++ sed -e "s/PBKDF2 hash of your password is //" ++} ++ ++MYPASS="$(getpass "${PASSWORD}" "${PASSWORD_CONFIRM}")" ++if [ -z "${MYPASS}" ]; then ++ echo "${self}: error: empty password" 1>&2 ++ exit 1 ++fi ++ ++# on the ESP, these will fail to set the permissions, but it's okay because ++# the directory is protected. ++install -m 0600 /dev/null "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : ++chmod 0600 "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : ++echo "GRUB2_PASSWORD=${MYPASS}" > "${OUTPUT_PATH}/user.cfg" ++ ++if ! grep -q "^### BEGIN /etc/grub.d/01_users ###$" "${OUTPUT_PATH}/grub.cfg"; then ++ echo "WARNING: The current configuration lacks password support!" ++ echo "Update your configuration with @grub_mkconfig@ to support this feature." ++fi +diff --git a/util/grub.d/01_users.in b/util/grub.d/01_users.in +new file mode 100644 +index 0000000..db2f44b +--- /dev/null ++++ b/util/grub.d/01_users.in +@@ -0,0 +1,11 @@ ++#!/bin/sh -e ++cat << EOF ++if [ -f \${prefix}/user.cfg ]; then ++ source \${prefix}/user.cfg ++ if [ -n "\${GRUB2_PASSWORD}" ]; then ++ set superusers="root" ++ export superusers ++ password_pbkdf2 root \${GRUB2_PASSWORD} ++ fi ++fi ++EOF +-- +2.33.0 + diff --git a/grub.patches b/grub.patches index 176b486..1bf37ec 100644 --- a/grub.patches +++ b/grub.patches @@ -207,6 +207,14 @@ Patch206: remove-the-items-of-unsupported-filesystems-in-fs.ls.patch Patch207: backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch Patch208: modify-klist-in-10_linux.in.patch Patch209: 0019-Add-fw_path-variable-revised.patch -Patch210: 0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch +Patch210: 0024-Don-t-say-GNU-Linux-in-generated-menus.patch +Patch211: 0026-Don-t-require-a-password-to-boot-entries-generated-b.patch +Patch212: 0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch +Patch213: 0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch +Patch214: 0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch +Patch215: 0032-Try-prefix-if-fw_path-doesn-t-work.patch +Patch216: 0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch +Patch217: 0035-Add-friendly-grub2-password-config-tool-985962.patch +Patch218: grub2-set-password-prompts-to-enter-the-current-pass.patch #Patch208: add-TPCM-support-with-ipmi-channel.patch #Patch209: skip-verification-when-not-loading-grub.cfg.patch diff --git a/grub2-set-password-prompts-to-enter-the-current-pass.patch b/grub2-set-password-prompts-to-enter-the-current-pass.patch new file mode 100644 index 0000000..1644e35 --- /dev/null +++ b/grub2-set-password-prompts-to-enter-the-current-pass.patch @@ -0,0 +1,313 @@ +From 23ade142e708ef9c225f0ccfd519e48132793888 Mon Sep 17 00:00:00 2001 +From: liuxin +Date: Thu, 2 Sep 2021 17:30:39 +0800 +Subject: [PATCH] grub2-set-password prompts to enter the current password and + add the password complexity check + +--- + util/grub-mkpasswd-pbkdf2.c | 105 ++++++++++++++++++++++++++++++--- + util/grub-set-password.in | 114 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 212 insertions(+), 7 deletions(-) + +diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c +index 29c68fb..b7c6e48 100644 +--- a/util/grub-mkpasswd-pbkdf2.c ++++ b/util/grub-mkpasswd-pbkdf2.c +@@ -42,10 +42,14 @@ + + #include "progname.h" + ++#define GRUB_PARAM_ERROR 1 ++#define GRUB_PARAM_SUCCESS 0 ++ + static struct argp_option options[] = { + {"iteration-count", 'c', N_("NUM"), 0, N_("Number of PBKDF2 iterations"), 0}, + {"buflen", 'l', N_("NUM"), 0, N_("Length of generated hash"), 0}, + {"salt", 's', N_("NUM"), 0, N_("Length of salt"), 0}, ++ {"salt arg", 'a', N_("VARCHAR"), 0, N_("preset salt var(hex code)"), 0}, + { 0, 0, 0, 0, 0, 0 } + }; + +@@ -54,8 +58,45 @@ struct arguments + unsigned int count; + unsigned int buflen; + unsigned int saltlen; ++ char * salt; + }; + ++static int illegal_char(char t) ++{ ++ int illegal = GRUB_PARAM_ERROR; ++ char legal[] = "0123456789ABCDEF"; ++ for (int i = 0; i < grub_strlen(legal); ++i) { ++ if (t == legal[i]) { ++ illegal = GRUB_PARAM_SUCCESS; ++ break; ++ } ++ } ++ return illegal; ++} ++ ++static int check_salt_verify(const char * arg) ++{ ++ grub_size_t len = grub_strlen(arg); ++ if (len <= 0 || len >= GRUB_SIZE_MAX) ++ { ++ fprintf(stderr, "salt length may be empty or too long!\n"); ++ return GRUB_PARAM_ERROR; ++ } ++ if (len % 2 != 0) ++ { ++ fprintf(stderr, "the salt value length is an even number!\n"); ++ return GRUB_PARAM_ERROR; ++ } ++ for (int i = 0; i < len; ++i) ++ { ++ if (illegal_char(arg[i])) ++ { ++ return GRUB_PARAM_ERROR; ++ } ++ } ++ return GRUB_PARAM_SUCCESS; ++} ++ + static error_t + argp_parser (int key, char *arg, struct argp_state *state) + { +@@ -76,6 +117,16 @@ argp_parser (int key, char *arg, struct argp_state *state) + case 's': + arguments->saltlen = strtoul (arg, NULL, 0); + break; ++ ++ case 'a': ++ if (check_salt_verify(arg)) ++ { ++ fprintf(stderr, "only hexadecimal numbers consisting of digits and uppercase letters are supported\n"); ++ return ARGP_ERR_UNKNOWN; ++ } ++ arguments->saltlen = grub_strlen(arg) / 2; ++ arguments->salt = arg; ++ break; + default: + return ARGP_ERR_UNKNOWN; + } +@@ -110,13 +161,44 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n) + *hex = 0; + } + ++static void ++hextobyte(const char *hex, grub_uint8_t *bin, grub_size_t n) ++{ ++ while(n) ++ { ++ grub_uint8_t tmp = 0x00; ++ if (((*hex) <= '9') && ((*hex) >= '0')) ++ { ++ tmp += (grub_uint8_t)((*hex) - '0') << 4 & 0xf0; ++ } ++ else ++ { ++ tmp += (grub_uint8_t)((*hex) - 'A' + 10) << 4 & 0xf0; ++ } ++ hex++; ++ if (((*hex) <= '9') && ((*hex) >= '0')) ++ { ++ tmp += (grub_uint8_t)((*hex) - '0') & 0x0f; ++ } ++ else ++ { ++ tmp += (grub_uint8_t)((*hex) - 'A' + 10) & 0x0f; ++ } ++ *bin = tmp; ++ bin++; ++ hex++; ++ n -= 2; ++ } ++} ++ + int + main (int argc, char *argv[]) + { + struct arguments arguments = { + .count = 10000, + .buflen = 64, +- .saltlen = 64 ++ .saltlen = 64, ++ .salt = NULL + }; + char *result, *ptr; + gcry_err_code_t gcry_err; +@@ -133,6 +215,12 @@ main (int argc, char *argv[]) + exit(1); + } + ++ if (arguments.salt != NULL && grub_strlen(arguments.salt) != 2 * arguments.saltlen) ++ { ++ fprintf(stderr, "%s", _("If the -a parameter is set, don't set the -s parameter again\n")); ++ exit(1); ++ } ++ + buf = xmalloc (arguments.buflen); + salt = xmalloc (arguments.saltlen); + +@@ -161,13 +249,16 @@ main (int argc, char *argv[]) + } + memset (pass2, 0, sizeof (pass2)); + +- if (grub_get_random (salt, arguments.saltlen)) ++ if (arguments.salt != NULL) + { +- memset (pass1, 0, sizeof (pass1)); +- free (buf); +- free (salt); +- grub_util_error ("%s", _("couldn't retrieve random data for salt")); +- } ++ hextobyte(arguments.salt, salt, arguments.saltlen * 2); ++ } else if (grub_get_random (salt, arguments.saltlen)) ++ { ++ memset (pass1, 0, sizeof (pass1)); ++ free (buf); ++ free (salt); ++ grub_util_error ("%s", _("couldn't retrieve random data for salt")); ++ } + + gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, + (grub_uint8_t *) pass1, strlen (pass1), +diff --git a/util/grub-set-password.in b/util/grub-set-password.in +index c0b5ebb..3e14a5d 100644 +--- a/util/grub-set-password.in ++++ b/util/grub-set-password.in +@@ -87,16 +87,130 @@ fixtty() { + } + + trap fixtty EXIT ++ ++getsaltpass() { ++ local P0 ++ local P1 ++ P0="$1" && shift ++ P1="$1" && shift ++ P2="$1" && shift ++ ++ ( echo ${P0} ; echo ${P1} ) | \ ++ LC_ALL=C ${grub_mkpasswd} -a ${P2} | \ ++ grep -v '[eE]nter password:' | \ ++ sed -e "s/PBKDF2 hash of your password is //" ++} ++ ++verifyusercfgoldpasswd() { ++ # get old password salt ++ expectsalt=`cat ${grubdir}/user.cfg | cut -d "." -f 5` ++ # get expect password ++ expectpass=`cat ${grubdir}/user.cfg` ++ prefix="GRUB2_PASSWORD=" ++ ++ stty -echo ++ echo -n "Enter Current password: " ++ read PASSWORD_CURRENT ++ echo ++ ++ needcheckpass="${prefix}$(getsaltpass "${PASSWORD_CURRENT}" "${PASSWORD_CURRENT}" "${expectsalt}")" ++ if [ "$expectpass" != "$needcheckpass" ]; then ++ echo "Authentication failed" ++ exit 1 ++ fi ++ ++ stty ${ttyopt} ++} ++ ++verifygrubcfgoldpasswd() { ++ # get old password line ++ expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root grub.pbkdf2.sha512" | cut -d " " -f 3` ++ # if not get password, try a quotation mark match ++ if [ -z "$expectpass" ];then ++ expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root \"grub.pbkdf2.sha512" | cut -d " " -f 3 | cut -d "\"" -f 2` ++ fi ++ if [ -z "$expectpass" ];then ++ expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root 'grub.pbkdf2.sha512" | cut -d " " -f 3 | cut -d "'" -f 2` ++ fi ++ if [ -n "$expectpass" ];then ++ # get old password salt ++ expectsalt=`echo ${expectpass} | cut -d "." -f 5` ++ stty -echo ++ echo -n "Enter Current password: " ++ read PASSWORD_CURRENT ++ echo ++ ++ needcheckpass="$(getsaltpass "${PASSWORD_CURRENT}" "${PASSWORD_CURRENT}" "${expectsalt}")" ++ if [ "$expectpass" != "$needcheckpass" ]; then ++ echo "Authentication failed" ++ exit 1 ++ fi ++ fi ++ ++} ++ ++if [ -e ${grubdir}/user.cfg ];then ++ verifyusercfgoldpasswd ++else ++ verifygrubcfgoldpasswd ++fi ++ ++checkcomplexity() { ++ set +e ++ USERNAME=`cat ${grubdir}/grub.cfg | grep "set superusers=" | cut -d "\"" -f 2 |tail -1` ++ local P1="$1" && shift ++ if [ "$P1" = "$USERNAME" ];then ++ echo "The password contains the user name in some form" ++ exit 1 ++ fi ++ # password len >= 8 ++ strlen=`echo "$P1" | grep -E '^(.{8,}).*$'` ++ if [ -z "$strlen" ];then ++ echo "The password is shorter than 8 characters" ++ exit 1 ++ fi ++ # lowercase ++ strlow=`echo "$P1" | grep -E --color '^(.*[a-z]+).*$'` ++ # uppercase ++ strupp=`echo $P1 | grep -E --color '^(.*[A-Z]).*$'` ++ # special character ++ strts=`echo $P1 | grep -E --color '^(.*\W).*$'` ++ # num ++ strnum=`echo $P1 | grep -E --color '^(.*[0-9]).*$'` ++ complexity=0 ++ if [ -n "$strlow" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ -n "$strupp" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ -n "$strts" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ -n "$strnum" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ $complexity -lt 3 ];then ++ echo "The password contains less than 3 character classes" ++ exit 1 ++ fi ++ set -e ++} ++ + stty -echo + + # prompt & confirm new grub2 root user password + echo -n "Enter password: " + read PASSWORD + echo ++stty ${ttyopt} ++checkcomplexity $PASSWORD ++stty -echo + echo -n "Confirm password: " + read PASSWORD_CONFIRM + echo + stty ${ttyopt} ++checkcomplexity $PASSWORD_CONFIRM + + getpass() { + local P0 +-- +2.33.0 + diff --git a/grub2.spec b/grub2.spec index 788a643..15fb21f 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 3 +Release: 4 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -449,6 +449,12 @@ fi %{_datadir}/man/man* %changelog +* Mon Mar 11 2024 zhangqiumiao - 1:2.12-4 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:Don't require a password to boot entries generated by grub-mkconfig + * Fri Mar 8 2024 zhangqiumiao - 1:2.12-3 - Type:bugfix - CVE:NA -- Gitee From 1e52014b39673718830070eb7dfe450646954074 Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Thu, 21 Mar 2024 11:36:26 +0000 Subject: [PATCH 03/26] add TPCM support with ipmi channel Signed-off-by: Qiumiao Zhang --- add-TPCM-support-with-ipmi-channel.patch | 19 +++++++++---------- grub.macros | 2 +- grub.patches | 4 ++-- grub2.spec | 8 +++++++- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/add-TPCM-support-with-ipmi-channel.patch b/add-TPCM-support-with-ipmi-channel.patch index d1511d9..29b1017 100644 --- a/add-TPCM-support-with-ipmi-channel.patch +++ b/add-TPCM-support-with-ipmi-channel.patch @@ -13,7 +13,6 @@ fix firmwarehash length and uiCmdLength error clean code zhangqiumiao(4): -skip verification when just opening the grub.cfg without loading it support control switch modify GRUB_IPMI_TIMEOUT_MS from 7000 to 2000 @@ -68,10 +67,10 @@ index 0000000..57a4cea + ((value >> 8 ) & 0x0000FF00) | \ + ((value >> 24 ) & 0x000000FF)) + -+static grub_efi_guid_t gIpmiInterfaceProtocolGuid = EFI_TPCM_GUID; -+static grub_efi_guid_t hash2_service_binding_guid = GRUB_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID; -+static grub_efi_guid_t hash2_guid = GRUB_EFI_HASH2_PROTOCOL_GUID; -+static grub_efi_guid_t sm3_guid = GRUB_HASH_ALGORITHM_SM3_GUID; ++static grub_guid_t gIpmiInterfaceProtocolGuid = EFI_TPCM_GUID; ++static grub_guid_t hash2_service_binding_guid = GRUB_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID; ++static grub_guid_t hash2_guid = GRUB_EFI_HASH2_PROTOCOL_GUID; ++static grub_guid_t sm3_guid = GRUB_HASH_ALGORITHM_SM3_GUID; + +static grub_efi_ipmi_interface_protocol_t *tpcm_ipmi; +static grub_efi_uint16_t grub_tcpm_file_type = GRUB_FILE_TYPE_NONE; @@ -80,7 +79,7 @@ index 0000000..57a4cea +static grub_efi_uint8_t permissive = 0; + +static grub_efi_handle_t -+grub_efi_service_binding (grub_efi_guid_t *service_binding_guid) ++grub_efi_service_binding (grub_guid_t *service_binding_guid) +{ + grub_efi_service_binding_t *service; + grub_efi_status_t status; @@ -102,7 +101,7 @@ index 0000000..57a4cea + return NULL; + } + -+ status = efi_call_2 (service->create_child, service, &child_dev); ++ status = service->create_child (service, &child_dev); + if (status != GRUB_EFI_SUCCESS) + { + grub_printf ("Failed to create child device of efi service %x\n", status); @@ -718,19 +717,19 @@ index 0000000..d4cf93b +struct grub_efi_hash2_protocol { + grub_efi_status_t + (*get_hash_size) (struct grub_efi_hash2_protocol *this, -+ grub_efi_guid_t *hash_algorithm, ++ grub_guid_t *hash_algorithm, + grub_efi_uintn_t hash_size); + + grub_efi_status_t + (*hash) (struct grub_efi_hash2_protocol *this, -+ grub_efi_guid_t *hash_algorithm, ++ grub_guid_t *hash_algorithm, + grub_efi_uint8_t *message, + grub_efi_uintn_t message_size, + grub_efi_hash2_output *hash); + + grub_efi_status_t + (*hash_init) (struct grub_efi_hash2_protocol *this, -+ grub_efi_guid_t *hash_algorithm); ++ grub_guid_t *hash_algorithm); + + grub_efi_status_t + (*hash_update) (struct grub_efi_hash2_protocol *this, diff --git a/grub.macros b/grub.macros index a358017..03f7024 100644 --- a/grub.macros +++ b/grub.macros @@ -118,7 +118,7 @@ ### fixme %ifarch aarch64 %{arm} riscv64 loongarch64 -%global efi_modules " tpm " +%global efi_modules " tpm tpcm_kunpeng " %else %global efi_modules " backtrace chain tpm usb usbserial_common usbserial_pl2303 usbserial_ftdi usbserial_usbdebug keylayouts at_keyboard " %endif diff --git a/grub.patches b/grub.patches index 1bf37ec..d6547be 100644 --- a/grub.patches +++ b/grub.patches @@ -216,5 +216,5 @@ Patch215: 0032-Try-prefix-if-fw_path-doesn-t-work.patch Patch216: 0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch Patch217: 0035-Add-friendly-grub2-password-config-tool-985962.patch Patch218: grub2-set-password-prompts-to-enter-the-current-pass.patch -#Patch208: add-TPCM-support-with-ipmi-channel.patch -#Patch209: skip-verification-when-not-loading-grub.cfg.patch +Patch219: add-TPCM-support-with-ipmi-channel.patch +Patch220: skip-verification-when-not-loading-grub.cfg.patch diff --git a/grub2.spec b/grub2.spec index 15fb21f..10c3619 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 4 +Release: 5 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -449,6 +449,12 @@ fi %{_datadir}/man/man* %changelog +* Thu Mar 21 2024 zhangqiumiao - 1:2.12-5 +- Type:requirement +- CVE:NA +- SUG:NA +- DESC:add TPCM support with ipmi channel + * Mon Mar 11 2024 zhangqiumiao - 1:2.12-4 - Type:bugfix - CVE:NA -- Gitee From c9cf3a76023a60fa416036bb95da3e32cb977d4f Mon Sep 17 00:00:00 2001 From: jinlun Date: Fri, 22 Mar 2024 17:14:54 +0800 Subject: [PATCH 04/26] Interface for replacing the EFI signature --- grub2.spec | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/grub2.spec b/grub2.spec index 10c3619..6f087ef 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 5 +Release: 6 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -42,10 +42,6 @@ BuildRequires: autoconf automake device-mapper-devel freetype-devel git BuildRequires: texinfo gettext-devel dejavu-sans-fonts help2man systemd fuse-devel BuildRequires: libtasn1-devel -%if 0%{?openEuler_sign_rsa} -BuildRequires: sign-openEuler -%endif - %ifarch %{golang_arches} BuildRequires: pesign >= 0.99-8 %endif @@ -203,8 +199,10 @@ makeinfo --info --no-split -I docs -o docs/grub.info docs/grub.texi makeinfo --html --no-split -I docs -o docs/grub-dev.html docs/grub-dev.texi makeinfo --html --no-split -I docs -o docs/grub.html docs/grub.texi %if 0%{?openEuler_sign_rsa} -/opt/sign-openEuler/client --config /opt/sign-openEuler/config.toml add --key-name default-x509ee --file-type efi-image --key-type x509ee --sign-type authenticode %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname} -/opt/sign-openEuler/client --config /opt/sign-openEuler/config.toml add --key-name default-x509ee --file-type efi-image --key-type x509ee --sign-type authenticode %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname} +sh /usr/lib/rpm/brp-ebs-sign --efi %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname} +sh /usr/lib/rpm/brp-ebs-sign --efi %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname} +mv %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname}.sig %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname} +mv %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname}.sig %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname} %endif %check @@ -449,6 +447,12 @@ fi %{_datadir}/man/man* %changelog +* Fri Mar 22 2024 jinlun - 1:2.12-6 +- Type:requirement +- CVE:NA +- SUG:NA +- DESC:Interface for replacing the EFI signature + * Thu Mar 21 2024 zhangqiumiao - 1:2.12-5 - Type:requirement - CVE:NA -- Gitee From f567bbdc444bb5ddf157c65e568e5b50a1f17169 Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Mon, 8 Apr 2024 07:45:20 +0000 Subject: [PATCH 05/26] fix compressed kernel verification failed Signed-off-by: Qiumiao Zhang --- ...ompressed-kernel-verification-failed.patch | 29 +++++++++++ ...upmode-not-available-in-some-machine.patch | 48 +++++++++++++++++++ grub.patches | 2 + grub2.spec | 8 +++- 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 fix-compressed-kernel-verification-failed.patch create mode 100644 fix-setupmode-not-available-in-some-machine.patch diff --git a/fix-compressed-kernel-verification-failed.patch b/fix-compressed-kernel-verification-failed.patch new file mode 100644 index 0000000..fa97f96 --- /dev/null +++ b/fix-compressed-kernel-verification-failed.patch @@ -0,0 +1,29 @@ +From 0a73812b9ba12f8af4909b952751d6d5f4fd2dd2 Mon Sep 17 00:00:00 2001 +From: Qiumiao Zhang +Date: Sat, 23 Jul 2022 19:54:34 +0800 +Subject: [PATCH] fix compressed kernel verification failed + +Signed-off-by: Yusong Gao +--- + include/grub/file.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/grub/file.h b/include/grub/file.h +index daf23a9..5279e7d 100644 +--- a/include/grub/file.h ++++ b/include/grub/file.h +@@ -187,10 +187,10 @@ typedef enum grub_file_filter_id + { + GRUB_FILE_FILTER_DISTRUST, + GRUB_FILE_FILTER_NOCAT, +- GRUB_FILE_FILTER_VERIFY, + GRUB_FILE_FILTER_GZIO, + GRUB_FILE_FILTER_XZIO, + GRUB_FILE_FILTER_LZOPIO, ++ GRUB_FILE_FILTER_VERIFY, + GRUB_FILE_FILTER_MAX, + GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO, + GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO, +-- +2.33.0 + diff --git a/fix-setupmode-not-available-in-some-machine.patch b/fix-setupmode-not-available-in-some-machine.patch new file mode 100644 index 0000000..bfa7829 --- /dev/null +++ b/fix-setupmode-not-available-in-some-machine.patch @@ -0,0 +1,48 @@ +From 4fc72f509627da808b452eb1186282237c449b65 Mon Sep 17 00:00:00 2001 +From: fengtao +Date: Tue, 22 Mar 2022 22:22:22 +0800 +Subject: [PATCH] fix setupmode not available in some machine + +In some machine, there is no setupmode variable, so we should +give setupmode a default vaule: setup_mode = 0 + +if we cannot get setupmode variable, we use setup_mode instead. + +--- + grub-core/kern/efi/sb.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c +index c52ec62..f58fb13 100644 +--- a/grub-core/kern/efi/sb.c ++++ b/grub-core/kern/efi/sb.c +@@ -50,6 +50,7 @@ grub_efi_get_secureboot (void) + grub_uint8_t *moksbstate = NULL; + grub_uint8_t secureboot = GRUB_EFI_SECUREBOOT_MODE_UNKNOWN; + const char *secureboot_str = "UNKNOWN"; ++ grub_uint8_t setup_mode = 0; + + status = grub_efi_get_variable ("SecureBoot", &efi_variable_guid, + &size, (void **) &secboot); +@@ -67,9 +68,16 @@ grub_efi_get_secureboot (void) + &size, (void **) &setupmode); + + if (status != GRUB_EFI_SUCCESS) +- goto out; ++ { ++ grub_dprintf ("efi", "No SetupMode variable\n"); ++ } ++ else ++ { ++ grub_dprintf ("efi", "SetupMode: %d\n", *setupmode); ++ setup_mode = *setupmode; ++ } + +- if ((*secboot == 0) || (*setupmode == 1)) ++ if ((*secboot == 0) || (setup_mode == 1)) + { + secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED; + goto out; +-- +2.23.0 + diff --git a/grub.patches b/grub.patches index d6547be..5295d23 100644 --- a/grub.patches +++ b/grub.patches @@ -218,3 +218,5 @@ Patch217: 0035-Add-friendly-grub2-password-config-tool-985962.patch Patch218: grub2-set-password-prompts-to-enter-the-current-pass.patch Patch219: add-TPCM-support-with-ipmi-channel.patch Patch220: skip-verification-when-not-loading-grub.cfg.patch +Patch221: fix-setupmode-not-available-in-some-machine.patch +Patch222: fix-compressed-kernel-verification-failed.patch diff --git a/grub2.spec b/grub2.spec index 6f087ef..b4bb1de 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 6 +Release: 7 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,12 @@ fi %{_datadir}/man/man* %changelog +* Mon Apr 8 2024 zhangqiumiao - 1:2.12-7 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:fix compressed kernel verification failed + * Fri Mar 22 2024 jinlun - 1:2.12-6 - Type:requirement - CVE:NA -- Gitee From 908a3e71137970eaa927be7b646ead3ac17ce084 Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Tue, 9 Apr 2024 13:59:26 +0000 Subject: [PATCH 06/26] sync patches from 22.03-LTS-Next Signed-off-by: Qiumiao Zhang --- grub.patches | 38 ++++++++------- grub2.spec | 9 +++- support-TPM2.0.patch | 97 +++++++++++++++++++++++++++++++++++++ use-default-timestamp.patch | 57 ++++++++++++++++++++++ 4 files changed, 182 insertions(+), 19 deletions(-) create mode 100644 support-TPM2.0.patch create mode 100644 use-default-timestamp.patch diff --git a/grub.patches b/grub.patches index 5295d23..0292498 100644 --- a/grub.patches +++ b/grub.patches @@ -202,21 +202,23 @@ Patch201: 0002-ofdisk-add-early_log-support.patch Patch202: 0001-disk-Optimize-disk-iteration-by-moving-memdisk-to-th.patch Patch203: grub2-bash-completion-2.12.patch Patch204: 0010-re-write-.gitignore.patch -Patch205: disable-some-unsupported-filesystems.patch -Patch206: remove-the-items-of-unsupported-filesystems-in-fs.ls.patch -Patch207: backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch -Patch208: modify-klist-in-10_linux.in.patch -Patch209: 0019-Add-fw_path-variable-revised.patch -Patch210: 0024-Don-t-say-GNU-Linux-in-generated-menus.patch -Patch211: 0026-Don-t-require-a-password-to-boot-entries-generated-b.patch -Patch212: 0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch -Patch213: 0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch -Patch214: 0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch -Patch215: 0032-Try-prefix-if-fw_path-doesn-t-work.patch -Patch216: 0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch -Patch217: 0035-Add-friendly-grub2-password-config-tool-985962.patch -Patch218: grub2-set-password-prompts-to-enter-the-current-pass.patch -Patch219: add-TPCM-support-with-ipmi-channel.patch -Patch220: skip-verification-when-not-loading-grub.cfg.patch -Patch221: fix-setupmode-not-available-in-some-machine.patch -Patch222: fix-compressed-kernel-verification-failed.patch +Patch205: disable-some-unsupported-filesystems.patch +Patch206: remove-the-items-of-unsupported-filesystems-in-fs.ls.patch +Patch207: backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch +Patch208: modify-klist-in-10_linux.in.patch +Patch209: 0019-Add-fw_path-variable-revised.patch +Patch210: 0024-Don-t-say-GNU-Linux-in-generated-menus.patch +Patch211: 0026-Don-t-require-a-password-to-boot-entries-generated-b.patch +Patch212: 0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch +Patch213: 0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch +Patch214: 0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch +Patch215: 0032-Try-prefix-if-fw_path-doesn-t-work.patch +Patch216: 0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch +Patch217: 0035-Add-friendly-grub2-password-config-tool-985962.patch +Patch218: grub2-set-password-prompts-to-enter-the-current-pass.patch +Patch219: add-TPCM-support-with-ipmi-channel.patch +Patch220: skip-verification-when-not-loading-grub.cfg.patch +Patch221: fix-setupmode-not-available-in-some-machine.patch +Patch222: fix-compressed-kernel-verification-failed.patch +Patch223: support-TPM2.0.patch +Patch224: use-default-timestamp.patch diff --git a/grub2.spec b/grub2.spec index b4bb1de..b21aa7d 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 7 +Release: 8 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,13 @@ fi %{_datadir}/man/man* %changelog +* Tue Apr 9 2024 zhangqiumiao - 1:2.12-8 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:support TPM2.0 + use default timestamp + * Mon Apr 8 2024 zhangqiumiao - 1:2.12-7 - Type:bugfix - CVE:NA diff --git a/support-TPM2.0.patch b/support-TPM2.0.patch new file mode 100644 index 0000000..e5ad77e --- /dev/null +++ b/support-TPM2.0.patch @@ -0,0 +1,97 @@ +From f3d9f0413e8c7304b5bb4a0e927a6608504f2795 Mon Sep 17 00:00:00 2001 +From: gaoyusong +Date: Thu, 13 May 2021 18:34:23 +0800 +Subject: [PATCH] support TPM2.0 + +--- + grub-core/kern/verifiers.c | 26 ++++++++++++++++++++------ + grub-core/script/execute.c | 12 +++++++++++- + 2 files changed, 31 insertions(+), 7 deletions(-) + +diff --git a/grub-core/kern/verifiers.c b/grub-core/kern/verifiers.c +index 75d7994..1d3ca2b 100644 +--- a/grub-core/kern/verifiers.c ++++ b/grub-core/kern/verifiers.c +@@ -84,9 +84,15 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) + grub_file_t ret = 0; + grub_err_t err; + int defer = 0; ++ int grub_env_flag = 0; ++ char *ptr = NULL; + + grub_dprintf ("verify", "file: %s type: %d\n", io->name, type); + ++ ptr = grub_strstr(io->name, "grubenv"); ++ if (ptr) ++ grub_env_flag = 1; ++ + if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_SIGNATURE + || (type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_VERIFY_SIGNATURE + || (type & GRUB_FILE_TYPE_SKIP_SIGNATURE)) +@@ -148,6 +154,8 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) + verified->buf = grub_malloc (ret->size); + if (!verified->buf) + { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "cannot allocate verified buffer, the %s is too large\n", io->name); + goto fail; + } + if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size) +@@ -158,9 +166,12 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) + goto fail; + } + +- err = ver->write (context, verified->buf, ret->size); +- if (err) +- goto fail; ++ if (!grub_env_flag) ++ { ++ err = ver->write (context, verified->buf, ret->size); ++ if (err) ++ goto fail; ++ } + + err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE; + if (err) +@@ -179,9 +190,12 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) + /* Verification done earlier. So, we are happy here. */ + flags & GRUB_VERIFY_FLAGS_DEFER_AUTH) + continue; +- err = ver->write (context, verified->buf, ret->size); +- if (err) +- goto fail; ++ if (!grub_env_flag) ++ { ++ err = ver->write (context, verified->buf, ret->size); ++ if (err) ++ goto fail; ++ } + + err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE; + if (err) +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index 0c6dd9c..3e761c4 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -1002,7 +1002,17 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) + argv.args[i]); + } + cmdstring[cmdlen - 1] = '\0'; +- grub_verify_string (cmdstring, GRUB_VERIFY_COMMAND); ++ ++ if (grub_strncmp(cmdstring, "[ 0 = 1 ]", 9) == 0) { ++ char res_str[] = "[ = 1 ]"; ++ grub_verify_string (res_str, GRUB_VERIFY_COMMAND); ++ } else if (grub_strncmp(cmdstring, "[ 0 = 1 -o = 1 ]", 17) == 0) { ++ char res_str[] = "[ = 1 -o = 1 ]"; ++ grub_verify_string (res_str, GRUB_VERIFY_COMMAND); ++ } else { ++ grub_verify_string (cmdstring, GRUB_VERIFY_COMMAND); ++ } ++ + grub_free (cmdstring); + invert = 0; + argc = argv.argc - 1; +-- +2.19.1 + diff --git a/use-default-timestamp.patch b/use-default-timestamp.patch new file mode 100644 index 0000000..6196ab9 --- /dev/null +++ b/use-default-timestamp.patch @@ -0,0 +1,57 @@ +From 62cb96c5b34bfa68ad3d7ffe3f3098d8cd08f83f Mon Sep 17 00:00:00 2001 +From: zhouyihang +Date: Thu, 10 Jun 2021 20:01:54 +0800 +Subject: [PATCH] use default timestamp + +--- + docs/grub-dev.texi | 4 ++-- + docs/grub.texi | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi +index 9008377..874b3ea 100644 +--- a/docs/grub-dev.texi ++++ b/docs/grub-dev.texi +@@ -18,7 +18,7 @@ + + @copying + This developer manual is for GNU GRUB (version @value{VERSION}, +-@value{UPDATED}). ++24 June 2019). + + Copyright @copyright{} 1999,2000,2001,2002,2004,2005,2006,2008,2009,2010,2011 Free Software Foundation, Inc. + +@@ -40,7 +40,7 @@ Invariant Sections. + @titlepage + @sp 10 + @title the GNU GRUB developer manual +-@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. ++@subtitle The GRand Unified Bootloader, version @value{VERSION}, 24 June 2019. + @author Yoshinori K. Okuji + @author Colin D Bennett + @author Vesa Jääskeläinen +diff --git a/docs/grub.texi b/docs/grub.texi +index a4da9c2..79055be 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -18,7 +18,7 @@ + + @copying + This manual is for GNU GRUB (version @value{VERSION}, +-@value{UPDATED}). ++24 June 2019). + + Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. + +@@ -48,7 +48,7 @@ Invariant Sections. + @titlepage + @sp 10 + @title the GNU GRUB manual +-@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. ++@subtitle The GRand Unified Bootloader, version @value{VERSION}, 24 June 2019). + @author Gordon Matzigkeit + @author Yoshinori K. Okuji + @author Colin Watson +-- +2.19.1 + -- Gitee From ce31b98a9c7cb28116572daf9e62349bc24e2a2f Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Tue, 30 Apr 2024 09:47:44 +0000 Subject: [PATCH 07/26] sync patches from openEuler-22.03-LTS-SP3 Signed-off-by: Qiumiao Zhang --- ...-Properly-disable-the-os-prober-by-d.patch | 75 + ...tes-Disable-the-os-prober-by-default.patch | 73 + ...f-man-pages-with-slightly-nicer-ones.patch | 1959 +++++++++++++++++ ...rnel-settings-and-use-it-in-10_linux.patch | 296 +++ ...-incr-command-to-increment-integer-v.patch | 96 + grub.macros | 4 +- grub.patches | 5 + grub2.spec | 22 +- 8 files changed, 2522 insertions(+), 8 deletions(-) create mode 100644 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch create mode 100644 0003-Revert-templates-Disable-the-os-prober-by-default.patch create mode 100644 0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch create mode 100644 0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch create mode 100644 0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch diff --git a/0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch b/0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch new file mode 100644 index 0000000..ae3882f --- /dev/null +++ b/0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Fri, 11 Jun 2021 12:10:54 +0200 +Subject: [PATCH] Revert "templates: Properly disable the os-prober by +default" + +This reverts commit 54e0a1bbf1e9106901a557195bb35e5e20fb3925. +--- + util/grub-mkconfig.in | 5 +---- + util/grub.d/30_os-prober.in | 8 ++++---- + 2 files changed, 5 insertions(+), 8 deletions(-) + +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index 908afa8..f939872 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -154,9 +154,6 @@ probe_nfsroot_device () { + + NFSROOT_DEVICE="`awk '($9!="autofs")&&($9!="securityfs")' /proc/self/mountinfo | probe_nfsroot_device`" + +-# Disable os-prober by default due to security reasons. +-GRUB_DISABLE_OS_PROBER="true" +- + if [ "x${NFSROOT_DEVICE}" != "x" ]; then + GRUB_DEVICE="" + GRUB_DEVICE_UUID="" +@@ -254,7 +251,6 @@ export GRUB_DEVICE \ + GRUB_DEVICE_PARTUUID \ + GRUB_DEVICE_BOOT \ + GRUB_DEVICE_BOOT_UUID \ +- GRUB_DISABLE_OS_PROBER \ + GRUB_FS \ + GRUB_FONT \ + GRUB_PRELOAD_MODULES \ +@@ -300,6 +296,7 @@ export GRUB_DEFAULT \ + GRUB_BACKGROUND \ + GRUB_THEME \ + GRUB_GFXPAYLOAD_LINUX \ ++ GRUB_DISABLE_OS_PROBER \ + GRUB_INIT_TUNE \ + GRUB_SAVEDEFAULT \ + GRUB_ENABLE_CRYPTODISK \ +diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in +index 2221090..8de62d5 100644 +--- a/util/grub.d/30_os-prober.in ++++ b/util/grub.d/30_os-prober.in +@@ -26,8 +26,8 @@ export TEXTDOMAINDIR="@localedir@" + + . "$pkgdatadir/grub-mkconfig_lib" + +-if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then +- grub_warn "$(gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.")" ++if [ "x${GRUB_DISABLE_OS_PROBER}" = "xfalse" ]; then ++ gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.\n" + exit 0 + fi + +@@ -36,12 +36,12 @@ if ! command -v os-prober > /dev/null || ! command -v linux-boot-prober > /dev/n + exit 0 + fi + +-grub_warn "$(gettext_printf "os-prober will be executed to detect other bootable partitions.\nIts output will be used to detect bootable binaries on them and create new boot entries.")" +- + OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`" + if [ -z "${OSPROBED}" ] ; then + # empty os-prober output, nothing doing + exit 0 ++else ++ grub_warn "$(gettext_printf "os-prober was executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" + fi + + osx_entry() { +-- +2.33.0 + diff --git a/0003-Revert-templates-Disable-the-os-prober-by-default.patch b/0003-Revert-templates-Disable-the-os-prober-by-default.patch new file mode 100644 index 0000000..f14cabc --- /dev/null +++ b/0003-Revert-templates-Disable-the-os-prober-by-default.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Fri, 11 Jun 2021 12:10:58 +0200 +Subject: [PATCH] Revert "templates: Disable the os-prober by default" + +This reverts commit e346414725a70e5c74ee87ca14e580c66f517666. +--- + docs/grub.texi | 18 ++++++++---------- + util/grub.d/30_os-prober.in | 5 +---- + 2 files changed, 9 insertions(+), 14 deletions(-) + +diff --git a/docs/grub.texi b/docs/grub.texi +index fcd6cad..1603432 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -1552,13 +1552,10 @@ boot sequence. If you have problems, set this option to @samp{text} and + GRUB will tell Linux to boot in normal text mode. + + @item GRUB_DISABLE_OS_PROBER +-The @command{grub-mkconfig} has a feature to use the external +-@command{os-prober} program to discover other operating systems installed on +-the same machine and generate appropriate menu entries for them. It is disabled +-by default since automatic and silent execution of @command{os-prober}, and +-creating boot entries based on that data, is a potential attack vector. Set +-this option to @samp{false} to enable this feature in the +-@command{grub-mkconfig} command. ++Normally, @command{grub-mkconfig} will try to use the external ++@command{os-prober} program, if installed, to discover other operating ++systems installed on the same system and generate appropriate menu entries ++for them. Set this option to @samp{true} to disable this. + + @item GRUB_OS_PROBER_SKIP_LIST + List of space-separated FS UUIDs of filesystems to be ignored from os-prober +@@ -1889,9 +1886,10 @@ than zero; otherwise 0. + @section Multi-boot manual config + + Currently autogenerating config files for multi-boot environments depends on +-os-prober and has several shortcomings. Due to that it is disabled by default. +-It is advised to use the power of GRUB syntax and do it yourself. A possible +-configuration is detailed here, feel free to adjust to your needs. ++os-prober and has several shortcomings. While fixing it is scheduled for the ++next release, meanwhile you can make use of the power of GRUB syntax and do it ++yourself. A possible configuration is detailed here, feel free to adjust to your ++needs. + + First create a separate GRUB partition, big enough to hold GRUB. Some of the + following entries show how to load OS installer images from this same partition, +diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in +index 8de62d5..affff6b 100644 +--- a/util/grub.d/30_os-prober.in ++++ b/util/grub.d/30_os-prober.in +@@ -26,8 +26,7 @@ export TEXTDOMAINDIR="@localedir@" + + . "$pkgdatadir/grub-mkconfig_lib" + +-if [ "x${GRUB_DISABLE_OS_PROBER}" = "xfalse" ]; then +- gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.\n" ++if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then + exit 0 + fi + +@@ -40,8 +39,6 @@ OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`" + if [ -z "${OSPROBED}" ] ; then + # empty os-prober output, nothing doing + exit 0 +-else +- grub_warn "$(gettext_printf "os-prober was executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" + fi + + osx_entry() { +-- +2.33.0 + diff --git a/0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch b/0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch new file mode 100644 index 0000000..cc73cbf --- /dev/null +++ b/0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch @@ -0,0 +1,1959 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 4 Mar 2014 11:00:23 -0500 +Subject: [PATCH] Replace a lot of man pages with slightly nicer ones. + +Replace a bunch of machine generated ones with ones that look nicer. +--- + configure.ac | 23 ++++++ + conf/Makefile.extra-dist | 1 - + docs/Makefile.am | 2 - + docs/man/grub-bios-setup.h2m | 6 -- + docs/man/grub-editenv.h2m | 5 -- + docs/man/grub-emu.h2m | 6 -- + docs/man/grub-file.h2m | 2 - + docs/man/grub-fstest.h2m | 4 - + docs/man/grub-glue-efi.h2m | 4 - + docs/man/grub-install.h2m | 6 -- + docs/man/grub-kbdcomp.h2m | 10 --- + docs/man/grub-macbless.h2m | 4 - + docs/man/grub-macho2img.h2m | 4 - + docs/man/grub-menulst2cfg.h2m | 4 - + docs/man/grub-mkconfig.h2m | 4 - + docs/man/grub-mkfont.h2m | 4 - + docs/man/grub-mkimage.h2m | 6 -- + docs/man/grub-mklayout.h2m | 10 --- + docs/man/grub-mknetdir.h2m | 4 - + docs/man/grub-mkpasswd-pbkdf2.h2m | 4 - + docs/man/grub-mkrelpath.h2m | 4 - + docs/man/grub-mkrescue.h2m | 4 - + docs/man/grub-mkstandalone.h2m | 4 - + docs/man/grub-mount.h2m | 2 - + docs/man/grub-ofpathname.h2m | 4 - + docs/man/grub-pe2elf.h2m | 4 - + docs/man/grub-probe.h2m | 4 - + docs/man/grub-reboot.h2m | 5 -- + docs/man/grub-render-label.h2m | 3 - + docs/man/grub-script-check.h2m | 4 - + docs/man/grub-set-default.h2m | 5 -- + docs/man/grub-sparc64-setup.h2m | 6 -- + docs/man/grub-syslinux2cfg.h2m | 4 - + gentpl.py | 5 +- + util/grub-bios-setup.8 | 54 +++++++++++++ + util/grub-editenv.1 | 46 +++++++++++ + util/grub-file.1 | 165 ++++++++++++++++++++++++++++++++++++++ + util/grub-fstest.1 | 99 +++++++++++++++++++++++ + util/grub-glue-efi.1 | 31 +++++++ + util/grub-install.8 | 128 +++++++++++++++++++++++++++++ + util/grub-kbdcomp.1 | 19 +++++ + util/grub-macbless.1 | 22 +++++ + util/grub-menulst2cfg.1 | 12 +++ + util/grub-mkconfig.8 | 17 ++++ + util/grub-mkfont.1 | 87 ++++++++++++++++++++ + util/grub-mkimage.1 | 95 ++++++++++++++++++++++ + util/grub-mklayout.1 | 27 +++++++ + util/grub-mknetdir.1 | 12 +++ + util/grub-mkpasswd-pbkdf2.1 | 27 +++++++ + util/grub-mkrelpath.1 | 12 +++ + util/grub-mkrescue.1 | 123 ++++++++++++++++++++++++++++ + util/grub-mkstandalone.1 | 100 +++++++++++++++++++++++ + util/grub-ofpathname.8 | 12 +++ + util/grub-probe.8 | 80 ++++++++++++++++++ + util/grub-reboot.8 | 21 +++++ + util/grub-render-label.1 | 51 ++++++++++++ + util/grub-script-check.1 | 21 +++++ + util/grub-set-default.8 | 21 +++++ + util/grub-sparc64-setup.8 | 12 +++ + 59 files changed, 1318 insertions(+), 147 deletions(-) + delete mode 100644 docs/man/grub-bios-setup.h2m + delete mode 100644 docs/man/grub-editenv.h2m + delete mode 100644 docs/man/grub-emu.h2m + delete mode 100644 docs/man/grub-file.h2m + delete mode 100644 docs/man/grub-fstest.h2m + delete mode 100644 docs/man/grub-glue-efi.h2m + delete mode 100644 docs/man/grub-install.h2m + delete mode 100644 docs/man/grub-kbdcomp.h2m + delete mode 100644 docs/man/grub-macbless.h2m + delete mode 100644 docs/man/grub-macho2img.h2m + delete mode 100644 docs/man/grub-menulst2cfg.h2m + delete mode 100644 docs/man/grub-mkconfig.h2m + delete mode 100644 docs/man/grub-mkfont.h2m + delete mode 100644 docs/man/grub-mkimage.h2m + delete mode 100644 docs/man/grub-mklayout.h2m + delete mode 100644 docs/man/grub-mknetdir.h2m + delete mode 100644 docs/man/grub-mkpasswd-pbkdf2.h2m + delete mode 100644 docs/man/grub-mkrelpath.h2m + delete mode 100644 docs/man/grub-mkrescue.h2m + delete mode 100644 docs/man/grub-mkstandalone.h2m + delete mode 100644 docs/man/grub-mount.h2m + delete mode 100644 docs/man/grub-ofpathname.h2m + delete mode 100644 docs/man/grub-pe2elf.h2m + delete mode 100644 docs/man/grub-probe.h2m + delete mode 100644 docs/man/grub-reboot.h2m + delete mode 100644 docs/man/grub-render-label.h2m + delete mode 100644 docs/man/grub-script-check.h2m + delete mode 100644 docs/man/grub-set-default.h2m + delete mode 100644 docs/man/grub-sparc64-setup.h2m + delete mode 100644 docs/man/grub-syslinux2cfg.h2m + create mode 100644 util/grub-bios-setup.8 + create mode 100644 util/grub-editenv.1 + create mode 100644 util/grub-file.1 + create mode 100644 util/grub-fstest.1 + create mode 100644 util/grub-glue-efi.1 + create mode 100644 util/grub-install.8 + create mode 100644 util/grub-kbdcomp.1 + create mode 100644 util/grub-macbless.1 + create mode 100644 util/grub-menulst2cfg.1 + create mode 100644 util/grub-mkconfig.8 + create mode 100644 util/grub-mkfont.1 + create mode 100644 util/grub-mkimage.1 + create mode 100644 util/grub-mklayout.1 + create mode 100644 util/grub-mknetdir.1 + create mode 100644 util/grub-mkpasswd-pbkdf2.1 + create mode 100644 util/grub-mkrelpath.1 + create mode 100644 util/grub-mkrescue.1 + create mode 100644 util/grub-mkstandalone.1 + create mode 100644 util/grub-ofpathname.8 + create mode 100644 util/grub-probe.8 + create mode 100644 util/grub-reboot.8 + create mode 100644 util/grub-render-label.1 + create mode 100644 util/grub-script-check.1 + create mode 100644 util/grub-set-default.8 + create mode 100644 util/grub-sparc64-setup.8 + +diff --git a/configure.ac b/configure.ac +index 8331f95b645..bec8535af70 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -77,6 +77,29 @@ grub_TRANSFORM([grub-set-default]) + grub_TRANSFORM([grub-sparc64-setup]) + grub_TRANSFORM([grub-render-label]) + grub_TRANSFORM([grub-file]) ++grub_TRANSFORM([grub-bios-setup.3]) ++grub_TRANSFORM([grub-editenv.1]) ++grub_TRANSFORM([grub-fstest.3]) ++grub_TRANSFORM([grub-glue-efi.3]) ++grub_TRANSFORM([grub-install.1]) ++grub_TRANSFORM([grub-kbdcomp.3]) ++grub_TRANSFORM([grub-menulst2cfg.1]) ++grub_TRANSFORM([grub-mkconfig.1]) ++grub_TRANSFORM([grub-mkfont.3]) ++grub_TRANSFORM([grub-mkimage.1]) ++grub_TRANSFORM([grub-mklayout.3]) ++grub_TRANSFORM([grub-mknetdir.3]) ++grub_TRANSFORM([grub-mkpasswd-pbkdf2.3]) ++grub_TRANSFORM([grub-mkrelpath.3]) ++grub_TRANSFORM([grub-mkrescue.1]) ++grub_TRANSFORM([grub-mkstandalone.3]) ++grub_TRANSFORM([grub-ofpathname.3]) ++grub_TRANSFORM([grub-probe.3]) ++grub_TRANSFORM([grub-reboot.3]) ++grub_TRANSFORM([grub-render-label.3]) ++grub_TRANSFORM([grub-script-check.3]) ++grub_TRANSFORM([grub-set-default.1]) ++grub_TRANSFORM([grub-sparc64-setup.3]) + + # Allow HOST_CC to override CC. + if test "x$HOST_CC" != x; then +diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist +index 8f1485d52a5..b909f2c073a 100644 +--- a/conf/Makefile.extra-dist ++++ b/conf/Makefile.extra-dist +@@ -11,7 +11,6 @@ EXTRA_DIST += unicode + EXTRA_DIST += util/import_gcry.py + EXTRA_DIST += util/import_unicode.py + +-EXTRA_DIST += docs/man + EXTRA_DIST += docs/autoiso.cfg + EXTRA_DIST += docs/grub.cfg + EXTRA_DIST += docs/osdetect.cfg +diff --git a/docs/Makefile.am b/docs/Makefile.am +index 93eb3962765..ab28f199694 100644 +--- a/docs/Makefile.am ++++ b/docs/Makefile.am +@@ -5,5 +5,3 @@ info_TEXINFOS = grub.texi grub-dev.texi + grub_TEXINFOS = fdl.texi + + EXTRA_DIST = font_char_metrics.png font_char_metrics.txt +- +- +diff --git a/docs/man/grub-bios-setup.h2m b/docs/man/grub-bios-setup.h2m +deleted file mode 100644 +index ac6ede36296..00000000000 +--- a/docs/man/grub-bios-setup.h2m ++++ /dev/null +@@ -1,6 +0,0 @@ +-[NAME] +-grub-bios-setup \- set up a device to boot using GRUB +-[SEE ALSO] +-.BR grub-install (8), +-.BR grub-mkimage (1), +-.BR grub-mkrescue (1) +diff --git a/docs/man/grub-editenv.h2m b/docs/man/grub-editenv.h2m +deleted file mode 100644 +index 3859d3d4c4f..00000000000 +--- a/docs/man/grub-editenv.h2m ++++ /dev/null +@@ -1,5 +0,0 @@ +-[NAME] +-grub-editenv \- edit GRUB environment block +-[SEE ALSO] +-.BR grub-reboot (8), +-.BR grub-set-default (8) +diff --git a/docs/man/grub-emu.h2m b/docs/man/grub-emu.h2m +deleted file mode 100644 +index ef1c000656a..00000000000 +--- a/docs/man/grub-emu.h2m ++++ /dev/null +@@ -1,6 +0,0 @@ +-[NAME] +-grub-emu \- GRUB emulator +-[SEE ALSO] +-If you are trying to install GRUB, then you should use +-.BR grub-install (8) +-rather than this program. +diff --git a/docs/man/grub-file.h2m b/docs/man/grub-file.h2m +deleted file mode 100644 +index e09bb4d3101..00000000000 +--- a/docs/man/grub-file.h2m ++++ /dev/null +@@ -1,2 +0,0 @@ +-[NAME] +-grub-file \- check file type +diff --git a/docs/man/grub-fstest.h2m b/docs/man/grub-fstest.h2m +deleted file mode 100644 +index 9676b159afd..00000000000 +--- a/docs/man/grub-fstest.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-fstest \- debug tool for GRUB filesystem drivers +-[SEE ALSO] +-.BR grub-probe (8) +diff --git a/docs/man/grub-glue-efi.h2m b/docs/man/grub-glue-efi.h2m +deleted file mode 100644 +index c1c6ded49ff..00000000000 +--- a/docs/man/grub-glue-efi.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-glue-efi \- generate a fat binary for EFI +-[DESCRIPTION] +-grub-glue-efi processes ia32 and amd64 EFI images and glues them according to Apple format. +diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m +deleted file mode 100644 +index 8cbbc87a0f2..00000000000 +--- a/docs/man/grub-install.h2m ++++ /dev/null +@@ -1,6 +0,0 @@ +-[NAME] +-grub-install \- install GRUB to a device +-[SEE ALSO] +-.BR grub-mkconfig (8), +-.BR grub-mkimage (1), +-.BR grub-mkrescue (1) +diff --git a/docs/man/grub-kbdcomp.h2m b/docs/man/grub-kbdcomp.h2m +deleted file mode 100644 +index d81f9157e01..00000000000 +--- a/docs/man/grub-kbdcomp.h2m ++++ /dev/null +@@ -1,10 +0,0 @@ +-[NAME] +-grub-kbdcomp \- generate a GRUB keyboard layout file +-[DESCRIPTION] +-grub-kbdcomp processes a X keyboard layout description in +-.BR keymaps (5) +-format into a format that can be used by GRUB's +-.B keymap +-command. +-[SEE ALSO] +-.BR grub-mklayout (8) +diff --git a/docs/man/grub-macbless.h2m b/docs/man/grub-macbless.h2m +deleted file mode 100644 +index 0197c0087d7..00000000000 +--- a/docs/man/grub-macbless.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-macbless \- bless a mac file/directory +-[SEE ALSO] +-.BR grub-install (1) +diff --git a/docs/man/grub-macho2img.h2m b/docs/man/grub-macho2img.h2m +deleted file mode 100644 +index d79aaeed8f9..00000000000 +--- a/docs/man/grub-macho2img.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-macho2img \- convert Mach-O to raw image +-[SEE ALSO] +-.BR grub-mkimage (1) +diff --git a/docs/man/grub-menulst2cfg.h2m b/docs/man/grub-menulst2cfg.h2m +deleted file mode 100644 +index c2e0055ed7e..00000000000 +--- a/docs/man/grub-menulst2cfg.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-menulst2cfg \- transform legacy menu.lst into grub.cfg +-[SEE ALSO] +-.BR grub-mkconfig (8) +diff --git a/docs/man/grub-mkconfig.h2m b/docs/man/grub-mkconfig.h2m +deleted file mode 100644 +index 9b42f813010..00000000000 +--- a/docs/man/grub-mkconfig.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-mkconfig \- generate a GRUB configuration file +-[SEE ALSO] +-.BR grub-install (8) +diff --git a/docs/man/grub-mkfont.h2m b/docs/man/grub-mkfont.h2m +deleted file mode 100644 +index d46fe600eca..00000000000 +--- a/docs/man/grub-mkfont.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-mkfont \- make GRUB font files +-[SEE ALSO] +-.BR grub-mkconfig (8) +diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m +deleted file mode 100644 +index f0fbc2bb197..00000000000 +--- a/docs/man/grub-mkimage.h2m ++++ /dev/null +@@ -1,6 +0,0 @@ +-[NAME] +-grub-mkimage \- make a bootable image of GRUB +-[SEE ALSO] +-.BR grub-install (8), +-.BR grub-mkrescue (1), +-.BR grub-mknetdir (8) +diff --git a/docs/man/grub-mklayout.h2m b/docs/man/grub-mklayout.h2m +deleted file mode 100644 +index 1e43409c0ab..00000000000 +--- a/docs/man/grub-mklayout.h2m ++++ /dev/null +@@ -1,10 +0,0 @@ +-[NAME] +-grub-mklayout \- generate a GRUB keyboard layout file +-[DESCRIPTION] +-grub-mklayout processes a keyboard layout description in +-.BR keymaps (5) +-format into a format that can be used by GRUB's +-.B keymap +-command. +-[SEE ALSO] +-.BR grub-mkconfig (8) +diff --git a/docs/man/grub-mknetdir.h2m b/docs/man/grub-mknetdir.h2m +deleted file mode 100644 +index a2ef13ec111..00000000000 +--- a/docs/man/grub-mknetdir.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-mknetdir \- prepare a GRUB netboot directory. +-[SEE ALSO] +-.BR grub-mkimage (1) +diff --git a/docs/man/grub-mkpasswd-pbkdf2.h2m b/docs/man/grub-mkpasswd-pbkdf2.h2m +deleted file mode 100644 +index 4d202f3da7e..00000000000 +--- a/docs/man/grub-mkpasswd-pbkdf2.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB +-[SEE ALSO] +-.BR grub-mkconfig (8) +diff --git a/docs/man/grub-mkrelpath.h2m b/docs/man/grub-mkrelpath.h2m +deleted file mode 100644 +index d01f3961e3f..00000000000 +--- a/docs/man/grub-mkrelpath.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-mkrelpath \- make a system path relative to its root +-[SEE ALSO] +-.BR grub-probe (8) +diff --git a/docs/man/grub-mkrescue.h2m b/docs/man/grub-mkrescue.h2m +deleted file mode 100644 +index a427f02e3c6..00000000000 +--- a/docs/man/grub-mkrescue.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-mkrescue \- make a GRUB rescue image +-[SEE ALSO] +-.BR grub-mkimage (1) +diff --git a/docs/man/grub-mkstandalone.h2m b/docs/man/grub-mkstandalone.h2m +deleted file mode 100644 +index c77313978ad..00000000000 +--- a/docs/man/grub-mkstandalone.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-mkstandalone \- make a memdisk-based GRUB image +-[SEE ALSO] +-.BR grub-mkimage (1) +diff --git a/docs/man/grub-mount.h2m b/docs/man/grub-mount.h2m +deleted file mode 100644 +index 8d168982d72..00000000000 +--- a/docs/man/grub-mount.h2m ++++ /dev/null +@@ -1,2 +0,0 @@ +-[NAME] +-grub-mount \- export GRUB filesystem with FUSE +diff --git a/docs/man/grub-ofpathname.h2m b/docs/man/grub-ofpathname.h2m +deleted file mode 100644 +index 74b43eea039..00000000000 +--- a/docs/man/grub-ofpathname.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-ofpathname \- find OpenBOOT path for a device +-[SEE ALSO] +-.BR grub-probe (8) +diff --git a/docs/man/grub-pe2elf.h2m b/docs/man/grub-pe2elf.h2m +deleted file mode 100644 +index 7ca29bd703c..00000000000 +--- a/docs/man/grub-pe2elf.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-pe2elf \- convert PE image to ELF +-[SEE ALSO] +-.BR grub-mkimage (1) +diff --git a/docs/man/grub-probe.h2m b/docs/man/grub-probe.h2m +deleted file mode 100644 +index 6e1ffdcf937..00000000000 +--- a/docs/man/grub-probe.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-probe \- probe device information for GRUB +-[SEE ALSO] +-.BR grub-fstest (1) +diff --git a/docs/man/grub-reboot.h2m b/docs/man/grub-reboot.h2m +deleted file mode 100644 +index e4acace65ce..00000000000 +--- a/docs/man/grub-reboot.h2m ++++ /dev/null +@@ -1,5 +0,0 @@ +-[NAME] +-grub-reboot \- set the default boot entry for GRUB, for the next boot only +-[SEE ALSO] +-.BR grub-set-default (8), +-.BR grub-editenv (1) +diff --git a/docs/man/grub-render-label.h2m b/docs/man/grub-render-label.h2m +deleted file mode 100644 +index 50ae5247c05..00000000000 +--- a/docs/man/grub-render-label.h2m ++++ /dev/null +@@ -1,3 +0,0 @@ +-[NAME] +-grub-render-label \- generate a .disk_label for Apple Macs. +- +diff --git a/docs/man/grub-script-check.h2m b/docs/man/grub-script-check.h2m +deleted file mode 100644 +index 3653682671a..00000000000 +--- a/docs/man/grub-script-check.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-script-check \- check grub.cfg for syntax errors +-[SEE ALSO] +-.BR grub-mkconfig (8) +diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m +deleted file mode 100644 +index 7945001c154..00000000000 +--- a/docs/man/grub-set-default.h2m ++++ /dev/null +@@ -1,5 +0,0 @@ +-[NAME] +-grub-set-default \- set the saved default boot entry for GRUB +-[SEE ALSO] +-.BR grub-reboot (8), +-.BR grub-editenv (1) +diff --git a/docs/man/grub-sparc64-setup.h2m b/docs/man/grub-sparc64-setup.h2m +deleted file mode 100644 +index 18f803a50db..00000000000 +--- a/docs/man/grub-sparc64-setup.h2m ++++ /dev/null +@@ -1,6 +0,0 @@ +-[NAME] +-grub-sparc64-setup \- set up a device to boot using GRUB +-[SEE ALSO] +-.BR grub-install (8), +-.BR grub-mkimage (1), +-.BR grub-mkrescue (1) +diff --git a/docs/man/grub-syslinux2cfg.h2m b/docs/man/grub-syslinux2cfg.h2m +deleted file mode 100644 +index ad25c8ab753..00000000000 +--- a/docs/man/grub-syslinux2cfg.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-syslinux2cfg \- transform syslinux config into grub.cfg +-[SEE ALSO] +-.BR grub-menulst2cfg (8) +diff --git a/gentpl.py b/gentpl.py +index c86550d4f9e..2cba0bbbd6f 100644 +--- a/gentpl.py ++++ b/gentpl.py +@@ -805,10 +805,7 @@ def manpage(defn, adddeps): + + output("if COND_MAN_PAGES\n") + gvar_add("man_MANS", name + "." + mansection) +- rule(name + "." + mansection, name + " " + adddeps, """ +-chmod a+x """ + name + """ +-PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=""" + mansection + """ -i $(top_srcdir)/docs/man/""" + name + """.h2m -o $@ """ + name + """ +-""") ++ rule(name + "." + mansection, name + " " + adddeps, "cat $(top_srcdir)/util/" + name + "." + mansection + " | $(top_builddir)/config.status --file=$@:-") + gvar_add("CLEANFILES", name + "." + mansection) + output("endif\n") + +diff --git a/util/grub-bios-setup.8 b/util/grub-bios-setup.8 +new file mode 100644 +index 00000000000..56f582b3d75 +--- /dev/null ++++ b/util/grub-bios-setup.8 +@@ -0,0 +1,54 @@ ++.TH GRUB-BIOS-SETUP 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-bios-setup\fR \(em Set up images to boot from a device. ++ ++.SH SYNOPSIS ++\fBgrub-bios-setup\fR [-a | --allow-floppy] [-b | --boot-image=\fIFILE\fR] ++.RS 17 ++[-c | --core-image=\fIFILE\fR] [-d | --directory=\fIDIR\fR] ++.RE ++.RS 17 ++[-f | --force] [-m | --device-map=\fIFILE\fR] ++.RE ++.RS 17 ++[-s | --skip-fs-probe] [-v | --verbose] \fIDEVICE\fR ++ ++.SH DESCRIPTION ++You should not normally run this program directly. Use grub-install instead. ++ ++.SH OPTIONS ++.TP ++\fB--allow-floppy\fR ++Make the device also bootable as a floppy. This option is the default for ++/dev/fdX devices. Some BIOSes will not boot images created with this option. ++ ++.TP ++\fB--boot-image\fR=\fIFILE\fR ++Use FILE as the boot image. The default value is \fBboot.img\fR. ++ ++.TP ++\fB--core-image\fR=\fIFILE\fR ++Use FILE as ther core image. The default value is \fBcore.img\fR. ++ ++.TP ++\fB--directory\fR=\fIDIR\fR ++Use GRUB files in the directory DIR. The default value is \fB/boot/grub\fR. ++ ++.TP ++\fB--force\fR ++Install even if problems are detected. ++ ++.TP ++\fB--device-map\fR=\fIFILE\fR ++Use FILE as the device map. The default value is /boot/grub/device.map . ++ ++.TP ++\fB--skip-fs-probe\fR ++Do not probe DEVICE for filesystems. ++ ++.TP ++\fB--verbose\fR ++Print verbose messages. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-editenv.1 b/util/grub-editenv.1 +new file mode 100644 +index 00000000000..d28ba03ba42 +--- /dev/null ++++ b/util/grub-editenv.1 +@@ -0,0 +1,46 @@ ++.TH GRUB-EDITENV 1 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-editenv\fR \(em Manage the GRUB environment block. ++ ++.SH SYNOPSIS ++\fBgrub-editenv\fR [-v | --verbose] [\fIFILE\fR] ++.RS 14 ++ ++ ++.SH DESCRIPTION ++\fBgrub-editenv\fR is a command line tool to manage GRUB's stored environment. ++ ++.SH OPTIONS ++.TP ++\fB--verbose\fR ++Print verbose messages. ++ ++.TP ++\fBFILE\fR ++.RS 7 ++File name to use for grub environment. Default is /boot/grub/grubenv . ++.RE ++ ++.SH COMMANDS ++.TP ++\fBcreate\fR ++.RS 7 ++Create a blank environment block file. ++.RE ++ ++.TP ++\fBlist\fR ++.RS 7 ++List the current variables. ++.RE ++ ++.TP ++\fBset\fR [\fINAME\fR=\fIVALUE\fR ...] ++Set variables. ++ ++.TP ++\fBunset [\fINAME\fR ...] ++Delete variables. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-file.1 b/util/grub-file.1 +new file mode 100644 +index 00000000000..b29cb327889 +--- /dev/null ++++ b/util/grub-file.1 +@@ -0,0 +1,165 @@ ++.TH GRUB-FILE 1 "Web Feb 26 2014" ++.SH NAME ++\fBgrub-file\fR \(em Check if FILE is of specified type. ++ ++.SH SYNOPSIS ++\fBgrub-file\fR (--is-i386-xen-pae-domu | --is-x86_64-xen-domu | ++.RS 11 ++--is-x86-xen-dom0 | --is-x86-multiboot | ++.RE ++.RS 11 ++--is-x86-multiboot2 | --is-arm-linux | --is-arm64-linux | ++.RE ++.RS 11 ++--is-ia64-linux | --is-mips-linux | --is-mipsel-linux | ++.RE ++.RS 11 ++--is-sparc64-linux | --is-powerpc-linux | --is-x86-linux | ++.RE ++.RS 11 ++--is-x86-linux32 | --is-x86-kfreebsd | --is-i386-kfreebsd | ++.RE ++.RS 11 ++--is-x86_64-kfreebsd | --is-x86-knetbsd | ++.RE ++.RS 11 ++--is-i386-knetbsd | --is-x86_64-knetbsd | --is-i386-efi | ++.RE ++.RS 11 ++--is-x86_64-efi | --is-ia64-efi | --is-arm64-efi | ++.RE ++.RS 11 ++--is-arm-efi | --is-hibernated-hiberfil | --is-x86_64-xnu | ++.RE ++.RS 11 ++--is-i386-xnu | --is-xnu-hibr | --is-x86-bios-bootsector) ++.RE ++.RS 11 ++\fIFILE\fR ++ ++.SH DESCRIPTION ++\fBgrub-file\fR is used to check if \fIFILE\fR is of a specified type. ++ ++.SH OPTIONS ++.TP ++--is-i386-xen-pae-domu ++Check if FILE can be booted as i386 PAE Xen unprivileged guest kernel ++ ++.TP ++--is-x86_64-xen-domu ++Check if FILE can be booted as x86_64 Xen unprivileged guest kernel ++ ++.TP ++--is-x86-xen-dom0 ++Check if FILE can be used as Xen x86 privileged guest kernel ++ ++.TP ++--is-x86-multiboot ++Check if FILE can be used as x86 multiboot kernel ++ ++.TP ++--is-x86-multiboot2 ++Check if FILE can be used as x86 multiboot2 kernel ++ ++.TP ++--is-arm-linux ++Check if FILE is ARM Linux ++ ++.TP ++--is-arm64-linux ++Check if FILE is ARM64 Linux ++ ++.TP ++--is-ia64-linux ++Check if FILE is IA64 Linux ++ ++.TP ++--is-mips-linux ++Check if FILE is MIPS Linux ++ ++.TP ++--is-mipsel-linux ++Check if FILE is MIPSEL Linux ++ ++.TP ++--is-sparc64-linux ++Check if FILE is SPARC64 Linux ++ ++.TP ++--is-powerpc-linux ++Check if FILE is POWERPC Linux ++ ++.TP ++--is-x86-linux ++Check if FILE is x86 Linux ++ ++.TP ++--is-x86-linux32 ++Check if FILE is x86 Linux supporting 32-bit protocol ++ ++.TP ++--is-x86-kfreebsd ++Check if FILE is x86 kFreeBSD ++ ++.TP ++--is-i386-kfreebsd ++Check if FILE is i386 kFreeBSD ++ ++.TP ++--is-x86_64-kfreebsd ++Check if FILE is x86_64 kFreeBSD ++ ++.TP ++--is-x86-knetbsd ++Check if FILE is x86 kNetBSD ++ ++.TP ++--is-i386-knetbsd ++Check if FILE is i386 kNetBSD ++ ++.TP ++--is-x86_64-knetbsd ++Check if FILE is x86_64 kNetBSD ++ ++.TP ++--is-i386-efi ++Check if FILE is i386 EFI file ++ ++.TP ++--is-x86_64-efi ++Check if FILE is x86_64 EFI file ++ ++.TP ++--is-ia64-efi ++Check if FILE is IA64 EFI file ++ ++.TP ++--is-arm64-efi ++Check if FILE is ARM64 EFI file ++ ++.TP ++--is-arm-efi ++Check if FILE is ARM EFI file ++ ++.TP ++--is-hibernated-hiberfil ++Check if FILE is hiberfil.sys in hibernated state ++ ++.TP ++--is-x86_64-xnu ++Check if FILE is x86_64 XNU (Mac OS X kernel) ++ ++.TP ++--is-i386-xnu ++Check if FILE is i386 XNU (Mac OS X kernel) ++ ++.TP ++--is-xnu-hibr ++Check if FILE is XNU (Mac OS X kernel) hibernated image ++ ++.TP ++--is-x86-bios-bootsector ++Check if FILE is BIOS bootsector ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-fstest.1 b/util/grub-fstest.1 +new file mode 100644 +index 00000000000..792fa78634c +--- /dev/null ++++ b/util/grub-fstest.1 +@@ -0,0 +1,99 @@ ++.TH GRUB-FSTEST 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-fstest\fR — Debug tool for GRUB's filesystem driver. ++ ++.SH SYNOPSIS ++\fBgrub-fstest\fR [-c | --diskcount=\fINUM\fR] [-C | --crypto] ++.RS 13 ++[-d | --debug=\fISTRING\fR] [-K | --zfs-key=\fIFILE\fR|\fIprompt\fR] ++.RE ++.RS 13 ++[-n | --length=\fINUM\fR] [-r | --root=\fIDEVICE_NAME\fR] ++.RE ++.RS 13 ++[-s | --skip=\fINUM\fR] [-u | --uncompress] [-v | --verbose] ++.RE ++.RS 13 ++\fIIMAGE_PATH\fR ++ ++.SH DESCRIPTION ++\fBgrub-fstest\fR is a tool for testing GRUB's filesystem drivers. You should not normally need to run this program. ++ ++.SH OPTIONS ++.TP ++\fB--diskcount\fR=\fINUM\fR ++Specify the number of input files. ++ ++.TP ++\fB--crypto\fR ++Mount cryptographic devices. ++ ++.TP ++\fB--debug\fR=\fISTRING\fR ++Set debug environment variable. ++ ++.TP ++\fB--zfs-key\fR=\fIFILE\fR|\fIprompt\fR ++Load ZFS cryptographic key. ++ ++.TP ++\fB--length\fR=\fINUM\fR ++Handle NUM bytes in output file. ++ ++.TP ++\fB--root\fR=\fIDEVICE_NAME\fR ++Set root device. ++ ++.TP ++\fB--skip\fR=\fINUM\fR ++Skip NUM bytes from output file. ++ ++.TP ++\fB--uncompress\fR ++Uncompress data. ++ ++.TP ++\fB--verbose\fR ++Print verbose messages. ++ ++.SH COMMANDS ++.TP ++\fBblocklist\fR \fIFILE\fR ++Display block list of \fIFILE\fR. ++ ++.TP ++\fBcat\fR \fIFILE\fR ++Display \fIFILE\fR on standard output. ++ ++.TP ++\fBcmp\fR \fIFILE\fR \fILOCAL\fR ++Compare \fIFILE\fR with local file \fILOCAL\fR. ++ ++.TP ++\fBcp\fR \fIFILE\fR \fILOCAL\fR ++Copy \fIFILE\fR to local file \fILOCAL\fR. ++ ++.TP ++\fBcrc\fR \fIFILE\fR ++Display the CRC-32 checksum of \fIFILE\fR. ++ ++.TP ++\fBhex\fR \fIFILE\fR ++Display contents of \fIFILE\fR in hexidecimal. ++ ++.TP ++\fBls\fR \fIPATH\fR ++List files at \fIPATH\fR. ++ ++.TP ++\fBxnu_uuid\fR \fIDEVICE\fR ++Display the XNU UUID of \fIDEVICE\fR. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-glue-efi.1 b/util/grub-glue-efi.1 +new file mode 100644 +index 00000000000..72bd555d577 +--- /dev/null ++++ b/util/grub-glue-efi.1 +@@ -0,0 +1,31 @@ ++.TH GRUB-GLUE-EFI 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-glue-efi\fR \(em Create an Apple fat EFI binary. ++ ++.SH SYNOPSIS ++\fBgrub-glue-efi\fR <-3 | --input32=\fIFILE\fR> <-6 | --input64=\fIFILE\fR> ++.RS 15 ++<-o | --output=\fIFILE\fR> [-v | --verbose] ++ ++.SH DESCRIPTION ++\fBgrub-glue-efi\fR creates an Apple fat EFI binary from two EFI binaries. ++ ++.SH OPTIONS ++.TP ++\fB--input32\fR=\fIFILE\fR ++Read 32-bit binary from \fIFILE\fR. ++ ++.TP ++\fB--input64\fR=\fIFILE\fR ++Read 64-bit binary from \fIFILE\fR. ++ ++.TP ++\fB--output\fR=\fIFILE\fR ++Write resulting fat binary to \fIFILE\fR. ++ ++.TP ++\fB--verbose\fR ++Print verbose messages. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-install.8 b/util/grub-install.8 +new file mode 100644 +index 00000000000..1db89e94b3b +--- /dev/null ++++ b/util/grub-install.8 +@@ -0,0 +1,128 @@ ++.TH GRUB-INSTALL 1 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-install\fR \(em Install GRUB on a device. ++ ++.SH SYNOPSIS ++\fBgrub-install\fR [--modules=\fIMODULES\fR] [--install-modules=\fIMODULES\fR] ++.RS 14 ++[--themes=\fITHEMES\fR] [--fonts=\fIFONTS\fR] [--locales=\fILOCALES\fR] ++.RE ++.RS 14 ++[--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR]] [-d | --directory=\fIDIR\fR] ++.RE ++.RS 14 ++[--grub-mkimage=\fIFILE\fR] [--boot-directory=\fIDIR\fR] ++.RE ++.RS 14 ++[--target=\fITARGET\fR] [--grub-setup=\fIFILE\fR] ++.RE ++.RS 14 ++[--grub-mkrelpath=\fIFILE\fR] [--grub-probe=\fIFILE\fR] ++.RE ++.RS 14 ++[--allow-floppy] [--recheck] [--force] [--force-file-id] ++.RE ++.RS 14 ++[--disk-module=\fIMODULE\fR] [--no-nvram] [--removable] ++.RE ++.RS 14 ++[--bootloader-id=\fIID\fR] [--efi-directory=\fIDIR\fR] \fIINSTALL_DEVICE\fR ++ ++.SH DESCRIPTION ++\fBgrub-install\fR installs GRUB onto a device. This includes copying GRUB images into the target directory (generally \fI/boot/grub\fR), and on some platforms may also include installing GRUB onto a boot sector. ++ ++.SH OPTIONS ++.TP ++\fB--modules\fR=\fIMODULES\fR\! ++Pre-load modules specified by \fIMODULES\fR. ++ ++.TP ++\fB--install-modules\fR=\fIMODULES\fR ++Install only \fIMODULES\fR and their dependencies. The default is to install all available modules. ++ ++.TP ++\fB--themes\fR=\fITHEMES\fR ++Install \fITHEMES\fR. The default is to install the \fIstarfield\fR theme, if available. ++ ++.TP ++\fB--fonts\fR=\fIFONTS\fR ++Install \fIFONTS\fR. The default is to install the \fIunicode\fR font. ++ ++.TP ++\fB--locales\fR=\fILOCALES\fR ++Install only locales listed in \fILOCALES\fR. The default is to install all available locales. ++ ++.TP ++\fB--compress\fR=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR ++Compress GRUB files using the specified compression algorithm. ++ ++.TP ++\fB--directory\fR=\fIDIR\fR ++Use images and modules in \fIDIR\fR. ++ ++.TP ++\fB--grub-mkimage\fR=\fIFILE\fR ++Use \fIFILE\fR as \fBgrub-mkimage\fR. The default is \fI/usr/bin/grub-mkimage\fR. ++ ++.TP ++\fB--boot-directory\fR=\fIDIR\fR ++Use \fIDIR\fR as the boot directory. The default is \fI/boot\fR. GRUB will put its files in a subdirectory of this directory named \fIgrub\fR. ++ ++.TP ++\fB--target\fR=\fITARGET\fR ++Install GRUB for \fITARGET\fR platform. The default is the platform \fBgrub-install\fR is running on. ++ ++.TP ++\fB--grub-setup\fR=\fIFILE\fR ++Use \fIFILE\fR as \fBgrub-setup\fR. The default is \fI/usr/bin/grub-setup\fR. ++ ++.TP ++\fB--grub-mkrelpath\fR=\fIFILE\fR ++Use \fIFILE\fR as \fBgrub-mkrelpath\fR. The default is \fI/usr/bin/grub-mkrelpath\fR. ++ ++.TP ++\fB--grub-probe\fR=\fIFILE\fR ++Use \fIFILE\fR as \fBgrub-probe\fR. The default is \fI/usr/bin/grub-mkrelpath\fR. ++ ++.TP ++\fB--allow-floppy ++Make the device also bootable as a floppy. This option is the default for /dev/fdX devices. Some BIOSes will not boot images created with this option. ++ ++.TP ++\fB--recheck ++Delete any existing device map and create a new one if necessary. ++ ++.TP ++\fB--force ++Install even if problems are detected. ++ ++.TP ++\fB--force-file-id ++Use identifier file even if UUID is available. ++ ++.TP ++\fB--disk-module\fR=\fIMODULE\fR ++Use \fIMODULE\fR for disk access. This allows you to manually specify either \fIbiosdisk\fR or \fInative\fR disk access. This option is only available on the BIOS target platform. ++ ++.TP ++\fB--no-nvram ++Do not update the \fIboot-device\fR NVRAM variable. This option is only available on IEEE1275 target platforms. ++ ++.TP ++\fB--removable ++Treat the target device as if it is removeable. This option is only available on the EFI target platform. ++ ++.TP ++\fB--bootloader-id\fR=\fIID\fR ++Use \fIID\fR as the bootloader ID. This option is only available on the EFI target platform. ++ ++.TP ++\fB--efi-directory\fR=\fIDIR\fR ++Use \fIDIR\fR as the EFI System Partition root. This option is only available on the EFI target platform. ++ ++.TP ++\fIINSTALL_DEVICE\fR ++Install GRUB to the block device \fIINSTALL_DEVICE\fR. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-kbdcomp.1 b/util/grub-kbdcomp.1 +new file mode 100644 +index 00000000000..0bb969a5b43 +--- /dev/null ++++ b/util/grub-kbdcomp.1 +@@ -0,0 +1,19 @@ ++.TH GRUB-KBDCOMP 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-kbdcomp\fR \(em Generate a GRUB keyboard layout file. ++ ++.SH SYNOPSIS ++\fBgrub-kbdcomp\fR <-o | --output=\fIFILE\fR> \fICKBMAP_ARGUMENTS\fR ++ ++.SH DESCRIPTION ++\fBgrub-kbdcomp\fR processes an X keyboard layout description in ++\fBkeymaps\fR(5) format into a format that can be used by GRUB's \fBkeymap\fR ++command. ++ ++.SH OPTIONS ++.TP ++\fB--output\fR=\fIFILE\fR ++Write output to \fIFILE\fR. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-macbless.1 b/util/grub-macbless.1 +new file mode 100644 +index 00000000000..41a96186f70 +--- /dev/null ++++ b/util/grub-macbless.1 +@@ -0,0 +1,22 @@ ++.TH GRUB-MACBLESS 1 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-macbless\fR \(em Mac-style bless on HFS or HFS+ ++ ++.SH SYNOPSIS ++\fBgrub-macbless\fR [-v | --verbose] [-p | --ppc] \fIFILE\fR | [-x | --x86] \fIFILE\fR ++ ++.SH OPTIONS ++.TP ++--x86 ++Bless for x86 based Macs. ++ ++.TP ++--ppc ++Bless for PPC based Macs. ++ ++.TP ++--verbose ++Print verbose messages. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-menulst2cfg.1 b/util/grub-menulst2cfg.1 +new file mode 100644 +index 00000000000..91e2ef87113 +--- /dev/null ++++ b/util/grub-menulst2cfg.1 +@@ -0,0 +1,12 @@ ++.TH GRUB-MENULST2CFG 1 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-menulst2cfg\fR \(em Convert a configuration file from GRUB 0.xx to GRUB 2.xx format. ++ ++.SH SYNOPSIS ++\fBgrub-menulst2cfg\fR [\fIINFILE\fR [\fIOUTFILE\fR]] ++ ++.SH DESCRIPTION ++\fBgrub-menulst2cfg\fR converts a configuration file from GRUB 0.xx to the current format. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-mkconfig.8 b/util/grub-mkconfig.8 +new file mode 100644 +index 00000000000..a2d1f577b9b +--- /dev/null ++++ b/util/grub-mkconfig.8 +@@ -0,0 +1,17 @@ ++.TH GRUB-MKCONFIG 1 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-mkconfig\fR \(em Generate a GRUB configuration file. ++ ++.SH SYNOPSIS ++\fBgrub-mkconfig\fR [-o | --output=\fIFILE\fR] ++ ++.SH DESCRIPTION ++\fBgrub-mkconfig\fR generates a configuration file for GRUB. ++ ++.SH OPTIONS ++.TP ++\fB--output\fR=\fIFILE\fR ++Write generated output to \fIFILE\fR. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-mkfont.1 b/util/grub-mkfont.1 +new file mode 100644 +index 00000000000..3494857987d +--- /dev/null ++++ b/util/grub-mkfont.1 +@@ -0,0 +1,87 @@ ++.TH GRUB-MKFONT 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-mkfont\fR \(em Convert common font file formats into the PF2 format. ++ ++.SH SYNOPSIS ++\fBgrub-mkfont\fR [--ascii-bitmaps] [-a | --force-autohint] ++.RS 13 ++[-b | --bold] [-c | --asce=\fINUM\fR] [-d | --desc=\fINUM\fR] ++.RE ++.RS 13 ++[-i | --index=\fINUM\fR] [-n | --name=\fINAME\fR] [--no-bitmap] ++.RE ++.RS 13 ++[--no-hinting] <-o | --output=\fIFILE\fR> ++.RE ++.RS 13 ++[-r | --range=\fIFROM-TO\fR[\fI,FROM-TO\fR]] [-s | --size=\fISIZE\fR] ++.RE ++.RS 13 ++[-v | --verbose] [--width-spec] \fIFONT_FILES\fR ++ ++.SH DESCRIPTION ++\fBgrub-mkfont\fR converts font files from common formats into the PF2 format used by GRUB. ++ ++.SH OPTIONS ++.TP ++--ascii-bitmaps ++Save only bitmaps for ASCII characters. ++ ++.TP ++--force-autohint ++Force generation of automatic hinting. ++ ++.TP ++--bold ++Convert font to bold. ++ ++.TP ++--asce=\fINUM\fR ++Set font ascent to \fINUM\fR. ++ ++.TP ++--desc=\fINUM\fR ++Set font descent to \fINUM\fR. ++ ++.TP ++--index=\fINUM\fR ++Select face index \fINUM\fR. ++ ++.TP ++--name=\fINAME\fR ++Set font family to \fINAME\fR. ++ ++.TP ++--no-bitmap ++Ignore bitmap strikes when loading. ++ ++.TP ++--no-hinting ++Disable hinting. ++ ++.TP ++--output=\fIFILE\fR ++Save ouptut to \fIFILE\fR. This argument is required. ++ ++.TP ++--range=\fIFROM-TO\fR\fI,FROM-TO\fR ++Set the font ranges to each pair of \fIFROM\fR,\fITO\fR. ++ ++.TP ++--size=\fISIZE\fR ++Set font size to \fISIZE\fR. ++ ++.TP ++--verbose ++Print verbose messages. ++ ++.TP ++--width-spec ++Create a width summary file. ++ ++.TP ++\fIFONT_FILES\fR ++The input files to be converted. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-mkimage.1 b/util/grub-mkimage.1 +new file mode 100644 +index 00000000000..4dea4f54597 +--- /dev/null ++++ b/util/grub-mkimage.1 +@@ -0,0 +1,95 @@ ++.TH GRUB-MKIMAGE 1 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-mkimage\fR \(em Make a bootable GRUB image. ++ ++.SH SYNOPSIS ++\fBgrub-mkimage\fR [-c | --config=\fRFILE\fI] [-C | --compression=(\fIxz\fR,\fInone\fR,\fIauto\fR)] ++.RS 14 ++[-d | --directory=\fRDIR\fR] [-k | --pubkey=\fIFILE\fR] ++.RE ++.RS 14 ++[-m | --memdisk=\fIFILE\fR] [-n | --note] [-o | --output=\fIFILE\fR] ++.RE ++.RS 14 ++[-O | --format=\fIFORMAT\fR] [-p | --prefix=\fIDIR\fR] ++.RE ++.RS 14 ++[-v | --verbose] \fIMODULES\fR ++ ++.SH DESCRIPTION ++\fBgrub-mkimage\fI builds a bootable image of GRUB. ++ ++.SH OPTIONS ++.TP ++--config=\fIFILE\fR ++Embed \fIFILE\fR as the image's initial configuration file. ++ ++.TP ++--compression=(\fIxz\fR,\fInone\fR,\fIauto\fR) ++Use one of \fIxz\fR, \fInone\fR, or \fIauto\fR as the compression method for the core image. ++ ++.TP ++--directory=\fIDIR\fR ++Use images and modules from \fIDIR\fR. The default value is \fB/usr/lib/grub/\fR. ++ ++.TP ++--pubkey=\fIFILE\fR ++Embed the public key \fIFILE\fR for signature checking. ++ ++.TP ++--memdisk=\fIFILE\fR ++Embed the memdisk image \fIFILE\fR. If no \fB-p\fR option is also specified, this implies \fI-p (memdisk)/boot/grub\fR. ++ ++.TP ++--note ++Add a CHRP \fINOTE\fR section. This option is only valid on IEEE1275 platforms. ++ ++.TP ++--output=\fIFILE\fR ++Write the generated file to \fIFILE\fR. The default is to write to standard output. ++ ++.TP ++--format=\fIFORMAT\fR ++Generate an image in the specified \fIFORMAT\fR. Valid values are: ++.RS ++.RS 4 ++.P ++i386-coreboot, ++i386-multiboot, ++i386-pc, ++i386-pc-pxe, ++i386-efi, ++i386-ieee1275, ++i386-qemu, ++x86_64-efi, ++mipsel-yeeloong-flash, ++mipsel-fuloong2f-flash, ++mipself-loongson-elf, ++powerpc-ieee1275, ++sparc64-ieee1275-raw, ++sparc64-ieee1275-cdcore, ++sparc64-ieee1275-aout, ++ia64-efi, ++mips-arc, ++mipsel-arc, ++mipsel-qemu_mips-elf, ++mips-qemu_mips-flash, ++mipsel-qemu_mips-flash, ++mips-qemu_mips-elf ++.RE ++.RE ++ ++.TP ++--prefix=\fIDIR\fR ++Set prefix directory. The default value is \fI/boot/grub\fR. ++ ++.TP ++--verbose ++Print verbose messages. ++ ++.TP ++\fIMODULES\fR ++Include \fIMODULES\fR. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-mklayout.1 b/util/grub-mklayout.1 +new file mode 100644 +index 00000000000..d1bbc2ec515 +--- /dev/null ++++ b/util/grub-mklayout.1 +@@ -0,0 +1,27 @@ ++.TH GRUB-MKLAYOUT 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-mklayout\fR \(em Generate a GRUB keyboard layout file. ++ ++.SH SYNOPSIS ++\fBgrub-mklayout\fR [-i | --input=\fIFILE\fR] [-o | --output=\fIFILE\fR] ++.RS 15 ++[-v | --verbose] ++ ++.SH DESCRIPTION ++\fBgrub-mklayout\fR generates a GRUB keyboard layout description which corresponds with the Linux console layout description given as input. ++ ++.SH OPTIONS ++.TP ++--input=\fIFILE\fR ++Use \fIFILE\fR as the input. The default value is the standard input device. ++ ++.TP ++--output=\fIFILE\fR ++Use \fIFILE\fR as the output. The default value is the standard output device. ++ ++.TP ++--verbose ++Print verbose messages. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-mknetdir.1 b/util/grub-mknetdir.1 +new file mode 100644 +index 00000000000..fa7e8d4ef0d +--- /dev/null ++++ b/util/grub-mknetdir.1 +@@ -0,0 +1,12 @@ ++.TH GRUB-MKNETDIR 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-mknetdir\fR \(em Prepare a GRUB netboot directory. ++ ++.SH SYNOPSIS ++\fBgrub-mknetdir\fR ++ ++.SH DESCRIPTION ++\fBgrub-mknetdir\fR prepares a directory for GRUB to be netbooted from. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-mkpasswd-pbkdf2.1 b/util/grub-mkpasswd-pbkdf2.1 +new file mode 100644 +index 00000000000..73c437c15d8 +--- /dev/null ++++ b/util/grub-mkpasswd-pbkdf2.1 +@@ -0,0 +1,27 @@ ++.TH GRUB-MKPASSWD-PBKDF2 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-mkpasswd-pbkdf2\fR \(em Generate a PBKDF2 password hash. ++ ++.SH SYNOPSIS ++\fBgrub-mkpasswd-pbkdf2\fR [-c | --iteration-count=\fINUM\fR] [-l | --buflen=\fINUM\fR] ++.RS 22 ++[-s | --salt=\fINUM\fR] ++ ++.SH DESCRIPTION ++\fBgrub-mkpasswd-pbkdf2\fR generates a PBKDF2 password string suitable for use in a GRUB configuration file. ++ ++.SH OPTIONS ++.TP ++--iteration-count=\fINUM\fR ++Number of PBKDF2 iterations. ++ ++.TP ++--buflen=\fINUM\fR ++Length of generated hash. ++ ++.TP ++--salt=\fINUM\fR ++Length of salt to use. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-mkrelpath.1 b/util/grub-mkrelpath.1 +new file mode 100644 +index 00000000000..85f1113621d +--- /dev/null ++++ b/util/grub-mkrelpath.1 +@@ -0,0 +1,12 @@ ++.TH GRUB-MKRELPATH 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-mkrelpath\fR \(em Generate a relative GRUB path given an OS path. ++ ++.SH SYNOPSIS ++\fBgrub-mkrelpath\fR \fIFILE\fR ++ ++.SH DESCRIPTION ++\fBgrub-mkrelpath\fR takes an OS filesystem path for \fIFILE\fR and returns a relative path suitable for use in a GRUB configuration file. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-mkrescue.1 b/util/grub-mkrescue.1 +new file mode 100644 +index 00000000000..4ed9fc723fd +--- /dev/null ++++ b/util/grub-mkrescue.1 +@@ -0,0 +1,123 @@ ++.TH GRUB-MKRESCUE 3 "Wed Feb 26 2014" ++.SH NAME ++grub-mkrescue \(em Generate a GRUB rescue image using GNU Xorriso. ++ ++.SH SYNOPSIS ++\fBgrub-mkrescue\fR [-o | --output=\fIFILE\fR] [--modules=\fIMODULES\fR] ++.RS 15 ++[--install-modules=\fIMODULES\fR] [--themes=\fITHEMES\fR] ++.RE ++.RS 15 ++[--fonts=\fIFONTS\fR] [--locales=\fILOCALES\fR] ++.RE ++.RS 15 ++[--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR]] [-d | --directory=\fIDIR\fR] ++.RE ++.RS 15 ++[--grub-mkimage=\fIFILE\fR] [--rom-directory=\fIDIR\fR] ++.RE ++.RS 15 ++[--xorriso=\fIFILE\fR] [--grub-glue-efi=\fIFILE\fR] ++.RE ++.RS 15 ++[--grub-render-label=\fIFILE\fR] [--label-font=\fIFILE\fR] ++.RE ++.RS 15 ++[--label-color=\fICOLOR\fR] [--label-bgcolor=\fIFILE\fR] ++.RE ++.RS 15 ++[--product-name=\fISTRING\fR] [--product-version=\fISTRING\fR] ++.RE ++.RS 15 ++[--sparc-boot] [--arcs-boot] ++ ++.SH DESCRIPTION ++\fBgrub-mkrescue\fR can be used to generate a rescue image with the GRUB bootloader. ++ ++.SH OPTIONS ++.TP ++\fB--output\fR=\fIFILE\fR ++Write the generated file to \fIFILE\fR. The default is to write to standard output. ++ ++.TP ++\fB--modules\fR=\fIMODULES\fR ++Pre-load modules specified by \fIMODULES\fR. ++ ++.TP ++\fB--install-modules\fR=\fIMODULES\fR ++Install only \fIMODULES\fR and their dependencies. The default is to install all available modules. ++ ++.TP ++\fB--themes\fR=\fITHEMES\fR ++Install \fITHEMES\fR. The default is to install the \fIstarfield\fR theme, if available. ++ ++.TP ++\fB--fonts\fR=\fIFONTS\fR ++Install \fIFONTS\fR. The default is to install the \fIunicode\fR font. ++ ++.TP ++\fB--locales\fR=\fILOCALES\fR ++Install only locales listed in \fILOCALES\fR. The default is to install all available locales. ++ ++.TP ++\fB--compress\fR[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR] ++Compress GRUB files using the specified compression algorithm. ++ ++.TP ++\fB--directory\fR=\fIDIR\fR ++Use images and modules in \fIDIR\fR. ++ ++.TP ++\fB--grub-mkimage\fR=\fIFILE\fR ++Use \fIFILE\fR as \fBgrub-mkimage\fR(1). The default is \fI/usr/bin/grub-mkimage\fR. ++ ++.TP ++\fB--rom-directory\fR=\fIDIR\fR ++Save ROM images in \fIDIR\fR. ++ ++.TP ++\fB--xorriso\fR=\fIFILE\fR ++Use \fIFILE\fR as \fBxorriso\fI. ++ ++.TP ++\fB--grub-glue-efi\fR=\fIFILE\fR ++Use \fIFILE\fR as \fBgrub-glue-efi\fR(3). ++ ++.TP ++\fB--grub-render-label\fR=\fIFILE\fR ++Use \fIFILE\fR as \fBgrub-render-label\fR(3). ++ ++.TP ++\fB--label-font\fR=\fIFILE\fR ++Use \fIFILE\fR as the font file for generated labels. ++ ++.TP ++\fB--label-color\fR=\fICOLOR\fR ++Use \fICOLOR\fI as the color for generated labels. ++ ++.TP ++\fB--label-bgcolor\fR=\fICOLOR\fR ++Use \fICOLOR\fR as the background color for generated labels. ++ ++.TP ++\fB--product-name\fR=\fISTRING\fR ++Use \fISTRING\fR as the product name in generated labels. ++ ++.TP ++\fB--product-version\fR=\fISTRING\fR ++Use \fISTRING\fR as the product version in generated labels. ++ ++.TP ++\fB--sparc-boot\fR ++Enable booting the SPARC platform. This disables HFS+, APM, ARCS, and "boot as disk image" on the \fIi386-pc\fR target platform. ++ ++.TP ++\fB--arcs-boot\fR ++Enable ARCS booting. This is typically for big-endian MIPS machines, and disables HFS+, APM, sparc64, and "boot as disk image" on the \fIi386-pc\fR target platform. ++ ++.TP ++\fB--\fR ++All options after a \fB--\fR will be passed directly to xorriso's command line when generating the image. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-mkstandalone.1 b/util/grub-mkstandalone.1 +new file mode 100644 +index 00000000000..ba2d2bdf279 +--- /dev/null ++++ b/util/grub-mkstandalone.1 +@@ -0,0 +1,100 @@ ++.TH GRUB-MKSTANDALONE 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-mkstandalone\fR \(em Generate a standalone image in the selected format. ++ ++.SH SYNOPSIS ++\fBgrub-mkstandalone\fR [-o | --output=\fIFILE\fR] [-O | --format=\fIFORMAT\fR] ++.RS 19 ++[-C | --compression=(\fIxz\fR|\fInone\fR|\fIauto\fR)] ++.RE ++.RS 19 ++[--modules=\fIMODULES\fR] [--install-modules=\fIMODULES\fR] ++.RE ++.RS 19 ++[--themes=\fITHEMES\fR] [--fonts=\fIFONTS\fR] ++.RE ++.RS 19 ++[--locales=\fILOCALES\fR] [--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR]] ++.RE ++.RS 19 ++[-d | --directory=\fIDIR\fR] [--grub-mkimage=\fIFILE\fR] ++.RE ++.RS 19 ++\fISOURCE...\fR ++ ++.SH DESCRIPTION ++ ++.SH OPTIONS ++.TP ++--output=\fIFILE\fR ++Write the generated file to \fIFILE\fR. The default is to write to standard output. ++ ++.TP ++--format=\fIFORMAT\fR ++Generate an image in the specified \fIFORMAT\fR. Valid values are: ++.RS ++.RS 4 ++.P ++i386-coreboot, ++i386-multiboot, ++i386-pc, ++i386-pc-pxe, ++i386-efi, ++i386-ieee1275, ++i386-qemu, ++x86_64-efi, ++mipsel-yeeloong-flash, ++mipsel-fuloong2f-flash, ++mipself-loongson-elf, ++powerpc-ieee1275, ++sparc64-ieee1275-raw, ++sparc64-ieee1275-cdcore, ++sparc64-ieee1275-aout, ++ia64-efi, ++mips-arc, ++mipsel-arc, ++mipsel-qemu_mips-elf, ++mips-qemu_mips-flash, ++mipsel-qemu_mips-flash, ++mips-qemu_mips-elf ++.RE ++.RE ++ ++.TP ++--compression=(\fIxz\fR|\fInone\fR|\fIauto\fR) ++Use one of \fIxz\fR, \fInone\fR, or \fIauto\fR as the compression method for the core image. ++ ++.TP ++--modules=\fIMODULES\fR ++Pre-load modules specified by \fIMODULES\fR. ++ ++.TP ++--install-modules=\fIMODULES\fR ++Install only \fIMODULES\fR and their dependencies. The default is to install all available modules. ++ ++.TP ++--themes=\fITHEMES\fR ++Install \fITHEMES\fR. The default is to install the \fIstarfield\fR theme, if available. ++ ++.TP ++--fonts=\fIFONTS\fR ++Install \fIFONTS\fR. The default is to install the \fIunicode\fR font. ++ ++.TP ++--locales=\fILOCALES\fR ++Install only locales listed in \fILOCALES\fR. The default is to install all available locales. ++ ++.TP ++--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR] ++Compress GRUB files using the specified compression algorithm. ++ ++.TP ++--directory=\fIDIR\fR ++Use images and modules in \fIDIR\fR. ++ ++.TP ++--grub-mkimage=\fIFILE\fR ++Use \fIFILE\fR as \fBgrub-mkimage\fR. The default is \fI/usr/bin/grub-mkimage\fR. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-ofpathname.8 b/util/grub-ofpathname.8 +new file mode 100644 +index 00000000000..bf3743aeba1 +--- /dev/null ++++ b/util/grub-ofpathname.8 +@@ -0,0 +1,12 @@ ++.TH GRUB-OFPATHNAME 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-ofpathname\fR \(em Generate an IEEE-1275 device path for a specified device. ++ ++.SH SYNOPSIS ++\fBgrub-ofpathname\fR \fIDEVICE\fR ++ ++.SH DESCRIPTION ++\fBgrub-ofpathname\fR generates an IEEE-1275 device path for the specified \fIDEVICE\fR. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-probe.8 b/util/grub-probe.8 +new file mode 100644 +index 00000000000..04e26c832bb +--- /dev/null ++++ b/util/grub-probe.8 +@@ -0,0 +1,80 @@ ++.TH GRUB-PROBE 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-probe\fR \(em Probe device information for a given path. ++ ++.SH SYNOPSIS ++\fBgrub-probe\fR \[-d | --device] [-m | --device-map=\fIFILE\fR] ++.RS 12 ++[-t | --target=(fs|fs_uuid|fs_label|drive|device|partmap| ++.RE ++.RS 28 ++abstraction|cryptodisk_uuid| ++.RE ++.RS 28 ++msdos_parttype)] ++.RE ++.RS 12 ++[-v | --verbose] (PATH|DEVICE) ++ ++.SH DESCRIPTION ++\fBgrub-probe\fR probes a path or device for filesystem and related information. ++ ++.SH OPTIONS ++.TP ++--device ++Final option represents a \fIDEVICE\fR, rather than a filesystem \fIPATH\fR. ++.TP ++--device-map=\fIFILE\fR ++Use \fIFILE\fR as the device map. The default value is \fI/boot/grub/device.map\fR. ++ ++.TP ++--target=(fs|fs_uuid|fs_label|drive|device|partmap|msdos_parttype) ++Select among various output definitions. The default is \fIfs\fR. ++.RS ++.TP ++\fIfs\fR ++filesystem module ++ ++.TP ++\fIfs_uuid\fR ++filesystem UUID ++ ++.TP ++\fIfs_label\fR ++filesystem label ++ ++.TP ++\fIdrive\fR ++GRUB drive name ++ ++.TP ++\fIdevice\fR ++System device ++ ++.TP ++\fIpartmap\fR ++partition map module ++ ++.TP ++\fIabstraction\fR ++abstraction module ++ ++.TP ++\fIcryptodisk_uuid\fR ++cryptographic container ++ ++.TP ++\fImsdos_partmap\fR ++MS-DOS partition map ++.RE ++ ++.TP ++--verbose ++Print verbose output. ++ ++.TP ++(\fIPATH\fR|\fIDEVICE\fR) ++If --device is passed, a block \fIDEVICE\fR. Otherwise, the \fIPATH\fR of a file on the filesystem. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-reboot.8 b/util/grub-reboot.8 +new file mode 100644 +index 00000000000..faa5e4eece2 +--- /dev/null ++++ b/util/grub-reboot.8 +@@ -0,0 +1,21 @@ ++.TH GRUB-REBOOT 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-reboot\fR \(em Set the default boot menu entry for the next boot only. ++ ++.SH SYNOPSIS ++\fBgrub-reboot\fR [--boot-directory=\fIDIR\fR] \fIMENU_ENTRY\fR ++ ++.SH DESCRIPTION ++\fBgrub-reboot\fR sets the default boot menu entry for the next boot, but not further boots after that. This command only works for GRUB configuration files created with \fIGRUB_DEFAULT=saved\fR in \fI/etc/default/grub\fR. ++ ++.SH OPTIONS ++.TP ++--boot-directory=\fIDIR\fR ++Find GRUB images under \fIDIR/grub\fR. The default value is \fI/boot\fR, resulting in grub images being search for at \fI/boot/grub\fR. ++ ++.TP ++\fIMENU_ENTRY\fR ++A number, a menu item title or a menu item identifier. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-render-label.1 b/util/grub-render-label.1 +new file mode 100644 +index 00000000000..4d51c8abf01 +--- /dev/null ++++ b/util/grub-render-label.1 +@@ -0,0 +1,51 @@ ++.TH GRUB-RENDER-LABEL 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-render-label\fR \(em Render an Apple disk label. ++ ++.SH SYNOPSIS ++\fBgrub-render-label\fR [-b | --bgcolor=\fICOLOR\fR] [-c | --color=\fICOLOR\fR] ++.RS 19 ++[-f | --font=\fIFILE\fR] [-i | --input=\fIFILE\fR] ++.RE ++.RS 19 ++[-o | --output=\fIFILE\fR] [-t | --text=\fISTRING\fR] ++.RE ++.RS 19 ++[-v | --verbose] ++ ++.SH DESCRIPTION ++\fBgrub-render-label\fR renders an Apple disk label (.disk_label) file. ++ ++ ++.SH OPTIONS ++.TP ++\fB--color\fR=\fICOLOR\fR ++Use \fICOLOR\fI as the color for generated labels. ++ ++.TP ++\fB--bgcolor\fR=\fICOLOR\fR ++Use \fICOLOR\fR as the background color for generated labels. ++ ++.TP ++\fB--font\fR=\fIFILE\fR ++Use \fIFILE\fR as the font file for generated labels. ++ ++.TP ++--input=\fIFILE\fR ++Read input text from \fIFILE\fR. ++ ++.TP ++--output=\fIFILE\fR ++Render output to \fIFILE\fR. ++ ++.TP ++--text=\fISTRING\fR ++Use \fISTRING\fR as input text. ++ ++.TP ++--verbose ++Print verbose output. ++ ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-script-check.1 b/util/grub-script-check.1 +new file mode 100644 +index 00000000000..0f1f625b05d +--- /dev/null ++++ b/util/grub-script-check.1 +@@ -0,0 +1,21 @@ ++.TH GRUB-SCRIPT-CHECK 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-script-check\fR \(em Check GRUB configuration file for syntax errors. ++ ++.SH SYNOPSIS ++\fBgrub-script-check\fR [-v | --verbose] \fIPATH\fR ++ ++.SH DESCRIPTION ++\fBgrub-script-check\fR verifies that a specified GRUB configuration file does not contain syntax errors. ++ ++.SH OPTIONS ++.TP ++--verbose ++Print verbose output. ++ ++.TP ++\fIPATH\fR ++Path of the file to use as input. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-set-default.8 b/util/grub-set-default.8 +new file mode 100644 +index 00000000000..a96265a1509 +--- /dev/null ++++ b/util/grub-set-default.8 +@@ -0,0 +1,21 @@ ++.TH GRUB-SET-DEFAULT 1 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-set-default\fR \(em Set the default boot menu entry for GRUB. ++ ++.SH SYNOPSIS ++\fBgrub-set-default\fR [--boot-directory=\fIDIR\fR] \fIMENU_ENTRY\fR ++ ++.SH DESCRIPTION ++\fBgrub-set-default\fR sets the default boot menu entry for all subsequent boots. This command only works for GRUB configuration files created with \fIGRUB_DEFAULT=saved\fR in \fI/etc/default/grub\fR. ++ ++.SH OPTIONS ++.TP ++--boot-directory=\fIDIR\fR ++Find GRUB images under \fIDIR/grub\fR. The default value is \fI/boot\fR, resulting in grub images being search for at \fI/boot/grub\fR. ++ ++.TP ++\fIMENU_ENTRY\fR ++A number, a menu item title or a menu item identifier. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-sparc64-setup.8 b/util/grub-sparc64-setup.8 +new file mode 100644 +index 00000000000..37ea2dd5eaa +--- /dev/null ++++ b/util/grub-sparc64-setup.8 +@@ -0,0 +1,12 @@ ++.TH GRUB-SPARC64-SETUP 3 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-sparc64-setup\fR \(em Set up a device to boot a sparc64 GRUB image. ++ ++.SH SYNOPSIS ++\fBgrub-sparc64-setup\fR [OPTIONS]. ++ ++.SH DESCRIPTION ++You should not normally run this program directly. Use grub-install instead. ++ ++.SH SEE ALSO ++.BR "info grub" diff --git a/0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch b/0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch new file mode 100644 index 0000000..ea396fc --- /dev/null +++ b/0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch @@ -0,0 +1,296 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 23 Jun 2016 11:01:39 -0400 +Subject: [PATCH] Add grub-get-kernel-settings and use it in 10_linux + +This patch adds grub-get-kernel-settings, which reads the system kernel +installation configuration from /etc/sysconfig/kernel, and outputs +${GRUB_...} variables suitable for evaluation by grub-mkconfig. Those +variables are then used by 10_linux to choose whether or not to create +debug stanzas. + +Resolves: rhbz#1226325 +--- + configure.ac | 2 + + Makefile.util.def | 7 ++ + util/bash-completion.d/grub-completion.bash.in | 22 +++++++ + util/grub-get-kernel-settings.3 | 20 ++++++ + util/grub-get-kernel-settings.in | 88 ++++++++++++++++++++++++++ + util/grub-mkconfig.in | 3 + + util/grub.d/10_linux.in | 23 +++++-- + 7 files changed, 160 insertions(+), 5 deletions(-) + create mode 100644 util/grub-get-kernel-settings.3 + create mode 100644 util/grub-get-kernel-settings.in + +diff --git a/configure.ac b/configure.ac +index 25e1abb59b9..58e57a745fa 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -65,6 +65,7 @@ grub_TRANSFORM([grub-install]) + grub_TRANSFORM([grub-mkconfig]) + grub_TRANSFORM([grub-mkfont]) + grub_TRANSFORM([grub-mkimage]) ++grub_TRANSFORM([grub-get-kernel-settings]) + grub_TRANSFORM([grub-glue-efi]) + grub_TRANSFORM([grub-mklayout]) + grub_TRANSFORM([grub-mkpasswd-pbkdf2]) +@@ -82,6 +83,7 @@ grub_TRANSFORM([grub-file]) + grub_TRANSFORM([grub-bios-setup.3]) + grub_TRANSFORM([grub-editenv.1]) + grub_TRANSFORM([grub-fstest.3]) ++grub_TRANSFORM([grub-get-kernel-settings.3]) + grub_TRANSFORM([grub-glue-efi.3]) + grub_TRANSFORM([grub-install.1]) + grub_TRANSFORM([grub-kbdcomp.3]) +diff --git a/Makefile.util.def b/Makefile.util.def +index 8ca4c14f0b9..43a1c7453b1 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -733,6 +733,13 @@ script = { + installdir = sbin; + }; + ++script = { ++ name = grub-get-kernel-settings; ++ common = util/grub-get-kernel-settings.in; ++ mansection = 3; ++ installdir = sbin; ++}; ++ + script = { + name = grub-set-default; + common = util/grub-set-default.in; +diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in +index 44bf135b9f8..5c4acd496d4 100644 +--- a/util/bash-completion.d/grub-completion.bash.in ++++ b/util/bash-completion.d/grub-completion.bash.in +@@ -264,6 +264,28 @@ have ${__grub_sparc64_setup_program} && \ + unset __grub_sparc64_setup_program + + ++# ++# grub-get-kernel-settings ++# ++_grub_get_kernel_settings () { ++ local cur ++ ++ COMPREPLY=() ++ cur=`_get_cword` ++ ++ if [[ "$cur" == -* ]]; then ++ __grubcomp "$(__grub_get_options_from_help)" ++ else ++ # Default complete with a filename ++ _filedir ++ fi ++} ++__grub_get_kernel_settings_program="@grub_get_kernel_settings@" ++have ${__grub_get_kernel_settings_program} && \ ++ complete -F _grub_get_kernel_settings -o filenames ${__grub_get_kernel_settings_program} ++unset __grub_get_kernel_settings_program ++ ++ + # + # grub-install + # +diff --git a/util/grub-get-kernel-settings.3 b/util/grub-get-kernel-settings.3 +new file mode 100644 +index 00000000000..ba33330e28d +--- /dev/null ++++ b/util/grub-get-kernel-settings.3 +@@ -0,0 +1,20 @@ ++.TH GRUB-GET-KERNEL-SETTINGS 3 "Thu Jun 25 2015" ++.SH NAME ++\fBgrub-get-kernel-settings\fR \(em Evaluate the system's kernel installation settings for use while making a grub configuration file. ++ ++.SH SYNOPSIS ++\fBgrub-get-kernel-settings\fR [OPTION] ++ ++.SH DESCRIPTION ++\fBgrub-get-kernel-settings\fR reads the kernel installation settings on the host system, and emits a set of grub settings suitable for use when creating a grub configuration file. ++ ++.SH OPTIONS ++.TP ++-h, --help ++Display program usage and exit. ++.TP ++-v, --version ++Display the current version. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-get-kernel-settings.in b/util/grub-get-kernel-settings.in +new file mode 100644 +index 00000000000..7e87dfccc0e +--- /dev/null ++++ b/util/grub-get-kernel-settings.in +@@ -0,0 +1,88 @@ ++#!/bin/sh ++set -e ++ ++# Evaluate new-kernel-pkg's configuration file. ++# Copyright (C) 2016 Free Software Foundation, Inc. ++# ++# 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 . ++ ++PACKAGE_NAME=@PACKAGE_NAME@ ++PACKAGE_VERSION=@PACKAGE_VERSION@ ++datadir="@datadir@" ++if [ "x$pkgdatadir" = x ]; then ++ pkgdatadir="${datadir}/@PACKAGE@" ++fi ++ ++self=`basename $0` ++ ++export TEXTDOMAIN=@PACKAGE@ ++export TEXTDOMAINDIR="@localedir@" ++ ++. "${pkgdatadir}/grub-mkconfig_lib" ++ ++# Usage: usage ++# Print the usage. ++usage () { ++ gettext_printf "Usage: %s [OPTION]\n" "$self" ++ gettext "Evaluate new-kernel-pkg configuration"; echo ++ echo ++ print_option_help "-h, --help" "$(gettext "print this message and exit")" ++ print_option_help "-v, --version" "$(gettext "print the version information and exit")" ++ echo ++} ++ ++# Check the arguments. ++while test $# -gt 0 ++do ++ option=$1 ++ shift ++ ++ case "$option" in ++ -h | --help) ++ usage ++ exit 0 ;; ++ -v | --version) ++ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" ++ exit 0 ;; ++ -*) ++ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 ++ usage ++ exit 1 ++ ;; ++ # Explicitly ignore non-option arguments, for compatibility. ++ esac ++done ++ ++if test -f /etc/sysconfig/kernel ; then ++ . /etc/sysconfig/kernel ++fi ++ ++if [ "$MAKEDEBUG" = "yes" ]; then ++ echo GRUB_LINUX_MAKE_DEBUG=true ++ echo export GRUB_LINUX_MAKE_DEBUG ++ echo GRUB_CMDLINE_LINUX_DEBUG=\"systemd.log_level=debug systemd.log_target=kmsg\" ++ echo export GRUB_CMDLINE_LINUX_DEBUG ++ echo GRUB_LINUX_DEBUG_TITLE_POSTFIX=\" with debugging\" ++ echo export GRUB_LINUX_DEBUG_TITLE_POSTFIX ++fi ++if [ "$DEFAULTDEBUG" = "yes" ]; then ++ echo GRUB_DEFAULT_TO_DEBUG=true ++else ++ echo GRUB_DEFAULT_TO_DEBUG=false ++fi ++echo export GRUB_DEFAULT_TO_DEBUG ++if [ "$UPDATEDEFAULT" = "yes" ]; then ++ echo GRUB_UPDATE_DEFAULT_KERNEL=true ++ echo export GRUB_UPDATE_DEFAULT_KERNEL ++fi +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index ba14cf6261c..005f093809b 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -45,6 +45,7 @@ grub_probe="${sbindir}/@grub_probe@" + grub_file="${bindir}/@grub_file@" + grub_editenv="${bindir}/@grub_editenv@" + grub_script_check="${bindir}/@grub_script_check@" ++grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" + + export TEXTDOMAIN=@PACKAGE@ + export TEXTDOMAINDIR="@localedir@" +@@ -158,6 +159,8 @@ if test -f ${sysconfdir}/default/grub ; then + fi + done + ++eval "$("${grub_get_kernel_settings}")" || true ++ + if [ "x${GRUB_DISABLE_UUID}" = "xtrue" ]; then + if [ -z "${GRUB_DISABLE_LINUX_UUID}" ]; then + GRUB_DISABLE_LINUX_UUID="true" +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 786dbabb4a8..292e333324b 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -140,7 +140,8 @@ linux_entry () + os="$1" + version="$2" + type="$3" +- args="$4" ++ isdebug="$4" ++ args="$5" + + if [ -n "${linux_root_device_thisversion}" ]; then + root_device="root=${linux_root_device_thisversion}" +@@ -158,6 +158,9 @@ linux_entry () + quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" + title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" + fi ++ if [ x$isdebug = xdebug ]; then ++ title="$title${GRUB_LINUX_DEBUG_TITLE_POSTFIX}" ++ fi + echo "menuentry '$(echo "$title" | grub_quote)' $(print_hotkey) ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" + hotkey=$(incr_hotkey) + else +@@ -440,11 +444,15 @@ while [ "x$list" != "x" ] ; do + fi + + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then +- linux_entry "${OS}" "${version}" simple \ ++ linux_entry "${OS}" "${version}" simple standard \ + "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" ++ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then ++ linux_entry "${OS}" "${version}" simple debug \ ++ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}" ++ fi + + submenu_indentation="$grub_tab" +- ++ + if [ -z "$boot_device_id" ]; then + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi +@@ -454,10 +454,15 @@ for linux in ${reverse_sorted_list}; do + is_top_level=false + fi + +- linux_entry "${OS}" "${version}" advanced \ ++ linux_entry "${OS}" "${version}" advanced standard \ + "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" ++ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then ++ linux_entry "${OS}" "${version}" advanced debug \ ++ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}" ++ fi ++ + if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then +- linux_entry "${OS}" "${version}" recovery \ ++ linux_entry "${OS}" "${version}" recovery standard \ + "${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}" + fi + done diff --git a/0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch b/0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch new file mode 100644 index 0000000..499fef6 --- /dev/null +++ b/0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 4 Jun 2018 19:49:47 +0200 +Subject: [PATCH] grub-editenv: Add "incr" command to increment integer +value + env. variables + +To be able to automatically detect if the last boot was successful, +We want to keep count of succesful / failed boots in some integer +environment variable. + +This commit adds a grub-editenvt "incr" command to increment such +integer value env. variables by 1 for use from various boot scripts. + +Signed-off-by: Hans de Goede +--- + util/grub-editenv.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 49 insertions(+) + +diff --git a/util/grub-editenv.c b/util/grub-editenv.c +index af30aab..e336bcd 100644 +--- a/util/grub-editenv.c ++++ b/util/grub-editenv.c +@@ -56,6 +56,9 @@ static struct argp_option options[] = { + /* TRANSLATORS: "unset" is a keyword. It's a summary of "unset" subcommand. */ + {N_("unset [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, + N_("Delete variables."), 0}, ++ /* TRANSLATORS: "incr" is a keyword. It's a summary of "incr" subcommand. */ ++ {N_("incr [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, ++ N_("Increase value of integer variables."), 0}, + + {0, 0, 0, OPTION_DOC, N_("Options:"), -1}, + {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, +@@ -577,6 +580,50 @@ probe_fs_envblk (fs_envblk_spec_t spec) + return NULL; + } + ++struct get_int_value_params { ++ char *varname; ++ int value; ++}; ++ ++static int ++get_int_value (const char *varname, const char *value, void *hook_data) ++{ ++ struct get_int_value_params *params = hook_data; ++ ++ if (strcmp (varname, params->varname) == 0) { ++ params->value = strtol (value, NULL, 10); ++ return 1; ++ } ++ return 0; ++} ++ ++static void ++incr_variables (const char *name, int argc, char *argv[]) ++{ ++ grub_envblk_t envblk; ++ char buf[16]; ++ ++ envblk = open_envblk_file (name); ++ while (argc) ++ { ++ struct get_int_value_params params = { ++ .varname = argv[0], ++ .value = 0, /* Consider unset variables 0 */ ++ }; ++ ++ grub_envblk_iterate (envblk, ¶ms, get_int_value); ++ snprintf(buf, sizeof(buf), "%d", params.value + 1); ++ ++ if (! grub_envblk_set (envblk, argv[0], buf)) ++ grub_util_error ("%s", _("environment block too small")); ++ ++ argc--; ++ argv++; ++ } ++ ++ write_envblk (name, envblk); ++ grub_envblk_close (envblk); ++} + + int + main (int argc, char *argv[]) +@@ -620,6 +667,8 @@ main (int argc, char *argv[]) + set_variables (filename, argc - curindex, argv + curindex); + else if (strcmp (command, "unset") == 0) + unset_variables (filename, argc - curindex, argv + curindex); ++ else if (strcmp (command, "incr") == 0) ++ incr_variables (filename, argc - curindex, argv + curindex); + else + { + char *program = xstrdup(program_name); +-- +2.33.0 + diff --git a/grub.macros b/grub.macros index 03f7024..056e128 100644 --- a/grub.macros +++ b/grub.macros @@ -446,8 +446,8 @@ GRUB_MODULES=" all_video boot btrfs \\\ gcry_sha256 gcry_twofish gcry_whirlpool \\\ gfxmenu gfxterm gzio \\\ halt http iso9660 jpeg \\\ - loadenv loopback linux luks \\\ - luks2 minicmd net \\\ + loadenv loopback linux lvm lsefi lsefimmap luks \\\ + luks2 mdraid09 mdraid1x minicmd net \\\ normal part_apple part_msdos part_gpt \\\ password_pbkdf2 png reboot \\\ search search_fs_uuid search_fs_file \\\ diff --git a/grub.patches b/grub.patches index 0292498..97ff027 100644 --- a/grub.patches +++ b/grub.patches @@ -222,3 +222,8 @@ Patch221: fix-setupmode-not-available-in-some-machine.patch Patch222: fix-compressed-kernel-verification-failed.patch Patch223: support-TPM2.0.patch Patch224: use-default-timestamp.patch +Patch225: 0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch +Patch226: 0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch +Patch227: 0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch +Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch +Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch diff --git a/grub2.spec b/grub2.spec index b21aa7d..96d5b6e 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 8 +Release: 9 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -199,10 +199,10 @@ makeinfo --info --no-split -I docs -o docs/grub.info docs/grub.texi makeinfo --html --no-split -I docs -o docs/grub-dev.html docs/grub-dev.texi makeinfo --html --no-split -I docs -o docs/grub.html docs/grub.texi %if 0%{?openEuler_sign_rsa} -sh /usr/lib/rpm/brp-ebs-sign --efi %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname} -sh /usr/lib/rpm/brp-ebs-sign --efi %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname} -mv %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname}.sig %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname} -mv %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname}.sig %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname} +sh /usr/lib/rpm/brp-ebs-sign --efi %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname} || [ $? -eq 2 ] && echo "failed to sign, skip signature." +sh /usr/lib/rpm/brp-ebs-sign --efi %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname} || [ $? -eq 2 ] && echo "failed to sign, skip signature." +mv %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname}.sig %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubefiname} ||: +mv %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname}.sig %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdname} ||: %endif %check @@ -392,7 +392,7 @@ fi %files tools-minimal %defattr(-,root,root) #%attr(4755, root, root) %{_sbindir}/%{name}-set-bootflag -#%{_sbindir}/%{name}-get-kernel-settings +%{_sbindir}/%{name}-get-kernel-settings %{_sbindir}/%{name}-set*password %{_sbindir}/%{name}-set-default %{_bindir}/%{name}-editenv @@ -447,6 +447,16 @@ fi %{_datadir}/man/man* %changelog +* Tue May 7 2024 zhangqiumiao - 1:2.12-9 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:ignore signing failure + Revert "templates: Disable the os-prober by default" + Revert "templates: Properly disable the os-prober by default" + Add grub-get-kernel-settings and use it in 10_linux + Replace a lot of man pages with slightly nicer ones + * Tue Apr 9 2024 zhangqiumiao - 1:2.12-8 - Type:bugfix - CVE:NA -- Gitee From ab70457abb444aea568c9b3800b9e9ff6528ceb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=82=96=E5=9C=A8?= Date: Sat, 11 May 2024 09:32:27 +0800 Subject: [PATCH 08/26] Handle non-continuous data blocks in directory extents The directory extent list does not have to be a continuous list of data blocks. When GRUB tries to read a non-existant member of the list, grub_xfs_read_file() will return a block of zero'ed memory. Checking for a zero'ed magic number is sufficient to skip this non-existant data block. (cherry picked from commit 242fa05f2412202b241bbea01dc2bd69214b2e33) --- ...nuous-data-blocks-in-directory-exten.patch | 41 +++++++++++++++++++ grub.patches | 1 + grub2.spec | 12 +++++- 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/Handle-non-continuous-data-blocks-in-directory-exten.patch b/Handle-non-continuous-data-blocks-in-directory-exten.patch new file mode 100644 index 0000000..f2c5c5c --- /dev/null +++ b/Handle-non-continuous-data-blocks-in-directory-exten.patch @@ -0,0 +1,41 @@ +From edb3f9c9b1fd510775332e6788dc1a4d4af68666 Mon Sep 17 00:00:00 2001 +From: openEuler Buildteam +Date: Sat, 11 May 2024 09:22:03 +0800 +Subject: [PATCH] Handle non-continuous data blocks in directory extents + +--- + grub-core/fs/xfs.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 1ce5fa4..ed52586 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -904,6 +904,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + + int entries = -1; + char *end = dirblock + dirblk_size; ++ grub_uint32_t magic; + + numread = grub_xfs_read_file (dir, 0, 0, + blk << dirblk_log2, +@@ -914,6 +915,16 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + return 0; + } + ++ /* ++ * If this data block isn't actually part of the extent list then ++ * grub_xfs_read_file() returns a block of zeros. So, if the magic ++ * number field is all zeros then this block should be skipped. ++ */ ++ magic = *(grub_uint32_t *)(void *) dirblock; ++ if (!magic) ++ continue; ++ ++ + /* + * Leaf and tail information are only in the data block if the number + * of extents is 1. +-- +2.33.0 + diff --git a/grub.patches b/grub.patches index 97ff027..76867b6 100644 --- a/grub.patches +++ b/grub.patches @@ -227,3 +227,4 @@ Patch226: 0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch Patch227: 0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch +Patch230: Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/grub2.spec b/grub2.spec index 96d5b6e..2fc2879 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 9 +Release: 10 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,16 @@ fi %{_datadir}/man/man* %changelog +* Sat May 11 2024 xiaozai - 1:2.12-10 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:Handle non-continuous data blocks in directory extents + The directory extent list does not have to be a continuous list of data + blocks. When GRUB tries to read a non-existant member of the list, + grub_xfs_read_file() will return a block of zero'ed memory. Checking for + a zero'ed magic number is sufficient to skip this non-existant data block. + * Tue May 7 2024 zhangqiumiao - 1:2.12-9 - Type:bugfix - CVE:NA -- Gitee From 8c8cc1841b8bec9e80ddf8eb7cfb8b22d557a843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=82=96=E5=9C=A8?= Date: Sat, 11 May 2024 01:46:46 +0000 Subject: [PATCH 09/26] Revert " Handle non-continuous data blocks in" This reverts commit 242fa05f2412202b241bbea01dc2bd69214b2e33. (cherry picked from commit fd1e9fdd653fbd874133cbfd0a7885bd1fb2916f) --- ...nuous-data-blocks-in-directory-exten.patch | 41 ------------------- grub.patches | 1 - grub2.spec | 12 +----- 3 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/Handle-non-continuous-data-blocks-in-directory-exten.patch b/Handle-non-continuous-data-blocks-in-directory-exten.patch deleted file mode 100644 index f2c5c5c..0000000 --- a/Handle-non-continuous-data-blocks-in-directory-exten.patch +++ /dev/null @@ -1,41 +0,0 @@ -From edb3f9c9b1fd510775332e6788dc1a4d4af68666 Mon Sep 17 00:00:00 2001 -From: openEuler Buildteam -Date: Sat, 11 May 2024 09:22:03 +0800 -Subject: [PATCH] Handle non-continuous data blocks in directory extents - ---- - grub-core/fs/xfs.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c -index 1ce5fa4..ed52586 100644 ---- a/grub-core/fs/xfs.c -+++ b/grub-core/fs/xfs.c -@@ -904,6 +904,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, - - int entries = -1; - char *end = dirblock + dirblk_size; -+ grub_uint32_t magic; - - numread = grub_xfs_read_file (dir, 0, 0, - blk << dirblk_log2, -@@ -914,6 +915,16 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, - return 0; - } - -+ /* -+ * If this data block isn't actually part of the extent list then -+ * grub_xfs_read_file() returns a block of zeros. So, if the magic -+ * number field is all zeros then this block should be skipped. -+ */ -+ magic = *(grub_uint32_t *)(void *) dirblock; -+ if (!magic) -+ continue; -+ -+ - /* - * Leaf and tail information are only in the data block if the number - * of extents is 1. --- -2.33.0 - diff --git a/grub.patches b/grub.patches index 76867b6..97ff027 100644 --- a/grub.patches +++ b/grub.patches @@ -227,4 +227,3 @@ Patch226: 0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch Patch227: 0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch -Patch230: Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/grub2.spec b/grub2.spec index 2fc2879..96d5b6e 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 10 +Release: 9 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,16 +447,6 @@ fi %{_datadir}/man/man* %changelog -* Sat May 11 2024 xiaozai - 1:2.12-10 -- Type:bugfix -- CVE:NA -- SUG:NA -- DESC:Handle non-continuous data blocks in directory extents - The directory extent list does not have to be a continuous list of data - blocks. When GRUB tries to read a non-existant member of the list, - grub_xfs_read_file() will return a block of zero'ed memory. Checking for - a zero'ed magic number is sufficient to skip this non-existant data block. - * Tue May 7 2024 zhangqiumiao - 1:2.12-9 - Type:bugfix - CVE:NA -- Gitee From 9780808accf7c0ef6055b204542f9c9f51bfb7ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=82=96=E5=9C=A8?= Date: Sat, 11 May 2024 10:06:01 +0800 Subject: [PATCH 10/26] Handle non-continuous data blocks in directory extents The directory extent list does not have to be a continuous list of data blocks. When GRUB tries to read a non-existant member of the list, grub_xfs_read_file() will return a block of zero'ed memory. Checking for a zero'ed magic number is sufficient to skip this non-existant data block. Prior to commit 07318ee7e (fs/xfs: Fix XFS directory extent parsing) this was handled as a subtle side effect of reading the (non-existant) tail data structure. Since the block was zero'ed the computation of the number of directory entries in the block would return 0 as well. (cherry picked from commit e0cd43f8a5486debeba17349abbb088001164d70) --- ...nuous-data-blocks-in-directory-exten.patch | 49 +++++++++++++++++++ grub.patches | 1 + grub2.spec | 12 ++++- 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/Handle-non-continuous-data-blocks-in-directory-exten.patch b/Handle-non-continuous-data-blocks-in-directory-exten.patch new file mode 100644 index 0000000..20162aa --- /dev/null +++ b/Handle-non-continuous-data-blocks-in-directory-exten.patch @@ -0,0 +1,49 @@ +From 426d43bdf15e3e65c9b2cc80aa4b416750c643c3 Mon Sep 17 00:00:00 2001 +From: openEuler Buildteam +Date: Sat, 11 May 2024 10:00:32 +0800 +Subject: [PATCH] Handle non-continuous data blocks in directory extents + +The directory extent list does not have to be a continuous list of data +blocks. When GRUB tries to read a non-existant member of the list, +grub_xfs_read_file() will return a block of zero'ed memory. Checking for +a zero'ed magic number is sufficient to skip this non-existant data block. + +Prior to commit 07318ee7e (fs/xfs: Fix XFS directory extent parsing) +this was handled as a subtle side effect of reading the (non-existant) +tail data structure. Since the block was zero'ed the computation of the +number of directory entries in the block would return 0 as well. +--- + grub-core/fs/xfs.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 1ce5fa4..2a22e26 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -904,6 +904,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + + int entries = -1; + char *end = dirblock + dirblk_size; ++ grub_uint32_t magic; + + numread = grub_xfs_read_file (dir, 0, 0, + blk << dirblk_log2, +@@ -914,6 +915,15 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + return 0; + } + ++ /* ++ * If this data block isn't actually part of the extent list then ++ * grub_xfs_read_file() returns a block of zeros. So, if the magic ++ * number field is all zeros then this block should be skipped. ++ */ ++ magic = *(grub_uint32_t *)(void *) dirblock; ++ if (!magic) ++ continue; ++ + /* + * Leaf and tail information are only in the data block if the number + * of extents is 1. +-- +2.33.0 + diff --git a/grub.patches b/grub.patches index 97ff027..76867b6 100644 --- a/grub.patches +++ b/grub.patches @@ -227,3 +227,4 @@ Patch226: 0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch Patch227: 0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch +Patch230: Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/grub2.spec b/grub2.spec index 96d5b6e..2fc2879 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 9 +Release: 10 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,16 @@ fi %{_datadir}/man/man* %changelog +* Sat May 11 2024 xiaozai - 1:2.12-10 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:Handle non-continuous data blocks in directory extents + The directory extent list does not have to be a continuous list of data + blocks. When GRUB tries to read a non-existant member of the list, + grub_xfs_read_file() will return a block of zero'ed memory. Checking for + a zero'ed magic number is sufficient to skip this non-existant data block. + * Tue May 7 2024 zhangqiumiao - 1:2.12-9 - Type:bugfix - CVE:NA -- Gitee From 23374a2f553ea94270ef017b151888e83f9590c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=82=96=E5=9C=A8?= Date: Sat, 11 May 2024 03:26:36 +0000 Subject: [PATCH 11/26] Revert "Handle non-continuous data blocks in" This reverts commit e0cd43f8a5486debeba17349abbb088001164d70. (cherry picked from commit 88a9257d4914cb2aca40f3b0494a0dcb8927482d) --- ...nuous-data-blocks-in-directory-exten.patch | 49 ------------------- grub.patches | 1 - grub2.spec | 12 +---- 3 files changed, 1 insertion(+), 61 deletions(-) delete mode 100644 Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/Handle-non-continuous-data-blocks-in-directory-exten.patch b/Handle-non-continuous-data-blocks-in-directory-exten.patch deleted file mode 100644 index 20162aa..0000000 --- a/Handle-non-continuous-data-blocks-in-directory-exten.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 426d43bdf15e3e65c9b2cc80aa4b416750c643c3 Mon Sep 17 00:00:00 2001 -From: openEuler Buildteam -Date: Sat, 11 May 2024 10:00:32 +0800 -Subject: [PATCH] Handle non-continuous data blocks in directory extents - -The directory extent list does not have to be a continuous list of data -blocks. When GRUB tries to read a non-existant member of the list, -grub_xfs_read_file() will return a block of zero'ed memory. Checking for -a zero'ed magic number is sufficient to skip this non-existant data block. - -Prior to commit 07318ee7e (fs/xfs: Fix XFS directory extent parsing) -this was handled as a subtle side effect of reading the (non-existant) -tail data structure. Since the block was zero'ed the computation of the -number of directory entries in the block would return 0 as well. ---- - grub-core/fs/xfs.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c -index 1ce5fa4..2a22e26 100644 ---- a/grub-core/fs/xfs.c -+++ b/grub-core/fs/xfs.c -@@ -904,6 +904,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, - - int entries = -1; - char *end = dirblock + dirblk_size; -+ grub_uint32_t magic; - - numread = grub_xfs_read_file (dir, 0, 0, - blk << dirblk_log2, -@@ -914,6 +915,15 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, - return 0; - } - -+ /* -+ * If this data block isn't actually part of the extent list then -+ * grub_xfs_read_file() returns a block of zeros. So, if the magic -+ * number field is all zeros then this block should be skipped. -+ */ -+ magic = *(grub_uint32_t *)(void *) dirblock; -+ if (!magic) -+ continue; -+ - /* - * Leaf and tail information are only in the data block if the number - * of extents is 1. --- -2.33.0 - diff --git a/grub.patches b/grub.patches index 76867b6..97ff027 100644 --- a/grub.patches +++ b/grub.patches @@ -227,4 +227,3 @@ Patch226: 0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch Patch227: 0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch -Patch230: Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/grub2.spec b/grub2.spec index 2fc2879..96d5b6e 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 10 +Release: 9 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,16 +447,6 @@ fi %{_datadir}/man/man* %changelog -* Sat May 11 2024 xiaozai - 1:2.12-10 -- Type:bugfix -- CVE:NA -- SUG:NA -- DESC:Handle non-continuous data blocks in directory extents - The directory extent list does not have to be a continuous list of data - blocks. When GRUB tries to read a non-existant member of the list, - grub_xfs_read_file() will return a block of zero'ed memory. Checking for - a zero'ed magic number is sufficient to skip this non-existant data block. - * Tue May 7 2024 zhangqiumiao - 1:2.12-9 - Type:bugfix - CVE:NA -- Gitee From 9014aa3a762ff5c9f680383dda1e49c90dcf35c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=82=96=E5=9C=A8?= Date: Sat, 11 May 2024 11:33:07 +0800 Subject: [PATCH 12/26] Handle non-continuous data blocks in directory extents (cherry picked from commit eaccc141e1795ac3b376afe158a54a6f52fc6b62) --- ...nuous-data-blocks-in-directory-exten.patch | 57 +++++++++++++++++++ grub.patches | 1 + grub2.spec | 8 ++- 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/Handle-non-continuous-data-blocks-in-directory-exten.patch b/Handle-non-continuous-data-blocks-in-directory-exten.patch new file mode 100644 index 0000000..5381ee2 --- /dev/null +++ b/Handle-non-continuous-data-blocks-in-directory-exten.patch @@ -0,0 +1,57 @@ +From 68dd65cfdaad08b1f8ec01b84949b0bf88bc0d8c Mon Sep 17 00:00:00 2001 +From: Jon DeVree +Date: Sun, 11 Feb 2024 10:34:58 -0500 +Subject: [PATCH 0990/1000] fs/xfs: Handle non-continuous data blocks in + directory extents + +The directory extent list does not have to be a continuous list of data +blocks. When GRUB tries to read a non-existant member of the list, +grub_xfs_read_file() will return a block of zero'ed memory. Checking for +a zero'ed magic number is sufficient to skip this non-existant data block. + +Prior to commit 07318ee7e (fs/xfs: Fix XFS directory extent parsing) +this was handled as a subtle side effect of reading the (non-existant) +tail data structure. Since the block was zero'ed the computation of the +number of directory entries in the block would return 0 as well. + +Fixes: 07318ee7e (fs/xfs: Fix XFS directory extent parsing) +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2254370 + +Signed-off-by: Jon DeVree +Reviewed-By: Vladimir Serbinenko +Reviewed-by: Daniel Kiper +--- + grub-core/fs/xfs.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 1ce5fa4..2a22e26 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -904,6 +904,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + + int entries = -1; + char *end = dirblock + dirblk_size; ++ grub_uint32_t magic; + + numread = grub_xfs_read_file (dir, 0, 0, + blk << dirblk_log2, +@@ -914,6 +915,15 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + return 0; + } + ++ /* ++ * If this data block isn't actually part of the extent list then ++ * grub_xfs_read_file() returns a block of zeros. So, if the magic ++ * number field is all zeros then this block should be skipped. ++ */ ++ magic = *(grub_uint32_t *)(void *) dirblock; ++ if (!magic) ++ continue; ++ + /* + * Leaf and tail information are only in the data block if the number + * of extents is 1. +-- +2.33.0 + diff --git a/grub.patches b/grub.patches index 97ff027..76867b6 100644 --- a/grub.patches +++ b/grub.patches @@ -227,3 +227,4 @@ Patch226: 0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch Patch227: 0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch +Patch230: Handle-non-continuous-data-blocks-in-directory-exten.patch diff --git a/grub2.spec b/grub2.spec index 96d5b6e..91cc878 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 9 +Release: 10 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,12 @@ fi %{_datadir}/man/man* %changelog +* Sat May 11 2024 xiaozai - 1:2.12-10 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:Handle non-continuous data blocks in directory extents + * Tue May 7 2024 zhangqiumiao - 1:2.12-9 - Type:bugfix - CVE:NA -- Gitee From f5f908d912d38cc6fc21693d9ad553299c2f400f Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Sat, 11 May 2024 07:11:21 +0000 Subject: [PATCH 13/26] loongarch64: fix GRUB_EFI_MAX_ALLOCATION_ADDRESS undeclared Signed-off-by: Qiumiao Zhang (cherry picked from commit c7c931741222dc5d1fb93839ad463c152e217ef8) --- grub.patches | 1 + grub2.spec | 8 ++++++- ...GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 loongarch64-fix-GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch diff --git a/grub.patches b/grub.patches index 76867b6..ecb025b 100644 --- a/grub.patches +++ b/grub.patches @@ -228,3 +228,4 @@ Patch227: 0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch Patch230: Handle-non-continuous-data-blocks-in-directory-exten.patch +Patch231: loongarch64-fix-GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch diff --git a/grub2.spec b/grub2.spec index 91cc878..4a31c73 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 10 +Release: 11 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,12 @@ fi %{_datadir}/man/man* %changelog +* Sat May 11 2024 zhangqiumiao - 1:2.12-11 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:loongarch64: fix GRUB_EFI_MAX_ALLOCATION_ADDRESS undeclared + * Sat May 11 2024 xiaozai - 1:2.12-10 - Type:bugfix - CVE:NA diff --git a/loongarch64-fix-GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch b/loongarch64-fix-GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch new file mode 100644 index 0000000..69aa0ab --- /dev/null +++ b/loongarch64-fix-GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch @@ -0,0 +1,23 @@ +From 5e1c62c71d7e8f0a4ae6a71f6da30affb1d25985 Mon Sep 17 00:00:00 2001 +From: Qiumiao Zhang +Date: Sat, 11 May 2024 06:52:47 +0000 +Subject: [PATCH] loongarch64: fix GRUB_EFI_MAX_ALLOCATION_ADDRESS undeclared + +--- + include/grub/loongarch64/efi/memory.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h +index d460267..792258b 100644 +--- a/include/grub/loongarch64/efi/memory.h ++++ b/include/grub/loongarch64/efi/memory.h +@@ -20,5 +20,6 @@ + #include + + #define GRUB_EFI_MAX_USABLE_ADDRESS 0xfffffffffffULL ++#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS + + #endif /* ! GRUB_MEMORY_CPU_HEADER */ +-- +2.33.0 + -- Gitee From 0ebbd7d6f1ae0960671e93a74368f3c763d23b03 Mon Sep 17 00:00:00 2001 From: ouuleilei Date: Fri, 24 May 2024 19:38:29 +0800 Subject: [PATCH 14/26] Add sophgo's patch to support risc-v machine SG2042 (cherry picked from commit 20f2ea943e4cbb4e35477767638b41ddcf77eadc) --- grub.patches | 1 + grub2.spec | 5 ++++- modify-efi_max_usable-addr.patch | 26 ++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 modify-efi_max_usable-addr.patch diff --git a/grub.patches b/grub.patches index ecb025b..8e92f9f 100644 --- a/grub.patches +++ b/grub.patches @@ -229,3 +229,4 @@ Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch Patch230: Handle-non-continuous-data-blocks-in-directory-exten.patch Patch231: loongarch64-fix-GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch +Patch232: modify-efi_max_usable-addr.patch diff --git a/grub2.spec b/grub2.spec index 4a31c73..8b3e155 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 11 +Release: 12 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,9 @@ fi %{_datadir}/man/man* %changelog +* Fri May 24 2024 Ouuleilei - 1:2.12-12 +- Add sophgo's patch to support risc-v machine SG2042 + * Sat May 11 2024 zhangqiumiao - 1:2.12-11 - Type:bugfix - CVE:NA diff --git a/modify-efi_max_usable-addr.patch b/modify-efi_max_usable-addr.patch new file mode 100644 index 0000000..4b0c31d --- /dev/null +++ b/modify-efi_max_usable-addr.patch @@ -0,0 +1,26 @@ +From 7ab0dc548f8221a9c336a1682df9f729b975c7ff Mon Sep 17 00:00:00 2001 +From: "jingyu.li01" +Date: Tue, 2 Jan 2024 10:09:53 +0800 +Subject: [PATCH] include/grub/riscv64: modify efi_max_usable addr + +This is a temporary solution for relocation overflow on a segmented memory +layout. + +Signed-off-by: jingyu.li01 +--- + include/grub/riscv64/efi/memory.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/grub/riscv64/efi/memory.h b/include/grub/riscv64/efi/memory.h +index c6cb32417..eb6f1bb83 100644 +--- a/include/grub/riscv64/efi/memory.h ++++ b/include/grub/riscv64/efi/memory.h +@@ -1,7 +1,7 @@ + #ifndef GRUB_MEMORY_CPU_HEADER + #include + +-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL ++#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffULL + #define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS + + #endif /* ! GRUB_MEMORY_CPU_HEADER */ -- Gitee From 70403ebbcf41e9e3947847d951b23ece194ad936 Mon Sep 17 00:00:00 2001 From: Juxin Gao Date: Sat, 25 May 2024 12:00:44 +0800 Subject: [PATCH 15/26] LoongArch: Add back-compatibility for linux kernel. Signed-off-by: Juxin Gao (cherry picked from commit 49d8f0dc100cd059916c5ad1fe319fbccc856be7) --- ...-back-compatibility-for-linux-kernel.patch | 2192 +++++++++++++++++ grub.patches | 3 +- grub2.spec | 9 +- 3 files changed, 2202 insertions(+), 2 deletions(-) create mode 100644 LoongArch-Add-back-compatibility-for-linux-kernel.patch diff --git a/LoongArch-Add-back-compatibility-for-linux-kernel.patch b/LoongArch-Add-back-compatibility-for-linux-kernel.patch new file mode 100644 index 0000000..23d46dc --- /dev/null +++ b/LoongArch-Add-back-compatibility-for-linux-kernel.patch @@ -0,0 +1,2192 @@ +From 28dcf484821b95d7de85de33dbd41ee7682e5778 Mon Sep 17 00:00:00 2001 +From: Xue Liu +Date: Fri, 24 May 2024 14:16:02 +0800 +Subject: [PATCH] LoongArch: Add back-compatibility for linux kernel. + +--- + configure.ac | 4 +- + grub-core/Makefile.core.def | 7 +- + grub-core/kern/efi/mm.c | 33 +- + grub-core/lib/loongarch64/relocator.c | 163 ++++ + grub-core/lib/loongarch64/relocator_asm.S | 51 ++ + grub-core/loader/loongarch64/linux-efi.c | 102 +++ + grub-core/loader/loongarch64/linux-elf.c | 896 ++++++++++++++++++++++ + grub-core/loader/loongarch64/linux.c | 437 +++++++++++ + include/grub/loongarch64/efi/memory.h | 9 +- + include/grub/loongarch64/linux.h | 215 ++++++ + include/grub/loongarch64/memory.h | 59 ++ + include/grub/loongarch64/relocator.h | 38 + + 12 files changed, 2008 insertions(+), 6 deletions(-) + create mode 100644 grub-core/lib/loongarch64/relocator.c + create mode 100644 grub-core/lib/loongarch64/relocator_asm.S + create mode 100644 grub-core/loader/loongarch64/linux-efi.c + create mode 100644 grub-core/loader/loongarch64/linux-elf.c + create mode 100644 grub-core/loader/loongarch64/linux.c + create mode 100644 include/grub/loongarch64/linux.h + create mode 100644 include/grub/loongarch64/memory.h + create mode 100644 include/grub/loongarch64/relocator.h + +diff --git a/configure.ac b/configure.ac +index 71a2424a140d..96f4f5e9e554 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -146,7 +146,9 @@ case "$target_cpu" in + ;; + arm*) target_cpu=arm ;; + aarch64*) target_cpu=arm64 ;; +- loongarch64) target_cpu=loongarch64 ;; ++ loongarch64) target_cpu=loongarch64 ++ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_LOONGARCH64=1" ++ ;; + riscv32*) target_cpu=riscv32 ;; + riscv64*) target_cpu=riscv64 ;; + esac +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index cc33ca57af8b..7f025e5cfcd6 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1730,6 +1730,8 @@ module = { + x86_64_xen = lib/x86_64/xen/relocator.S; + xen = lib/i386/relocator_common_c.c; + x86_64_efi = lib/x86_64/efi/relocator.c; ++ loongarch64 = lib/loongarch64/relocator_asm.S; ++ loongarch64 = lib/loongarch64/relocator.c; + + extra_dist = lib/i386/relocator_common.S; + extra_dist = kern/powerpc/cache_flush.S; +@@ -1739,6 +1741,7 @@ module = { + enable = x86; + enable = i386_xen_pvh; + enable = xen; ++ enable = loongarch64; + }; + + module = { +@@ -1875,7 +1878,9 @@ module = { + arm_efi = loader/efi/linux.c; + arm_uboot = loader/arm/linux.c; + arm64 = loader/arm64/efi/linux.c; +- loongarch64 = loader/efi/linux.c; ++ loongarch64 = loader/loongarch64/linux.c; ++ loongarch64 = loader/loongarch64/linux-efi.c; ++ loongarch64 = loader/loongarch64/linux-elf.c; + riscv32 = loader/efi/linux.c; + riscv64 = loader/efi/linux.c; + emu = loader/emu/linux.c; +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 9b1d3add715b..31bffb534414 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -39,7 +39,11 @@ + #define MEMORY_MAP_SIZE 0x3000 + + /* The default heap size for GRUB itself in bytes. */ ++#ifdef GRUB_CPU_LOONGARCH64 ++#define DEFAULT_HEAP_SIZE 0x10000000 ++#else + #define DEFAULT_HEAP_SIZE 0x2000000 ++#endif + + static void *finish_mmap_buf = 0; + static grub_efi_uintn_t finish_mmap_size = 0; +@@ -156,7 +160,11 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + grub_efi_physical_address_t ret = address; + + /* Limit the memory access to less than 4GB for 32-bit platforms. */ ++#ifdef GRUB_CPU_LOONGARCH64 ++ if (address > grub_efi_max_usable_address()) ++#else + if (address > GRUB_EFI_MAX_USABLE_ADDRESS) ++#endif + { + char inv_addr[17], max_addr[17]; /* log16(2^64) = 16, plus NUL. */ + +@@ -184,7 +192,11 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + { + /* Uggh, the address 0 was allocated... This is too annoying, + so reallocate another one. */ ++#ifdef GRUB_CPU_LOONGARCH64 ++ ret = grub_efi_max_usable_address(); ++#else + ret = address; ++#endif + status = b->allocate_pages (alloctype, memtype, pages, &ret); + grub_efi_free_pages (0, pages); + if (status != GRUB_EFI_SUCCESS) +@@ -202,9 +214,15 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + void * + grub_efi_allocate_any_pages (grub_efi_uintn_t pages) + { ++#ifdef GRUB_CPU_LOONGARCH64 ++ return grub_efi_allocate_pages_real (grub_efi_max_usable_address(), ++ pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, ++ GRUB_EFI_LOADER_DATA); ++#else + return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, + pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_LOADER_DATA); ++#endif + } + + void * +@@ -480,8 +498,10 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY +-#if 1 +- && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS ++#ifdef GRUB_CPU_LOONGARCH64 ++ && desc->physical_start <= grub_efi_max_usable_address() ++#else ++ && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS + #endif + && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 + && desc->num_pages != 0) +@@ -496,7 +516,14 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + desc->physical_start = 0x100000; + } + +-#if 1 ++#ifdef GRUB_CPU_LOONGARCH64 ++ if (BYTES_TO_PAGES (filtered_desc->physical_start) ++ + filtered_desc->num_pages ++ > BYTES_TO_PAGES_DOWN (grub_efi_max_usable_address())) ++ filtered_desc->num_pages ++ = (BYTES_TO_PAGES_DOWN (grub_efi_max_usable_address()) ++ - BYTES_TO_PAGES (filtered_desc->physical_start)); ++#else + if (BYTES_TO_PAGES (filtered_desc->physical_start) + + filtered_desc->num_pages + > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS)) +diff --git a/grub-core/lib/loongarch64/relocator.c b/grub-core/lib/loongarch64/relocator.c +new file mode 100644 +index 000000000000..587fc585ab7a +--- /dev/null ++++ b/grub-core/lib/loongarch64/relocator.c +@@ -0,0 +1,163 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Free Software Foundation, Inc. ++ * ++ * 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 . ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++extern grub_uint8_t grub_relocator_forward_start; ++extern grub_uint8_t grub_relocator_forward_end; ++extern grub_uint8_t grub_relocator_backward_start; ++extern grub_uint8_t grub_relocator_backward_end; ++ ++#define REGW_SIZEOF (4 * sizeof (grub_uint32_t)) ++#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t)) ++ ++#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \ ++ - &grub_relocator_##x##_start) ++#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ ++ + REGW_SIZEOF * 3) ++grub_size_t grub_relocator_align = sizeof (grub_uint64_t); ++grub_size_t grub_relocator_forward_size; ++grub_size_t grub_relocator_backward_size; ++grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF; ++ ++void ++grub_cpu_relocator_init (void) ++{ ++ grub_relocator_forward_size = RELOCATOR_SIZEOF(forward); ++ grub_relocator_backward_size = RELOCATOR_SIZEOF(backward); ++} ++ ++static void ++write_reg (int regn, grub_uint64_t val, void **target) ++{ ++ grub_uint32_t lu12iw=0x14000000; ++ grub_uint32_t ori=0x03800000; ++ grub_uint32_t lu32id=0x16000000; ++ grub_uint32_t lu52id=0x03000000; ++ ++ *(grub_uint32_t *) *target = (lu12iw | (grub_uint32_t)((val & 0xfffff000)>>12<<5) | (grub_uint32_t)regn);; ++ *target = ((grub_uint32_t *) *target) + 1; ++ *(grub_uint32_t *) *target = (ori | (grub_uint32_t)((val & 0xfff)<<10) | (grub_uint32_t)(regn | regn<<5)); ++ *target = ((grub_uint32_t *) *target) + 1; ++ *(grub_uint32_t *) *target = (lu32id | (grub_uint32_t)((val & 0xfffff00000000)>>32<<5) | (grub_uint32_t)regn);; ++ *target = ((grub_uint32_t *) *target) + 1; ++ *(grub_uint32_t *) *target = (lu52id | (grub_uint32_t)((val & 0xfff0000000000000)>>52<<10) | (grub_uint32_t)(regn | regn<<5));; ++ *target = ((grub_uint32_t *) *target) + 1; ++} ++ ++static void ++write_jump (int regn, void **target) ++{ ++ grub_uint32_t jirl=0x4c000000; ++ ++ *(grub_uint32_t *) *target = (jirl | (grub_uint32_t)(regn<<5)); ++ *target = ((grub_uint32_t *) *target) + 1; ++} ++ ++void ++grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) ++{ ++ write_reg (1, addr, &rels); ++ write_jump (1, &rels); ++} ++ ++void ++grub_cpu_relocator_backward (void *ptr0, void *src, void *dest, ++ grub_size_t size) ++{ ++ void *ptr = ptr0; ++ write_reg (8, (grub_uint64_t) src, &ptr); ++ write_reg (9, (grub_uint64_t) dest, &ptr); ++ write_reg (10, (grub_uint64_t) size, &ptr); ++ grub_memcpy (ptr, &grub_relocator_backward_start, ++ RELOCATOR_SRC_SIZEOF (backward)); ++} ++ ++void ++grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, ++ grub_size_t size) ++{ ++ void *ptr = ptr0; ++ write_reg (8, (grub_uint64_t) src, &ptr); ++ write_reg (9, (grub_uint64_t) dest, &ptr); ++ write_reg (10, (grub_uint64_t) size, &ptr); ++ grub_memcpy (ptr, &grub_relocator_forward_start, ++ RELOCATOR_SRC_SIZEOF (forward)); ++} ++ ++grub_err_t ++grub_relocator64_boot (struct grub_relocator *rel, ++ struct grub_relocator64_state state) ++{ ++ grub_relocator_chunk_t ch; ++ void *ptr; ++ grub_err_t err; ++ void *relst; ++ grub_size_t relsize; ++ grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF; ++ unsigned i; ++ grub_addr_t vtarget; ++ ++ err = grub_relocator_alloc_chunk_align (rel, &ch, 0x3000000, ++ (0xffffffff - stateset_size) ++ + 1, stateset_size, ++ grub_relocator_align, ++ GRUB_RELOCATOR_PREFERENCE_NONE, 0); ++ if (err) ++ return err; ++ ++ ptr = get_virtual_current_address (ch); ++ for (i = 1; i < 32; i++) ++ write_reg (i, state.gpr[i], &ptr); ++ write_jump (state.jumpreg, &ptr); ++ ++ vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch), ++ stateset_size); ++ ++ err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize); ++ if (err) ++ return err; ++ ++ grub_arch_sync_caches ((void *) relst, relsize); ++ ++ asm volatile ( ++ "ibar 0 \n"); ++ ++ grub_uint64_t val; ++ __asm__ __volatile__( ++ "li.w %0, 0x4\n\t" ++ "csrxchg $r0, %0, 0x0\n\t" ++ : "=r"(val) ++ : ++ : ++ ); ++ ++ ((void (*) (void)) relst) (); ++ ++ /* Not reached. */ ++ return GRUB_ERR_NONE; ++} +diff --git a/grub-core/lib/loongarch64/relocator_asm.S b/grub-core/lib/loongarch64/relocator_asm.S +new file mode 100644 +index 000000000000..ffdccc903e5f +--- /dev/null ++++ b/grub-core/lib/loongarch64/relocator_asm.S +@@ -0,0 +1,51 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Free Software Foundation, Inc. ++ * ++ * 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 . ++ */ ++ ++#include ++ ++ .p2align 4 /* force 16-byte alignment */ ++ ++VARIABLE (grub_relocator_forward_start) ++ ++copycont1: ++ ld.d $r11,$r8,0 ++ st.d $r11,$r9,0 ++ addi.d $r8, $r8, 8 ++ addi.d $r10, $r10, -8 ++ addi.d $r9, $r9, 8 ++ bne $r10, $r0, copycont1 ++ ++VARIABLE (grub_relocator_forward_end) ++ ++VARIABLE (grub_relocator_backward_start) ++ ++ add.d $r9, $r9, $r10 ++ add.d $r8, $r8, $r10 ++ /* Backward movsl is implicitly off-by-one. compensate that. */ ++ addi.d $r9, $r9, -8 ++ addi.d $r8, $r8, -8 ++copycont2: ++ ld.w $r11,$r8,0 ++ st.w $r11,$r9,0 ++ addi.d $r8, $r8, -8 ++ addi.d $r10, $r10, -8 ++ addi.d $r9, $r9, -8 ++ bne $r10, $r0, copycont2 ++ ++VARIABLE (grub_relocator_backward_end) ++ +diff --git a/grub-core/loader/loongarch64/linux-efi.c b/grub-core/loader/loongarch64/linux-efi.c +new file mode 100644 +index 000000000000..8e2726163725 +--- /dev/null ++++ b/grub-core/loader/loongarch64/linux-efi.c +@@ -0,0 +1,102 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2021 Free Software Foundation, Inc. ++ * ++ * 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 . ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#define GRUB_EFI_PE_MAGIC 0x5A4D ++ ++grub_err_t ++finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params) ++{ ++ return grub_loongarch_setup_initrd_params(); ++} ++ ++grub_err_t ++grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) ++{ ++ if ((lh->code0 & 0xffff) == GRUB_EFI_PE_MAGIC) ++ return GRUB_ERR_NONE; ++ else ++ return 1; ++ ++ grub_dprintf ("linux", "UEFI stub kernel:\n"); ++ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset); ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) ++{ ++ grub_efi_memory_mapped_device_path_t *mempath; ++ grub_efi_handle_t image_handle; ++ grub_efi_boot_services_t *b; ++ grub_efi_status_t status; ++ grub_efi_loaded_image_t *loaded_image; ++ int len; ++ ++ mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); ++ if (!mempath) ++ return grub_errno; ++ ++ mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; ++ mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; ++ mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); ++ mempath[0].memory_type = GRUB_EFI_LOADER_DATA; ++ mempath[0].start_address = addr; ++ mempath[0].end_address = addr + size; ++ ++ mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; ++ mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; ++ mempath[1].header.length = sizeof (grub_efi_device_path_t); ++ ++ b = grub_efi_system_table->boot_services; ++ status = b->load_image (0, grub_efi_image_handle, ++ (grub_efi_device_path_t *) mempath, ++ (void *) addr, size, &image_handle); ++ if (status != GRUB_EFI_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); ++ ++ grub_dprintf ("linux", "linux command line: '%s'\n", args); ++ ++ /* Convert command line to UCS-2 */ ++ loaded_image = grub_efi_get_loaded_image (image_handle); ++ loaded_image->load_options_size = len = ++ (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t); ++ loaded_image->load_options = ++ grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); ++ if (!loaded_image->load_options) ++ return grub_errno; ++ ++ loaded_image->load_options_size = ++ 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, ++ (grub_uint8_t *) args, len, NULL); ++ ++ grub_dprintf ("linux", "starting image %p\n", image_handle); ++ status = b->start_image (image_handle, 0, NULL); ++ ++ /* When successful, not reached */ ++ b->unload_image (image_handle); ++ grub_efi_free_pages ((grub_addr_t) loaded_image->load_options, ++ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); ++ ++ return grub_errno; ++} +diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c +new file mode 100644 +index 000000000000..c5d943437ed8 +--- /dev/null ++++ b/grub-core/loader/loongarch64/linux-elf.c +@@ -0,0 +1,896 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2021 Free Software Foundation, Inc. ++ * ++ * 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define GRUB_EFI_MMAP_NR_SLACK_SLOTS 8 ++ ++#define GRUB_ADDRESS_TYPE_SYSRAM 1 ++#define GRUB_ADDRESS_TYPE_RESERVED 2 ++#define GRUB_ADDRESS_TYPE_ACPI 3 ++#define GRUB_ADDRESS_TYPE_NVS 4 ++#define GRUB_ADDRESS_TYPE_PMEM 5 ++ ++#define GRUB_EFI_LOONGSON_BPI_TABLE_GUID \ ++ { 0x4660f721, 0x2ec5, 0x416a, \ ++ { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ ++ } ++ ++#define GRUB_EFI_LARCH_SCREEN_INFO_GUID \ ++ { 0x07fd51a6, 0x9532, 0x926f, \ ++ { 0x51, 0xdc, 0x6a, 0x63, 0x60, 0x2f, 0x84, 0xb4 } \ ++ } ++ ++#define GRUB_EFI_LARCH_CONSOLE_OUT_DEVICE_GUID \ ++ { 0xd3b36f2c, 0xd551, 0x11d4, \ ++ { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ ++ } ++ ++#define GRUB_EFI_LARCH_BOOT_MEMMAP_GUID \ ++ { 0x800f683f, 0xd08b, 0x423a, \ ++ { 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4 } \ ++ } ++ ++#define GRUB_EFI_LARCH_INITRD_MEDIA_GUID \ ++ { 0x5568e427, 0x68fc, 0x4f3d, \ ++ { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \ ++ } ++ ++#define GRUB_EFI_SCREEN_INFO_GUID \ ++ { 0xe03fc20a, 0x85dc, 0x406e, \ ++ { 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95 } \ ++ } ++ ++static struct grub_relocator *relocator; ++static grub_guid_t compat_screen_info_guid = GRUB_EFI_LARCH_SCREEN_INFO_GUID; ++static grub_guid_t screen_info_guid = GRUB_EFI_SCREEN_INFO_GUID; ++ ++void grub_linux_loongarch_elf_relocator_unload (void) ++{ ++ grub_relocator_unload (relocator); ++} ++ ++static void ++find_bits (unsigned long mask, grub_efi_uint8_t *pos, grub_efi_uint8_t *size) ++{ ++ grub_efi_uint8_t first, len; ++ ++ first = 0; ++ len = 0; ++ ++ if (mask) ++ { ++ while (!(mask & 0x1)) ++ { ++ mask = mask >> 1; ++ first++; ++ } ++ ++ while (mask & 0x1) ++ { ++ mask = mask >> 1; ++ len++; ++ } ++ } ++ ++ *pos = first; ++ *size = len; ++} ++ ++static void ++setup_pixel_info (struct screen_info *si, grub_efi_uint32_t pixels_per_scan_line, ++ struct grub_efi_gop_pixel_bitmask pixel_info, int pixel_format) ++{ ++ if (pixel_format == GRUB_EFI_GOT_RGBA8) ++ { ++ si->lfb_depth = 32; ++ si->lfb_linelength = pixels_per_scan_line * 4; ++ si->red_size = 8; ++ si->red_pos = 0; ++ si->green_size = 8; ++ si->green_pos = 8; ++ si->blue_size = 8; ++ si->blue_pos = 16; ++ si->rsvd_size = 8; ++ si->rsvd_pos = 24; ++ } ++ else if (pixel_format == GRUB_EFI_GOT_BGRA8) ++ { ++ si->lfb_depth = 32; ++ si->lfb_linelength = pixels_per_scan_line * 4; ++ si->red_size = 8; ++ si->red_pos = 16; ++ si->green_size = 8; ++ si->green_pos = 8; ++ si->blue_size = 8; ++ si->blue_pos = 0; ++ si->rsvd_size = 8; ++ si->rsvd_pos = 24; ++ } ++ else if (pixel_format == GRUB_EFI_GOT_BITMASK) ++ { ++ find_bits(pixel_info.r, &si->red_pos, &si->red_size); ++ find_bits(pixel_info.g, &si->green_pos, &si->green_size); ++ find_bits(pixel_info.b, &si->blue_pos, &si->blue_size); ++ find_bits(pixel_info.a, &si->rsvd_pos, &si->rsvd_size); ++ si->lfb_depth = si->red_size + si->green_size + ++ si->blue_size + si->rsvd_size; ++ si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) / 8; ++ } ++ else ++ { ++ si->lfb_depth = 4; ++ si->lfb_linelength = si->lfb_width / 2; ++ si->red_size = 0; ++ si->red_pos = 0; ++ si->green_size = 0; ++ si->green_pos = 0; ++ si->blue_size = 0; ++ si->blue_pos = 0; ++ si->rsvd_size = 0; ++ si->rsvd_pos = 0; ++ } ++} ++ ++static struct screen_info * ++alloc_screen_info (void) ++{ ++ grub_efi_status_t status; ++ grub_efi_boot_services_t *b; ++ struct screen_info *si; ++ ++ b = grub_efi_system_table->boot_services; ++ status = b->allocate_pool (GRUB_EFI_RUNTIME_SERVICES_DATA, ++ sizeof(*si), (void**)&si); ++ if (status != GRUB_EFI_SUCCESS) ++ return NULL; ++ ++ status = b->install_configuration_table (&compat_screen_info_guid, si); ++ if (status != GRUB_EFI_SUCCESS) ++ goto free_mem; ++ ++ status = b->install_configuration_table (&screen_info_guid, si); ++ if (status == GRUB_EFI_SUCCESS) ++ return si; ++ ++free_table: ++ b->install_configuration_table (&compat_screen_info_guid, NULL); ++free_mem: ++ b->free_pool (si); ++ ++ return NULL; ++} ++ ++static struct screen_info * ++setup_screen_info (void) ++{ ++ grub_efi_boot_services_t *b; ++ grub_efi_handle_t gop_handle; ++ struct screen_info *si = NULL; ++ struct grub_efi_gop *gop, *first_gop; ++ grub_efi_handle_t *handles; ++ grub_efi_uintn_t num_handles, i; ++ grub_guid_t graphics_output_guid = GRUB_EFI_GOP_GUID; ++ grub_efi_uint16_t width, height; ++ grub_efi_uint32_t ext_lfb_base, pixels_per_scan_line; ++ grub_efi_uint64_t fb_base; ++ struct grub_efi_gop_pixel_bitmask pixel_info; ++ grub_efi_gop_pixel_format_t pixel_format; ++ ++ si = alloc_screen_info(); ++ if (!si) ++ return NULL; ++ ++ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, ++ &graphics_output_guid, NULL, &num_handles); ++ if (!handles || num_handles == 0) ++ goto free_screen_info; ++ ++ gop = NULL; ++ first_gop = NULL; ++ ++ for (i = 0; i < num_handles; i++) ++ { ++ struct grub_efi_gop_mode *mode; ++ struct grub_efi_gop_mode_info *info = NULL; ++ grub_guid_t conout_proto = GRUB_EFI_LARCH_CONSOLE_OUT_DEVICE_GUID; ++ void *dummy = NULL; ++ grub_efi_uint8_t conout_found = 0; ++ grub_efi_uint64_t current_fb_base; ++ ++ gop_handle = handles[i]; ++ gop = grub_efi_open_protocol (gop_handle, &graphics_output_guid, ++ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ ++ dummy = grub_efi_open_protocol (gop_handle, &conout_proto, ++ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (dummy != NULL) ++ conout_found = 1; ++ ++ mode = gop->mode; ++ info = mode->info; ++ current_fb_base = mode->fb_base; ++ ++ if ((!first_gop || conout_found) && ++ info->pixel_format != GRUB_EFI_GOT_BLT_ONLY) ++ { ++ /* ++ * Systems that use the UEFI Console Splitter may ++ * provide multiple GOP devices, not all of which are ++ * backed by real hardware. The workaround is to search ++ * for a GOP implementing the ConOut protocol, and if ++ * one isn't found, to just fall back to the first GOP. ++ */ ++ width = info->width; ++ height = info->height; ++ pixel_format = info->pixel_format; ++ pixel_info = info->pixel_bitmask; ++ pixels_per_scan_line = info->pixels_per_scanline; ++ fb_base = current_fb_base; ++ ++ /* ++ * Once we've found a GOP supporting ConOut, ++ * don't bother looking any further. ++ */ ++ first_gop = gop; ++ if (conout_found) ++ break; ++ } ++ } ++ ++ /* Did we find any GOPs? */ ++ if (!first_gop) ++ goto free_screen_info; ++ ++ /* EFI framebuffer */ ++ si->orig_video_isVGA = GRUB_VIDEO_TYPE_EFI; ++ ++ si->lfb_width = width; ++ si->lfb_height = height; ++ si->lfb_base = fb_base; ++ grub_dprintf ("loongson", "Screen info fb base: 0x%"PRIxGRUB_UINT32_T"\n", ++ si->lfb_base); ++ ++ ext_lfb_base = (grub_uint64_t)fb_base >> 32; ++ if (ext_lfb_base) { ++ si->capabilities |= GRUB_VIDEO_CAPABILITY_64BIT_BASE; ++ si->ext_lfb_base = ext_lfb_base; ++ } ++ si->pages = 1; ++ ++ setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format); ++ ++ si->lfb_size = si->lfb_linelength * si->lfb_height; ++ si->capabilities |= GRUB_VIDEO_CAPABILITY_SKIP_QUIRKS; ++ ++ return si; ++ ++free_screen_info: ++ b = grub_efi_system_table->boot_services; ++ b->install_configuration_table (&compat_screen_info_guid, NULL); ++ b->install_configuration_table (&screen_info_guid, NULL); ++ if (si) ++ b->free_pool (si); ++ ++ grub_dprintf ("loongson", "No screen info\n"); ++ return NULL; ++} ++ ++static grub_err_t ++allocate_memmap_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) ++{ ++ grub_err_t err; ++ grub_efi_status_t status; ++ grub_efi_uintn_t mmap_size, desc_size, size; ++ grub_efi_uint32_t desc_version; ++ grub_efi_memory_descriptor_t *mmap_buf; ++ grub_efi_boot_services_t *b; ++ struct efi_boot_memmap *m, tmp; ++ grub_guid_t boot_memmap_guid = GRUB_EFI_LARCH_BOOT_MEMMAP_GUID; ++ ++ setup_screen_info(); ++ ++ grub_dprintf ("loongson", "ramdisk_addr:0x%"PRIxGRUB_UINT64_T", \ ++ size:0x%"PRIxGRUB_UINT64_T"\n", ++ kernel_params->ramdisk_addr, ++ kernel_params->ramdisk_size); ++ ++ /* Set initrd info to system table*/ ++ err = grub_loongarch_setup_initrd_params(); ++ if (err != GRUB_ERR_NONE) ++ { ++ grub_error(GRUB_ERR_IO, "failed to install initrd media"); ++ return err; ++ } ++ ++ tmp.map_size = 0; ++ status = grub_efi_get_memory_map (&tmp.map_size, NULL, &tmp.map_key, ++ &tmp.desc_size, &tmp.desc_ver); ++ if (status != 0) { ++ grub_error (GRUB_ERR_IO, "cannot get memory map"); ++ goto uninstall_initrd_table; ++ } ++ size = tmp.map_size + tmp.desc_size * GRUB_EFI_MMAP_NR_SLACK_SLOTS; ++ m = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(*m) + size)); ++ if (!m) { ++ grub_error (GRUB_ERR_IO, "cannot allocate m memory"); ++ goto uninstall_initrd_table; ++ } ++ ++ b = grub_efi_system_table->boot_services; ++ status = b->install_configuration_table (&boot_memmap_guid, m); ++ if (status != GRUB_EFI_SUCCESS) { ++ grub_error (GRUB_ERR_IO, "failed to install boot memmap"); ++ goto free_m; ++ } ++ ++ m->buff_size = m->map_size = size; ++ if (grub_efi_get_memory_map (&m->map_size, m->map, ++ &m->map_key, &m->desc_size, ++ &m->desc_ver) <= 0) ++ { ++ grub_error (GRUB_ERR_IO, "cannot get EFI memory map"); ++ goto uninstall_mem_table; ++ } ++ ++ mmap_size = grub_efi_find_mmap_size (); ++ if (! mmap_size) ++ goto uninstall_mem_table; ++ ++ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); ++ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, ++ &desc_size, &desc_version); ++ if (err) { ++ grub_error (GRUB_ERR_IO, "failed to finish boot services"); ++ goto free_map; ++ } ++ ++ return 0; ++ ++free_map: ++ if (mmap_buf) ++ grub_efi_free_pages ((grub_addr_t) mmap_buf, ++ GRUB_EFI_BYTES_TO_PAGES (mmap_size)); ++ ++uninstall_mem_table: ++ b->install_configuration_table (&boot_memmap_guid, NULL); ++ ++free_m: ++ if (m) ++ grub_efi_free_pages ((grub_addr_t) m, ++ GRUB_EFI_BYTES_TO_PAGES (sizeof(*m) + size)); ++ ++uninstall_initrd_table: ++ grub_loongarch_remove_initrd_params(); ++ ++ return grub_error(GRUB_ERR_BAD_OS, "failed to V40 boot"); ++} ++ ++static grub_err_t ++allocate_fdt_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) ++{ ++ int node, retval; ++ grub_err_t err; ++ unsigned int size; ++ grub_efi_uintn_t mmap_size; ++ grub_efi_uintn_t desc_size; ++ grub_efi_uint32_t desc_version; ++ grub_efi_memory_descriptor_t *mmap_buf; ++ ++ size = GRUB_FDT_EMPTY_TREE_SZ + FDT_ADDR_SIZE_EXTRA + GRUB_EFI_LINUX_FDT_EXTRA_SPACE; ++ ++ kernel_params->fdt = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (size)); ++ if (!kernel_params->fdt) ++ return GRUB_ERR_OUT_OF_MEMORY; ++ ++ grub_fdt_create_empty_tree (kernel_params->fdt, size); ++ grub_fdt_set_prop32 (kernel_params->fdt, 0, FDT_ADDR_CELLS_STRING, 2); ++ grub_fdt_set_prop32 (kernel_params->fdt, 0, FDT_SIZE_CELLS_STRING, 2); ++ ++ node = grub_fdt_find_subnode (kernel_params->fdt, 0, "chosen"); ++ if (node < 0) ++ node = grub_fdt_add_subnode (kernel_params->fdt, 0, "chosen"); ++ if (node < 1) ++ goto failure; ++ ++ grub_dprintf ("loongson", "command_line %s, len %ld\n", ++ (char *)kernel_params->linux_args, ++ grub_strlen(kernel_params->linux_args) + 1); ++ if ((kernel_params->linux_args != NULL) && (grub_strlen(kernel_params->linux_args) > 0)) { ++ retval = grub_fdt_set_prop (kernel_params->fdt, node, "bootargs", kernel_params->linux_args, ++ grub_strlen(kernel_params->linux_args) + 1); ++ if (retval) ++ goto failure; ++ } ++ ++ /* Set initrd info */ ++ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) ++ { ++ grub_dprintf ("linux", "Initrd @ %p-%p\n", ++ (void *) kernel_params->ramdisk_addr, ++ (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); ++ ++ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,initrd-start", ++ kernel_params->ramdisk_addr); ++ if (retval) ++ goto failure; ++ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,initrd-end", ++ (grub_uint64_t) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); ++ if (retval) ++ goto failure; ++ } ++ ++ node = grub_fdt_find_subnode (kernel_params->fdt, 0, "chosen"); ++ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,uefi-system-table", ++ (grub_uint64_t)grub_efi_system_table); ++ if (retval) ++ goto failure; ++ ++ mmap_size = grub_efi_find_mmap_size (); ++ if (! mmap_size) ++ return grub_errno; ++ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); ++ if (! mmap_buf) ++ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); ++ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, ++ &desc_size, &desc_version); ++ if (err) ++ return err; ++ ++ if (!mmap_buf || !mmap_size || !desc_size) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,uefi-mmap-start", ++ (grub_uint64_t)mmap_buf); ++ if (retval) ++ goto failure; ++ ++ retval = grub_fdt_set_prop32 (kernel_params->fdt, node, "linux,uefi-mmap-size", ++ mmap_size); ++ if (retval) ++ goto failure; ++ ++ retval = grub_fdt_set_prop32 (kernel_params->fdt, node, "linux,uefi-mmap-desc-size", ++ desc_size); ++ if (retval) ++ goto failure; ++ ++ retval = grub_fdt_set_prop32 (kernel_params->fdt, node, "linux,uefi-mmap-desc-ver", ++ desc_version); ++ if (retval) ++ goto failure; ++ ++ return GRUB_ERR_NONE; ++ ++failure: ++ if (!kernel_params->fdt) { ++ return GRUB_ERR_BAD_OS; ++ } ++ grub_efi_free_pages ((grub_addr_t) kernel_params->fdt, ++ GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (kernel_params->fdt))); ++ kernel_params->fdt = NULL; ++ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); ++} ++ ++static void ++grub_linux_loongarch_elf_make_argv (struct linux_loongarch64_kernel_params *kernel_params) ++{ ++ static void* linux_args_addr; ++ int size; ++ grub_uint64_t *linux_argv; ++ char *args, *p, *linux_args; ++ int i, argc; ++ grub_err_t err; ++ ++ argc = kernel_params->linux_argc; ++ args = kernel_params->linux_args; ++ ++ /* new size */ ++ p = args; ++ size = (argc + 3 + 1) * sizeof (grub_uint64_t); /* orig arguments */ ++ for (i = 0; i < argc; i++) ++ { ++ size += ALIGN_UP (grub_strlen (p) + 1, 4); ++ p += grub_strlen (p) + 1; ++ } ++ ++ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) ++ { ++ size += ALIGN_UP (sizeof (GRUB_RD_START_STRING), 4) ++ + ALIGN_UP (sizeof (GRUB_RD_SIZE_STRING), 4) ++ + ALIGN_UP (sizeof (GRUB_INITRD_STRING), 4); ++ } ++ size = ALIGN_UP (size, 8); ++ ++ /* alloc memory */ ++ linux_args_addr = grub_linux_loongarch_alloc_virtual_mem_align (size, 8, &err); ++ ++ linux_argv = linux_args_addr; ++ linux_args = (char *)(linux_argv + (argc + 1 + 3)); ++ p = args; ++ for (i = 0; i < argc; i++) ++ { ++ grub_memcpy (linux_args, p, grub_strlen (p) + 1); ++ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; ++ linux_argv++; ++ linux_args += ALIGN_UP (grub_strlen (p) + 1, 4); ++ p += grub_strlen (p) + 1; ++ } ++ ++ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) ++ { ++ /* rd_start */ ++ grub_snprintf (linux_args, ++ sizeof (GRUB_RD_START_STRING), ++ "rd_start=0x%lx", ++ (grub_uint64_t) kernel_params->ramdisk_addr); ++ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; ++ linux_argv++; ++ linux_args += ALIGN_UP (sizeof (GRUB_RD_START_STRING), 4); ++ kernel_params->linux_argc++; ++ ++ /* rd_size */ ++ grub_snprintf (linux_args, ++ sizeof (GRUB_RD_SIZE_STRING), ++ "rd_size=0x%lx", ++ (grub_uint64_t) kernel_params->ramdisk_size); ++ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; ++ linux_argv++; ++ linux_args += ALIGN_UP (sizeof (GRUB_RD_SIZE_STRING), 4); ++ kernel_params->linux_argc++; ++ ++ /* initrd */ ++ grub_snprintf (linux_args, ++ sizeof (GRUB_INITRD_STRING), ++ "initrd=0x%lx,0x%lx", ++ ((grub_uint64_t) kernel_params->ramdisk_addr & 0xffffffff), ++ (grub_uint64_t) kernel_params->ramdisk_size); ++ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; ++ linux_argv++; ++ linux_args += ALIGN_UP (sizeof (GRUB_INITRD_STRING), 4); ++ kernel_params->linux_argc++; ++ } ++ ++ /* Reserve space for initrd arguments. */ ++ *linux_argv = 0; ++ ++ grub_free (kernel_params->linux_args); ++ kernel_params->linux_argv = (grub_addr_t) linux_args_addr; ++} ++ ++grub_err_t ++grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_params ++ *kernel_params) ++{ ++ struct boot_params_interface *boot_params = NULL; ++ struct grub_relocator64_state state; ++ grub_err_t err; ++ ++ /* linux kernel type is ELF */ ++ grub_memset (&state, 0, sizeof (state)); ++ ++ state.jumpreg = 1; ++ state.gpr[1] = kernel_params->kernel_addr; /* ra */ ++ if (grub_linux_loongarch_elf_get_boot_params (&boot_params) == 0) ++ { ++ grub_dprintf("loongson", "V4.0 boot\n"); ++ if (allocate_memmap_and_exit_boot (kernel_params) != GRUB_ERR_NONE) ++ return grub_errno; ++ state.gpr[4] = 1 << FLAGS_EFI_SUPPORT_BIT; /* a0 = flag */ ++ state.gpr[5] = (grub_uint64_t)kernel_params->linux_args; /* a1 = cmdline */ ++ state.gpr[6] = (grub_uint64_t)grub_efi_system_table; /* a2 = system_table */ ++ } else { ++ grub_dprintf("loongson", "BPI boot\n"); ++ grub_linux_loongarch_elf_make_argv (kernel_params); ++ state.gpr[4] = kernel_params->linux_argc; /* a0 = argc */ ++ state.gpr[5] = kernel_params->linux_argv; /* a1 = args */ ++ state.gpr[6] = (grub_uint64_t) boot_params; /* a2 = envp */ ++ err = grub_linux_loongarch_elf_boot_params (boot_params); ++ if (err) ++ return err; ++ } ++ ++ /* Boot the ELF kernel */ ++ grub_relocator64_boot (relocator, state); ++ ++ return GRUB_ERR_NONE; ++} ++ ++void* ++grub_linux_loongarch_alloc_virtual_mem_addr (grub_addr_t addr, ++ grub_size_t size, ++ grub_err_t *err) ++{ ++ relocator = grub_relocator_new (); ++ if (!relocator) ++ return NULL; ++ ++ grub_relocator_chunk_t ch; ++ *err = grub_relocator_alloc_chunk_addr (relocator, &ch, ++ grub_vtop ((void *) addr), ++ size); ++ if (*err) ++ return NULL; ++ return get_virtual_current_address (ch); ++} ++ ++void* ++grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, ++ grub_size_t align, ++ grub_err_t *err) ++{ ++ grub_relocator_chunk_t ch; ++ ++ *err = grub_relocator_alloc_chunk_align (relocator, &ch, ++ 0, (0xffffffff - size) + 1, ++ size, align, ++ GRUB_RELOCATOR_PREFERENCE_LOW, 0); ++ return get_virtual_current_address (ch); ++} ++ ++void* ++grub_linux_loongarch_alloc_initrd_mem_align (grub_size_t size, ++ grub_size_t align, ++ grub_err_t *err) ++{ ++ grub_relocator_chunk_t ch; ++ ++ /* Firstly try to allocate from memory higher than 256MB */ ++ *err = grub_relocator_alloc_chunk_align (relocator, &ch, ++ 0x10000000, (0xffffffff - size) + 1, size, align, ++ GRUB_RELOCATOR_PREFERENCE_LOW, 0); ++ if (*err != GRUB_ERR_NONE) ++ { ++ /* Failed, try to allocate in range 0 ~ 256MB */ ++ *err = grub_relocator_alloc_chunk_align (relocator, &ch, ++ 0, (0xfffffff - size) + 1, size, align, ++ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); ++ } ++ return get_virtual_current_address (ch); ++} ++ ++int ++grub_linux_loongarch_elf_get_boot_params (struct boot_params_interface **boot_params) ++{ ++ grub_efi_configuration_table_t *tables; ++ grub_guid_t bpi_guid = GRUB_EFI_LOONGSON_BPI_TABLE_GUID; ++ unsigned int i; ++ int found = 0; ++ ++ /* Look for Loongson BPI in UEFI config tables. */ ++ tables = grub_efi_system_table->configuration_table; ++ ++ for (i = 0; i < grub_efi_system_table->num_table_entries; i++) ++ if (grub_memcmp (&tables[i].vendor_guid, &bpi_guid, sizeof (bpi_guid)) == 0) ++ { ++ *boot_params = tables[i].vendor_table; ++ char *p = (char*) &((*boot_params)->signature); ++ if (grub_strncmp (p, "BPI", 3) == 0) ++ { ++ found = 1; ++ break; ++ } ++ } ++ return found; ++} ++ ++static grub_uint8_t ++grub_kernel_update_checksum (const grub_uint8_t *buffer, grub_efi_uintn_t length) ++{ ++ grub_uint8_t sum; ++ grub_efi_uintn_t count; ++ ++ for (sum = 0, count = 0; count < length; count++) ++ { ++ sum = (grub_uint8_t) (sum + *(buffer + count)); ++ } ++ ++ return (grub_uint8_t) (0x100 - sum); ++} ++ ++static grub_uint32_t ++grub_efi_loongarch64_memmap_sort (struct memmap array[], ++ grub_uint32_t length, ++ struct loongsonlist_mem_map* bpmem, ++ grub_uint32_t index, ++ grub_uint32_t memtype) ++{ ++ grub_uint64_t tempmemsize = 0; ++ grub_uint32_t j = 0; ++ grub_uint32_t t = 0; ++ ++ for(j = 0; j < length;) ++ { ++ tempmemsize = array[j].mem_size; ++ for(t = j + 1; t < length; t++) ++ { ++ if(array[j].mem_start + tempmemsize == array[t].mem_start) ++ { ++ tempmemsize += array[t].mem_size; ++ } ++ else ++ { ++ break; ++ } ++ } ++ bpmem->map[index].mem_type = memtype; ++ bpmem->map[index].mem_start = array[j].mem_start; ++ bpmem->map[index].mem_size = tempmemsize; ++ grub_printf("map[%d]:type %"PRIuGRUB_UINT32_T", start 0x%" ++ PRIxGRUB_UINT64_T", end 0x%"PRIxGRUB_UINT64_T"\n", ++ index, ++ bpmem->map[index].mem_type, ++ bpmem->map[index].mem_start, ++ bpmem->map[index].mem_start+ bpmem->map[index].mem_size ++ ); ++ j = t; ++ index++; ++ } ++ return index; ++} ++ ++grub_err_t ++grub_linux_loongarch_elf_boot_params (struct boot_params_interface *boot_params) ++{ ++ grub_int8_t checksum = 0; ++ grub_err_t err; ++ ++ struct loongsonlist_mem_map *loongson_mem_map = NULL; ++ struct _extention_list_hdr * listpointer = NULL; ++ grub_uint32_t tmp_index = 0; ++ grub_efi_memory_descriptor_t * lsdesc = NULL; ++ ++ grub_uint32_t free_index = 0; ++ grub_uint32_t reserve_index = 0; ++ grub_uint32_t acpi_table_index = 0; ++ grub_uint32_t acpi_nvs_index = 0; ++ ++ grub_efi_uintn_t mmap_size; ++ grub_efi_uintn_t desc_size; ++ grub_efi_memory_descriptor_t *mmap_buf; ++ ++ struct memmap reserve_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; ++ struct memmap free_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; ++ struct memmap acpi_table_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; ++ struct memmap acpi_nvs_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; ++ ++ grub_memset (reserve_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); ++ grub_memset (free_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); ++ grub_memset (acpi_table_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); ++ grub_memset (acpi_nvs_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); ++ ++ /* Check extlist headers */ ++ listpointer = boot_params->extlist; ++ for( ;listpointer != NULL; listpointer = listpointer->next) ++ { ++ char *pl= (char *)&(listpointer->signature); ++ if(grub_strncmp(pl, "MEM", 3) == 0) ++ { ++ loongson_mem_map = (struct loongsonlist_mem_map *)listpointer; ++ break; ++ } ++ } ++ ++ mmap_size = grub_efi_find_mmap_size (); ++ if (! mmap_size) ++ return grub_errno; ++ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); ++ if (! mmap_buf) ++ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); ++ ++ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, ++ &desc_size, NULL); ++ if (err) ++ return err; ++ ++ if (!mmap_buf || !mmap_size || !desc_size) ++ return -1; ++ ++ /* ++ According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ ++ now we can fill platform specific memory structure. ++ */ ++ for (lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); ++ lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) ++ { ++ /* System RAM */ ++ if((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ ++ (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ ++ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ ++ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ ++ (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ ++ (lsdesc->type != GRUB_EFI_PAL_CODE)) ++ { ++ free_mem[free_index].mem_type = GRUB_ADDRESS_TYPE_SYSRAM; ++ free_mem[free_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ free_mem[free_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; ++ free_index++; ++ ++ /*ACPI*/ ++ }else if((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ ++ acpi_table_mem[acpi_table_index].mem_type = GRUB_ADDRESS_TYPE_ACPI; ++ acpi_table_mem[acpi_table_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ acpi_table_mem[acpi_table_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; ++ acpi_table_index++; ++ }else if((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ ++ acpi_nvs_mem[acpi_nvs_index].mem_type = GRUB_ADDRESS_TYPE_NVS; ++ acpi_nvs_mem[acpi_nvs_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ acpi_nvs_mem[acpi_nvs_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; ++ acpi_nvs_index++; ++ ++ /* Reserve */ ++ }else{ ++ reserve_mem[reserve_index].mem_type = GRUB_ADDRESS_TYPE_RESERVED; ++ reserve_mem[reserve_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ reserve_mem[reserve_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; ++ reserve_index++; ++ } ++ } ++ ++ tmp_index = loongson_mem_map->map_count; ++ /*System RAM Sort*/ ++ tmp_index = grub_efi_loongarch64_memmap_sort(free_mem, ++ free_index, ++ loongson_mem_map, ++ tmp_index, ++ GRUB_ADDRESS_TYPE_SYSRAM); ++ /*ACPI Sort*/ ++ tmp_index = grub_efi_loongarch64_memmap_sort(acpi_table_mem, ++ acpi_table_index, ++ loongson_mem_map, ++ tmp_index, ++ GRUB_ADDRESS_TYPE_ACPI); ++ tmp_index = grub_efi_loongarch64_memmap_sort(acpi_nvs_mem, ++ acpi_nvs_index, ++ loongson_mem_map, ++ tmp_index, ++ GRUB_ADDRESS_TYPE_NVS); ++ ++ /*Reserve Sort*/ ++ { ++ grub_uint64_t loongarch_addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (loongarch_addr)); ++ if ((loongarch_addr & 0xff00000000000000) == 0x9000000000000000) ++ tmp_index = grub_efi_loongarch64_memmap_sort(reserve_mem, ++ reserve_index, ++ loongson_mem_map, ++ tmp_index, ++ GRUB_ADDRESS_TYPE_RESERVED); ++ else ++ tmp_index = grub_efi_loongarch64_memmap_sort(reserve_mem, ++ reserve_index, ++ loongson_mem_map, ++ tmp_index, ++ GRUB_ADDRESS_TYPE_RESERVED + 1); ++ } ++ loongson_mem_map->map_count = tmp_index; ++ loongson_mem_map->header.checksum = 0; ++ ++ checksum = grub_kernel_update_checksum ((grub_uint8_t *) loongson_mem_map, ++ loongson_mem_map->header.length); ++ loongson_mem_map->header.checksum = checksum; ++ ++ return grub_errno; ++} +diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c +new file mode 100644 +index 000000000000..7c8cd36fca15 +--- /dev/null ++++ b/grub-core/loader/loongarch64/linux.c +@@ -0,0 +1,437 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2021 Free Software Foundation, Inc. ++ * ++ * 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) ++ ++#define GRUB_EFI_LARCH_INITRD_MEDIA_GUID \ ++ { 0x5568e427, 0x68fc, 0x4f3d, \ ++ { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \ ++ } ++ ++static struct linux_loongarch64_kernel_params kernel_params; ++ ++static grub_addr_t phys_addr; ++static grub_dl_t my_mod; ++static int loaded; ++static int is_bpi_boot; ++static int grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_BAD; ++struct efi_initrd *initrd_tbl; ++ ++grub_err_t ++grub_loongarch_setup_initrd_params (void) ++{ ++ grub_efi_boot_services_t *b; ++ grub_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; ++ grub_efi_status_t status; ++ ++ if (!kernel_params.ramdisk_addr || !kernel_params.ramdisk_size) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("you need to load the initrd first")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ /* Set initrd info to system table*/ ++ b = grub_efi_system_table->boot_services; ++ initrd_tbl = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); ++ if (!initrd_tbl) ++ return grub_error (GRUB_ERR_IO, "cannot allocate tbl memory"); ++ ++ initrd_tbl->base = kernel_params.ramdisk_addr; ++ initrd_tbl->size = kernel_params.ramdisk_size; ++ status = b->install_configuration_table (&initrd_media_guid, initrd_tbl); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_error (GRUB_ERR_IO, "failed to install initrd media"); ++ goto free_tbl; ++ } ++ ++ return GRUB_ERR_NONE; ++ ++free_tbl: ++ if (initrd_tbl) ++ { ++ grub_efi_free_pages ((grub_addr_t) initrd_tbl, ++ GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); ++ } ++ ++ return GRUB_ERR_IO; ++} ++ ++void ++grub_loongarch_remove_initrd_params (void) ++{ ++ grub_efi_boot_services_t *b; ++ grub_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; ++ ++ if (!initrd_tbl) ++ return; ++ ++ b = grub_efi_system_table->boot_services; ++ b->install_configuration_table (&initrd_media_guid, NULL); ++ ++ grub_efi_free_pages ((grub_addr_t) initrd_tbl, ++ GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); ++ ++ initrd_tbl = NULL; ++} ++ ++ ++static grub_err_t ++grub_linux_boot (void) ++{ ++ ++ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_EFI) { ++ if (finalize_efi_params_linux (&kernel_params) != GRUB_ERR_NONE) ++ return grub_errno; ++ return (grub_arch_efi_linux_boot_image((grub_addr_t) kernel_params.kernel_addr, ++ kernel_params.kernel_size, ++ kernel_params.linux_args)); ++ } ++ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_ELF) { ++ return grub_linux_loongarch_elf_linux_boot_image (&kernel_params); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_linux_unload (void) ++{ ++ ++ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_EFI) { ++ if (kernel_params.ramdisk_addr) ++ grub_efi_free_pages ((grub_efi_physical_address_t) kernel_params.ramdisk_addr, ++ GRUB_EFI_BYTES_TO_PAGES (kernel_params.ramdisk_size)); ++ kernel_params.ramdisk_size = 0; ++ ++ if (kernel_params.kernel_addr) ++ grub_efi_free_pages ((grub_addr_t) kernel_params.kernel_addr, ++ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); ++ kernel_params.kernel_addr = 0; ++ } ++ ++ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_ELF) { ++ grub_free (kernel_params.linux_args); ++ kernel_params.linux_args = 0; ++ grub_linux_loongarch_elf_relocator_unload (); ++ } ++ ++ grub_dl_unref (my_mod); ++ loaded = 0; ++ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_BAD; ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_linux_loongarch_elf_load_kernel (grub_elf_t elf, const char *filename) ++{ ++ Elf64_Addr base; ++ grub_err_t err; ++ grub_uint8_t *playground; ++ grub_uint64_t addr; ++ int flag; ++ ++ /* Linux's entry point incorrectly contains a virtual address. */ ++ kernel_params.kernel_addr = elf->ehdr.ehdr64.e_entry; ++ kernel_params.kernel_size = grub_elf64_size (elf, &base, 0); ++ ++ if (kernel_params.kernel_size == 0) ++ return grub_errno; ++ ++ phys_addr = base; ++ kernel_params.kernel_size = ALIGN_UP (base + kernel_params.kernel_size - base, 8); ++ ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ if (addr & 0x1) { ++ flag = GRUB_ELF_LOAD_FLAGS_NONE; ++ } else { ++ flag = GRUB_ELF_LOAD_FLAGS_30BITS; ++ base &= ~ELF64_LOADMASK; ++ kernel_params.kernel_addr &= ~ELF64_LOADMASK; ++ } ++ ++ playground = grub_linux_loongarch_alloc_virtual_mem_addr (phys_addr, ++ kernel_params.kernel_size, ++ &err); ++ if (playground == NULL) ++ return err; ++ ++ /* Now load the segments into the area we claimed. */ ++ return grub_elf64_load (elf, filename, playground - base, ++ flag, 0, 0); ++} ++ ++static grub_err_t ++grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ grub_file_t file = 0; ++ struct linux_arch_kernel_header lh; ++ struct boot_params_interface *boot_params = NULL; ++ grub_elf_t elf = NULL; ++ grub_err_t err; ++ grub_size_t cmdline_size; ++ int i; ++ ++ grub_dl_ref (my_mod); ++ ++ /* Release the previously used memory. */ ++ grub_loader_unset (); ++ ++ if (argc == 0) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ goto fail; ++ } ++ ++ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); ++ if (!file) ++ goto fail; ++ ++ kernel_params.kernel_size = grub_file_size (file); ++ grub_dprintf ("linux", "kernel file size: %" PRIuGRUB_SIZE "\n", ++ kernel_params.kernel_size); ++ ++ if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) ++ return grub_errno; ++ ++ if (grub_arch_efi_linux_check_image (&lh) == GRUB_ERR_NONE) { ++ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_EFI; ++ } ++ ++ if (grub_loongarch_linux_type != GRUB_LOONGARCH_LINUX_EFI) { ++ elf = grub_elf_file (file, argv[0]); ++ if (elf != NULL) ++ { ++ /* linux kernel type is ELF */ ++ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_ELF; ++ if (elf->ehdr.ehdr64.e_type != ET_EXEC) ++ { ++ grub_error (GRUB_ERR_UNKNOWN_OS, ++ N_("this ELF file is not of the right type")); ++ goto fail; ++ } ++ if (elf->ehdr.ehdr64.e_machine != EM_LOONGARCH) ++ { ++ grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); ++ goto fail; ++ } ++ ++ if (grub_elf_is_elf64 (elf)) ++ { ++ err = grub_linux_loongarch_elf_load_kernel (elf, argv[0]); ++ if (err) ++ goto fail; ++ } else { ++ grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); ++ goto fail; ++ } ++ grub_dprintf ("linux", "kernel @ %p\n", (void*) elf->ehdr.ehdr64.e_entry); ++ } ++ } else { ++ if (grub_file_seek (file, 0) == (grub_off_t) -1) ++ goto fail; ++ ++ if (grub_file_read (file, &lh, sizeof (lh)) < (grub_ssize_t) sizeof (lh)) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), ++ argv[0]); ++ goto fail; ++ } ++ ++ if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE) ++ { ++ goto fail; ++ } ++ /* linux kernel type is EFI */ ++ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_EFI; ++ kernel_params.kernel_addr = (grub_addr_t) grub_efi_allocate_any_pages ( ++ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); ++ grub_dprintf ("linux", "kernel numpages: %" PRIuGRUB_SIZE "\n", ++ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); ++ if (!kernel_params.kernel_addr) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto fail; ++ } ++ ++ grub_file_seek (file, 0); ++ if (grub_file_read (file, (void*) kernel_params.kernel_addr, kernel_params.kernel_size) ++ < (grub_int64_t) kernel_params.kernel_size) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); ++ goto fail; ++ } ++ ++ grub_dprintf ("linux", "kernel @ %p\n", (void*) kernel_params.kernel_addr); ++ } ++ ++ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE) ++ + sizeof (GRUB_INITRD_STRING); ++ kernel_params.ramdisk_args_len = grub_loader_cmdline_size (argc, argv) ++ + sizeof (LINUX_IMAGE); ++ kernel_params.linux_argc = argc; ++ kernel_params.linux_args = grub_malloc (cmdline_size); ++ if (!kernel_params.linux_args) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto fail; ++ } ++ ++ grub_memcpy (kernel_params.linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); ++ ++ if (grub_linux_loongarch_elf_get_boot_params (&boot_params) == 1) ++ is_bpi_boot = 1; ++ else ++ is_bpi_boot = 0; ++ ++ if (is_bpi_boot == 0) ++ { ++ err = grub_create_loader_cmdline (argc, argv, ++ (char*) ((grub_addr_t) kernel_params.linux_args + sizeof (LINUX_IMAGE) - 1), ++ kernel_params.ramdisk_args_len, ++ GRUB_VERIFY_KERNEL_CMDLINE); ++ if (err) ++ goto fail; ++ } else { ++ /* save args from linux cmdline */ ++ char *p = kernel_params.linux_args; ++ ++ p += sizeof (LINUX_IMAGE) - 1; ++ for (i=0; i < argc; i++) ++ { ++ grub_memcpy (p, argv[i], grub_strlen(argv[i]) + 1); ++ p += grub_strlen(argv[i]) + 1; ++ } ++ } ++ ++ if (grub_errno == GRUB_ERR_NONE) ++ { ++ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); ++ loaded = 1; ++ } ++ ++fail: ++ if (elf != NULL) { ++ /* grub_elf_close will call grub_file_close() */ ++ grub_elf_close (elf); ++ } else { ++ if (file) ++ grub_file_close (file); ++ } ++ ++ if (grub_errno != GRUB_ERR_NONE) ++ { ++ grub_dl_unref (my_mod); ++ loaded = 0; ++ } ++ ++ if (kernel_params.linux_args && !loaded) ++ grub_free (kernel_params.linux_args); ++ ++ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_EFI) { ++ if (kernel_params.kernel_addr && !loaded) ++ grub_efi_free_pages ((grub_addr_t) kernel_params.kernel_addr, ++ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); ++ } ++ ++ return grub_errno; ++} ++ ++static grub_err_t ++grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; ++ grub_size_t initrd_size; ++ void *initrd_mem = NULL; ++ grub_err_t err; ++ ++ if (argc == 0) ++ { ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ goto fail; ++ } ++ ++ if (!loaded) ++ { ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); ++ goto fail; ++ } ++ ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) ++ goto fail; ++ ++ initrd_size = grub_get_initrd_size (&initrd_ctx); ++ grub_dprintf ("linux", "Loading initrd\n"); ++ ++ initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x10000, &err); ++ if (err) ++ goto fail; ++ ++ if (!initrd_mem) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto fail; ++ } ++ ++ if (grub_initrd_load (&initrd_ctx, initrd_mem)) ++ goto fail; ++ ++ /* save ramdisk addr and size */ ++ kernel_params.ramdisk_addr = (grub_addr_t) initrd_mem; ++ kernel_params.ramdisk_size = initrd_size; ++ grub_dprintf ("linux", "ramdisk [addr=%p, size=0x%lx]\n", ++ (void *) initrd_mem, initrd_size); ++fail: ++ grub_initrd_close (&initrd_ctx); ++ ++ return grub_errno; ++} ++ ++static grub_command_t cmd_linux, cmd_initrd; ++ ++GRUB_MOD_INIT(linux) ++{ ++ cmd_linux = grub_register_command ("linux", grub_cmd_linux, ++ N_("FILE [ARGS...]"), N_("Load Linux.")); ++ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, ++ N_("FILE"), N_("Load initrd.")); ++ my_mod = mod; ++} ++ ++GRUB_MOD_FINI(linux) ++{ ++ grub_unregister_command (cmd_linux); ++ grub_unregister_command (cmd_initrd); ++} +diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h +index 792258b2af20..fbe35a4b6bf4 100644 +--- a/include/grub/loongarch64/efi/memory.h ++++ b/include/grub/loongarch64/efi/memory.h +@@ -19,7 +19,14 @@ + #ifndef GRUB_MEMORY_CPU_HEADER + #include + +-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xfffffffffffULL ++static inline grub_uint64_t grub_efi_max_usable_address(void) ++{ ++ grub_uint64_t addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ return addr |= 0xffffffffffUL; ++} ++ ++#define GRUB_EFI_MAX_USABLE_ADDRESS (grub_efi_max_usable_address()) + #define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS + + #endif /* ! GRUB_MEMORY_CPU_HEADER */ +diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h +new file mode 100644 +index 000000000000..73876b8383bb +--- /dev/null ++++ b/include/grub/loongarch64/linux.h +@@ -0,0 +1,215 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2021 Free Software Foundation, Inc. ++ * ++ * 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 . ++ */ ++ ++#ifndef GRUB_LOONGARCH64_LINUX_HEADER ++#define GRUB_LOONGARCH64_LINUX_HEADER 1 ++ ++#include ++ ++/* LoongArch linux kernel type */ ++#define GRUB_LOONGARCH_LINUX_BAD 0 ++#define GRUB_LOONGARCH_LINUX_ELF 1 ++#define GRUB_LOONGARCH_LINUX_EFI 2 ++ ++#define GRUB_LOONGSON3_BOOT_MEM_MAP_MAX 128 ++ ++#define GRUB_LINUX_LOONGARCH_MAGIC_SIGNATURE 0x6E6F73676E6F6F4C /* 'Loongson' */ ++ ++/* From linux/Documentation/loongarch/booting.txt ++ * ++ * 0-1: MZ ++ * 0x28: LoongArch\0 ++ * 0x3c: PE/COFF头偏移 ++ * 0x20e:内核版本号偏移-512 ++ * riscv的version字段在0x20偏移处,现在LoongArch没有使用,是0 ++ */ ++struct linux_loongarch64_kernel_header ++{ ++ grub_uint32_t code0; /* Executable code */ ++ grub_uint32_t code1; /* Executable code */ ++ grub_uint64_t text_offset; /* Image load offset */ ++ grub_uint64_t res0; /* reserved */ ++ grub_uint64_t res1; /* reserved */ ++ grub_uint64_t res2; /* reserved */ ++ grub_uint64_t magic; /* Magic number, little endian, "Loongson" */ ++ grub_uint64_t res3; /* reserved */ ++ grub_uint32_t res4; /* reserved */ ++ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ ++}; ++ ++struct linux_loongarch64_kernel_params ++{ ++ grub_addr_t kernel_addr; /* kernel entry address */ ++ grub_size_t kernel_size; /* kernel size */ ++ grub_addr_t ramdisk_addr; /* initrd load address */ ++ grub_size_t ramdisk_size; /* initrd size */ ++ int ramdisk_args_len; /* position of initrd in linux_args */ ++ int linux_argc; /* cmdline parameters number*/ ++ grub_addr_t linux_argv; /* cmdline parameters address*/ ++ void* linux_args; ++ void* fdt; ++}; ++ ++#include ++#include ++ ++#define GRUB_EFI_MAX_PHY_ADDRESS 0xffffffffffffULL ++#define ELF32_LOADMASK (0xf0000000UL) ++#define ELF64_LOADMASK (0xf000000000000000ULL) ++#define FLAGS_EFI_SUPPORT_BIT 0 ++ ++/*initrd info*/ ++#define GRUB_RD_START_STRING "rd_start=0xXXXXXXXXXXXXXXXX" ++#define GRUB_RD_SIZE_STRING "rd_size=0xXXXXXXXXXXXXXXXX" ++#define GRUB_INITRD_STRING "initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX" ++ ++#define FDT_ADDR_CELLS_STRING "#address-cells" ++#define FDT_SIZE_CELLS_STRING "#size-cells" ++#define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ ++ sizeof (FDT_ADDR_CELLS_STRING) + \ ++ sizeof (FDT_SIZE_CELLS_STRING)) ++ ++struct efi_boot_memmap { ++ grub_efi_uintn_t map_size; ++ grub_efi_uintn_t desc_size; ++ grub_efi_uint32_t desc_ver; ++ grub_efi_uintn_t map_key; ++ grub_efi_uintn_t buff_size; ++ grub_efi_memory_descriptor_t map[]; ++}; ++ ++struct efi_initrd { ++ grub_efi_uintn_t base; ++ grub_efi_uintn_t size; ++}; ++ ++/* ++ * These are set up by the setup-routine at boot-time: ++ */ ++struct screen_info { ++ grub_efi_uint8_t orig_x; /* 0x00 */ ++ grub_efi_uint8_t orig_y; /* 0x01 */ ++ grub_efi_uint16_t ext_mem_k; /* 0x02 */ ++ grub_efi_uint16_t orig_video_page; /* 0x04 */ ++ grub_efi_uint8_t orig_video_mode; /* 0x06 */ ++ grub_efi_uint8_t orig_video_cols; /* 0x07 */ ++ grub_efi_uint8_t flags; /* 0x08 */ ++ grub_efi_uint8_t unused2; /* 0x09 */ ++ grub_efi_uint16_t orig_video_ega_bx;/* 0x0a */ ++ grub_efi_uint16_t unused3; /* 0x0c */ ++ grub_efi_uint8_t orig_video_lines; /* 0x0e */ ++ grub_efi_uint8_t orig_video_isVGA; /* 0x0f */ ++ grub_efi_uint16_t orig_video_points;/* 0x10 */ ++ ++ /* VESA graphic mode -- linear frame buffer */ ++ grub_efi_uint16_t lfb_width; /* 0x12 */ ++ grub_efi_uint16_t lfb_height; /* 0x14 */ ++ grub_efi_uint16_t lfb_depth; /* 0x16 */ ++ grub_efi_uint32_t lfb_base; /* 0x18 */ ++ grub_efi_uint32_t lfb_size; /* 0x1c */ ++ grub_efi_uint16_t cl_magic, cl_offset; /* 0x20 */ ++ grub_efi_uint16_t lfb_linelength; /* 0x24 */ ++ grub_efi_uint8_t red_size; /* 0x26 */ ++ grub_efi_uint8_t red_pos; /* 0x27 */ ++ grub_efi_uint8_t green_size; /* 0x28 */ ++ grub_efi_uint8_t green_pos; /* 0x29 */ ++ grub_efi_uint8_t blue_size; /* 0x2a */ ++ grub_efi_uint8_t blue_pos; /* 0x2b */ ++ grub_efi_uint8_t rsvd_size; /* 0x2c */ ++ grub_efi_uint8_t rsvd_pos; /* 0x2d */ ++ grub_efi_uint16_t vesapm_seg; /* 0x2e */ ++ grub_efi_uint16_t vesapm_off; /* 0x30 */ ++ grub_efi_uint16_t pages; /* 0x32 */ ++ grub_efi_uint16_t vesa_attributes; /* 0x34 */ ++ grub_efi_uint32_t capabilities; /* 0x36 */ ++ grub_efi_uint32_t ext_lfb_base; /* 0x3a */ ++ grub_efi_uint8_t _reserved[2]; /* 0x3e */ ++} __attribute__((packed)); ++ ++#define GRUB_VIDEO_TYPE_EFI 0x70 ++#define GRUB_VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0) ++#define GRUB_VIDEO_CAPABILITY_64BIT_BASE (1 << 1) /* Frame buffer base is 64-bit */ ++ ++/* From arch/loongarch/include/asm/mach-loongson64/boot_param.h */ ++struct _extention_list_hdr { ++ grub_uint64_t signature; ++ grub_uint32_t length; ++ grub_uint8_t revision; ++ grub_uint8_t checksum; ++ union { ++ struct _extention_list_hdr *next; ++ grub_uint64_t next_offset; ++ }; ++ ++} GRUB_PACKED; ++ ++struct boot_params_interface { ++ grub_uint64_t signature; /* {"B", "P", "I", "0", "1", ... } */ ++ grub_efi_system_table_t *systemtable; ++ union { ++ struct _extention_list_hdr *extlist; ++ grub_uint64_t extlist_offset; ++ }; ++ grub_uint64_t flags; ++}GRUB_PACKED; ++ ++struct loongsonlist_mem_map { ++ struct _extention_list_hdr header; /* {"M", "E", "M"} */ ++ grub_uint8_t map_count; ++ struct memmap { ++ grub_uint32_t mem_type; ++ grub_uint64_t mem_start; ++ grub_uint64_t mem_size; ++ } GRUB_PACKED map[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; ++}GRUB_PACKED; ++ ++grub_err_t ++finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params); ++ ++grub_err_t ++grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_params ++ *kernel_params); ++ ++void* ++grub_linux_loongarch_alloc_virtual_mem_addr (grub_addr_t addr, ++ grub_size_t size, ++ grub_err_t *err); ++ ++void* ++grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, ++ grub_size_t align, ++ grub_err_t *err); ++ ++void* ++grub_linux_loongarch_alloc_initrd_mem_align (grub_size_t size, ++ grub_size_t align, ++ grub_err_t *err); ++ ++void ++grub_linux_loongarch_elf_relocator_unload (void); ++ ++int ++grub_linux_loongarch_elf_get_boot_params (struct boot_params_interface **boot_params); ++ ++grub_err_t ++grub_linux_loongarch_elf_boot_params (struct boot_params_interface *boot_params); ++ ++grub_err_t ++grub_linux_loongarch_elf_load_kernel (grub_elf_t elf, const char *filename); ++ ++#endif /* ! GRUB_LOONGARCH64_LINUX_HEADER */ +diff --git a/include/grub/loongarch64/memory.h b/include/grub/loongarch64/memory.h +new file mode 100644 +index 000000000000..cc9faefc1d9d +--- /dev/null ++++ b/include/grub/loongarch64/memory.h +@@ -0,0 +1,59 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2017 Free Software Foundation, Inc. ++ * ++ * 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 . ++ */ ++ ++#ifndef GRUB_MEMORY_CPU_HEADER ++#define GRUB_MEMORY_CPU_HEADER 1 ++ ++#ifndef ASM_FILE ++#include ++#include ++#include ++#endif ++ ++#ifndef ASM_FILE ++ ++typedef grub_addr_t grub_phys_addr_t; ++ ++static inline grub_phys_addr_t ++grub_vtop (void *a) ++{ ++ if (-1 == ((grub_int64_t) a >> 32)) ++ return ((grub_phys_addr_t) a) & 0x1fffffffUL; ++ return ((grub_phys_addr_t) a) & 0xffffffffffffUL; ++} ++ ++static inline void * ++grub_map_memory (grub_phys_addr_t a, grub_size_t size) ++{ ++ grub_uint64_t addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ if (addr & 0x1) ++ return (void *) (a | (addr & 0xffffffffffffff00UL)); ++ else ++ return (void *) a; ++} ++ ++static inline void ++grub_unmap_memory (void *a __attribute__ ((unused)), ++ grub_size_t size __attribute__ ((unused))) ++{ ++} ++ ++#endif ++ ++#endif +diff --git a/include/grub/loongarch64/relocator.h b/include/grub/loongarch64/relocator.h +new file mode 100644 +index 000000000000..cef3aaaf77ba +--- /dev/null ++++ b/include/grub/loongarch64/relocator.h +@@ -0,0 +1,38 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Free Software Foundation, Inc. ++ * ++ * 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 . ++ */ ++ ++#ifndef GRUB_RELOCATOR_CPU_HEADER ++#define GRUB_RELOCATOR_CPU_HEADER 1 ++ ++#include ++#include ++#include ++ ++struct grub_relocator64_state ++{ ++ /* gpr[0] is ignored since it's hardwired to 0. */ ++ grub_uint64_t gpr[32]; ++ /* Register holding target $pc. */ ++ int jumpreg; ++}; ++ ++grub_err_t ++grub_relocator64_boot (struct grub_relocator *rel, ++ struct grub_relocator64_state state); ++ ++#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ +-- +2.43.0 + diff --git a/grub.patches b/grub.patches index 8e92f9f..245b57d 100644 --- a/grub.patches +++ b/grub.patches @@ -229,4 +229,5 @@ Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch Patch230: Handle-non-continuous-data-blocks-in-directory-exten.patch Patch231: loongarch64-fix-GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch -Patch232: modify-efi_max_usable-addr.patch +Patch232: modify-efi_max_usable-addr.patch +Patch233: LoongArch-Add-back-compatibility-for-linux-kernel.patch diff --git a/grub2.spec b/grub2.spec index 8b3e155..888d542 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 12 +Release: 13 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,13 @@ fi %{_datadir}/man/man* %changelog + +* Sat May 25 2024 liuxue - 1:2.12-13 +- Type:requirement +- CVE:NA +- SUG:NA +- DESC:loongarch64: Add back-compatibility for linux kernel + * Fri May 24 2024 Ouuleilei - 1:2.12-12 - Add sophgo's patch to support risc-v machine SG2042 -- Gitee From f179429aaa2a6d4b6aa2dc3167f8331b63ac4f93 Mon Sep 17 00:00:00 2001 From: Xue Liu Date: Tue, 28 May 2024 16:59:28 +0800 Subject: [PATCH 16/26] Fix that patch233 introduced old code (cherry picked from commit 48fdc532e5fef9f652843f24114384c2f765aa2d) --- ...patch-28dcf48482-introduced-old-code.patch | 25 +++++++++++++++++++ grub.patches | 5 ++-- grub2.spec | 7 +++++- 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 Fix-that-patch-28dcf48482-introduced-old-code.patch diff --git a/Fix-that-patch-28dcf48482-introduced-old-code.patch b/Fix-that-patch-28dcf48482-introduced-old-code.patch new file mode 100644 index 0000000..2371388 --- /dev/null +++ b/Fix-that-patch-28dcf48482-introduced-old-code.patch @@ -0,0 +1,25 @@ +From 0bc8d39e5c12e8fefa43962d8a741061cd78c649 Mon Sep 17 00:00:00 2001 +From: Xue Liu +Date: Tue, 28 May 2024 16:49:06 +0800 +Subject: [PATCH] Fix that patch 28dcf48482 introduced old code + +--- + grub-core/kern/efi/mm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 31bffb534414..afad55e98880 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -501,7 +501,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + #ifdef GRUB_CPU_LOONGARCH64 + && desc->physical_start <= grub_efi_max_usable_address() + #else +- && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS ++ && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS + #endif + && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 + && desc->num_pages != 0) +-- +2.43.0 + diff --git a/grub.patches b/grub.patches index 245b57d..6e08bf2 100644 --- a/grub.patches +++ b/grub.patches @@ -229,5 +229,6 @@ Patch228: 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch Patch229: 0003-Revert-templates-Disable-the-os-prober-by-default.patch Patch230: Handle-non-continuous-data-blocks-in-directory-exten.patch Patch231: loongarch64-fix-GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch -Patch232: modify-efi_max_usable-addr.patch -Patch233: LoongArch-Add-back-compatibility-for-linux-kernel.patch +Patch232: modify-efi_max_usable-addr.patch +Patch233: LoongArch-Add-back-compatibility-for-linux-kernel.patch +Patch234: Fix-that-patch-28dcf48482-introduced-old-code.patch diff --git a/grub2.spec b/grub2.spec index 888d542..70a6c06 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 13 +Release: 14 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,11 @@ fi %{_datadir}/man/man* %changelog +* Tue May 28 2024 liuxue - 1:2.12-14 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:Fix that patch233 introduced old code * Sat May 25 2024 liuxue - 1:2.12-13 - Type:requirement -- Gitee From 0124258ffcb13a156eb8ccf1167d5f614ea1e364 Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Wed, 5 Jun 2024 02:03:28 +0000 Subject: [PATCH 17/26] lib/libtasn1: Fix ETYPE_OK off by one array size check Signed-off-by: Qiumiao Zhang (cherry picked from commit 4155120fe548cfc7cff865d1b938514a7d25da28) --- ...btasn1-Fix-ETYPE_OK-off-by-one-array.patch | 29 +++++++++++++++++++ grub.patches | 1 + grub2.spec | 8 ++++- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2021-46848-lib-libtasn1-Fix-ETYPE_OK-off-by-one-array.patch diff --git a/backport-CVE-2021-46848-lib-libtasn1-Fix-ETYPE_OK-off-by-one-array.patch b/backport-CVE-2021-46848-lib-libtasn1-Fix-ETYPE_OK-off-by-one-array.patch new file mode 100644 index 0000000..2846bd8 --- /dev/null +++ b/backport-CVE-2021-46848-lib-libtasn1-Fix-ETYPE_OK-off-by-one-array.patch @@ -0,0 +1,29 @@ +From 3395407f083eae362637d7a29e31c97008a57f4f Mon Sep 17 00:00:00 2001 +From: Simon Josefsson +Date: Wed, 17 Aug 2022 12:25:06 +0200 +Subject: [PATCH] lib/libtasn1: Fix ETYPE_OK off by one array size check + +Reported by David Trabish in +. + +Signed-off-by: Simon Josefsson +--- + grub-core/lib/libtasn1/lib/int.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/lib/libtasn1/lib/int.h b/grub-core/lib/libtasn1/lib/int.h +index edfe84a..c15bfa6 100644 +--- a/grub-core/lib/libtasn1/lib/int.h ++++ b/grub-core/lib/libtasn1/lib/int.h +@@ -97,7 +97,7 @@ typedef struct tag_and_class_st + # define ETYPE_TAG(etype) (_asn1_tags[etype].tag) + # define ETYPE_CLASS(etype) (_asn1_tags[etype].class) + # define ETYPE_OK(etype) (((etype) != ASN1_ETYPE_INVALID && \ +- (etype) <= _asn1_tags_size && \ ++ (etype) < _asn1_tags_size && \ + _asn1_tags[(etype)].desc != NULL)?1:0) + + # define ETYPE_IS_STRING(etype) ((etype == ASN1_ETYPE_GENERALSTRING || \ +-- +2.33.0 + diff --git a/grub.patches b/grub.patches index 6e08bf2..0090e23 100644 --- a/grub.patches +++ b/grub.patches @@ -232,3 +232,4 @@ Patch231: loongarch64-fix-GRUB_EFI_MAX_ALLOCATION_ADDRESS-unde.patch Patch232: modify-efi_max_usable-addr.patch Patch233: LoongArch-Add-back-compatibility-for-linux-kernel.patch Patch234: Fix-that-patch-28dcf48482-introduced-old-code.patch +Patch235: backport-CVE-2021-46848-lib-libtasn1-Fix-ETYPE_OK-off-by-one-array.patch diff --git a/grub2.spec b/grub2.spec index 70a6c06..500d9f6 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 14 +Release: 15 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,12 @@ fi %{_datadir}/man/man* %changelog +* Wed Jun 5 2024 zhangqiumiao - 1:2.12-15 +- Type:CVE +- CVE:CVE-2021-46848 +- SUG:NA +- DESC:lib/libtasn1: Fix ETYPE_OK off by one array size check + * Tue May 28 2024 liuxue - 1:2.12-14 - Type:bugfix - CVE:NA -- Gitee From 93d708d5248bca20c3862af57f606c91965b2e97 Mon Sep 17 00:00:00 2001 From: wangziliang Date: Mon, 17 Jun 2024 06:47:02 +0000 Subject: [PATCH 18/26] disk/mdraid1x_linux: Prevent infinite recursion (cherry picked from commit 8c7269a15f9cd142bad32e63fc78aba25db966b2) --- ...d1x_linux-Prevent-infinite-recursion.patch | 139 ++++++++++++++++++ grub.patches | 1 + grub2.spec | 8 +- 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 backport-disk-mdraid1x_linux-Prevent-infinite-recursion.patch diff --git a/backport-disk-mdraid1x_linux-Prevent-infinite-recursion.patch b/backport-disk-mdraid1x_linux-Prevent-infinite-recursion.patch new file mode 100644 index 0000000..8f2197d --- /dev/null +++ b/backport-disk-mdraid1x_linux-Prevent-infinite-recursion.patch @@ -0,0 +1,139 @@ +From 99b4c0c3841bf71b0f2ef83607e9d6f13874c67c Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Mon, 29 Apr 2024 16:38:03 +0000 +Subject: [PATCH] disk/mdraid1x_linux: Prevent infinite recursion + +The test corpus for version-1 RAID generated an infinite recursion +in grub_partition_iterate() while attempting to read the superblock. +The reason for the issue was that the data region overlapped with +the superblock. + +The infinite call loop looks like this: + grub_partition_iterate() -> partmap->iterate() -> + -> grub_disk_read() -> grub_disk_read_small() -> + -> grub_disk_read_small_real() -> grub_diskfilter_read() -> + -> read_lv() -> read_segment() -> grub_diskfilter_read_node() -> + -> grub_disk_read() -> grub_disk_read_small() -> ... + +The fix adds checks for both the superblock region and the data +region when parsing the superblock metadata in grub_mdraid_detect(). + +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +--- + grub-core/disk/mdraid1x_linux.c | 78 +++++++++++++++++++++++++++++++++ + 1 file changed, 78 insertions(+) + +diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c +index 72e5cb6f4..dd5d440a3 100644 +--- a/grub-core/disk/mdraid1x_linux.c ++++ b/grub-core/disk/mdraid1x_linux.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -103,6 +104,9 @@ struct grub_raid_super_1x + + #define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */ + ++#define GRUB_MD_SECTOR_SHIFT 9 /* Follow Linux kernel v6.8. */ ++#define GRUB_MD_SECTOR_SIZE (1 << GRUB_MD_SECTOR_SHIFT) ++ + static struct grub_diskfilter_vg * + grub_mdraid_detect (grub_disk_t disk, + struct grub_diskfilter_pv_id *id, +@@ -129,6 +133,7 @@ grub_mdraid_detect (grub_disk_t disk, + grub_uint32_t level; + struct grub_diskfilter_vg *array; + char *uuid; ++ grub_uint64_t sb_sz, data_end, sb_end; + + if (size == GRUB_DISK_SIZE_UNKNOWN && minor_version == 0) + continue; +@@ -154,6 +159,79 @@ grub_mdraid_detect (grub_disk_t disk, + || grub_le_to_cpu64 (sb.super_offset) != sector) + continue; + ++ /* ++ * The first check follows the Linux kernel's data_size ++ * validation from v6.8-rc5. ++ */ ++ if (grub_le_to_cpu64 (sb.data_size) < 10 || ++ grub_le_to_cpu64 (sb.raid_disks) > GRUB_MDRAID_MAX_DISKS) ++ { ++ grub_dprintf ("mdraid1x", "Corrupted superblock\n"); ++ return NULL; ++ } ++ ++ /* ++ * Total size of superblock: 256 bytes plus 2 bytes per device ++ * in the array. ++ */ ++ sb_sz = sizeof (struct grub_raid_super_1x) + grub_le_to_cpu64 (sb.raid_disks) * 2; ++ ++ if (grub_add (grub_le_to_cpu64 (sb.super_offset), ++ (ALIGN_UP(sb_sz, GRUB_MD_SECTOR_SIZE) >> GRUB_MD_SECTOR_SHIFT), &sb_end)) ++ { ++ grub_dprintf ("mdraid1x", "Invalid superblock end.\n"); ++ return NULL; ++ } ++ ++ if (grub_add (grub_le_to_cpu64 (sb.data_offset), ++ grub_le_to_cpu64 (sb.data_size), &data_end)) ++ { ++ grub_dprintf ("mdraid1x", "Invalid data end.\n"); ++ return NULL; ++ } ++ ++ /* In minor versions 1 and 2, superblock is positioned before data. */ ++ if (minor_version) ++ { ++ if (grub_le_to_cpu64 (sb.data_offset) < sb_end) ++ { ++ grub_dprintf ("mdraid1x", ++ "The superblock either overlaps with the data " ++ "or is behind it.\n"); ++ return NULL; ++ } ++ ++ if (data_end > size) ++ { ++ grub_dprintf ("mdraid1x", ++ "The data region ends at %" PRIuGRUB_UINT64_T ", " ++ "past the end of the disk (%" PRIuGRUB_UINT64_T ")\n", ++ data_end, size); ++ return NULL; ++ } ++ } ++ else ++ { ++ /* In minor version 0, superblock is at the end of the device. */ ++ if (grub_le_to_cpu64 (sb.super_offset) < data_end) ++ { ++ grub_dprintf ("mdraid1x", ++ "The data either overlaps with the superblock " ++ "or is behind it.\n"); ++ return NULL; ++ } ++ ++ if (sb_end > size) ++ { ++ grub_dprintf ("mdraid1x", ++ "The superblock region ends at " ++ "%" PRIuGRUB_UINT64_T ", past the end of " ++ "the disk (%" PRIuGRUB_UINT64_T ")\n", ++ sb_end, size); ++ return NULL; ++ } ++ } ++ + if (sb.major_version != grub_cpu_to_le32_compile_time (1)) + /* Unsupported version. */ + return NULL; +-- +2.27.0 + diff --git a/grub.patches b/grub.patches index 0090e23..fdf4fd2 100644 --- a/grub.patches +++ b/grub.patches @@ -233,3 +233,4 @@ Patch232: modify-efi_max_usable-addr.patch Patch233: LoongArch-Add-back-compatibility-for-linux-kernel.patch Patch234: Fix-that-patch-28dcf48482-introduced-old-code.patch Patch235: backport-CVE-2021-46848-lib-libtasn1-Fix-ETYPE_OK-off-by-one-array.patch +Patch236: backport-disk-mdraid1x_linux-Prevent-infinite-recursion.patch diff --git a/grub2.spec b/grub2.spec index 500d9f6..deffc24 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 15 +Release: 16 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,12 @@ fi %{_datadir}/man/man* %changelog +* Mon Jun 17 2024 wangziliang - 1:2.12-16 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:disk/mdraid1x_linux: Prevent infinite recursion + * Wed Jun 5 2024 zhangqiumiao - 1:2.12-15 - Type:CVE - CVE:CVE-2021-46848 -- Gitee From dd3a6e2f51be55b222271522de15a1b862485bba Mon Sep 17 00:00:00 2001 From: yueyuankun Date: Wed, 19 Jun 2024 15:03:17 +0800 Subject: [PATCH 19/26] :Add gfxterm_background and serial modules to grub.efi (cherry picked from commit 16ede924d72eb579e3fc5a58eead2146a4bad170) --- grub.macros | 4 ++-- grub2.spec | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/grub.macros b/grub.macros index 056e128..48a3dc3 100644 --- a/grub.macros +++ b/grub.macros @@ -444,14 +444,14 @@ GRUB_MODULES=" all_video boot btrfs \\\ echo efifwsetup efinet ext2 f2fs \\\ fat font gcry_rijndael gcry_rsa gcry_serpent \\\ gcry_sha256 gcry_twofish gcry_whirlpool \\\ - gfxmenu gfxterm gzio \\\ + gfxmenu gfxterm gfxterm_background gzio \\\ halt http iso9660 jpeg \\\ loadenv loopback linux lvm lsefi lsefimmap luks \\\ luks2 mdraid09 mdraid1x minicmd net \\\ normal part_apple part_msdos part_gpt \\\ password_pbkdf2 png reboot \\\ search search_fs_uuid search_fs_file \\\ - search_label sleep test tftp \\\ + search_label serial sleep test tftp \\\ video xfs " \ GRUB_MODULES+=%{efi_modules} \ %{expand:%%{mkimage %{1} %{2} %{3} %{4}}} \ diff --git a/grub2.spec b/grub2.spec index deffc24..cf8fb66 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 16 +Release: 17 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,12 @@ fi %{_datadir}/man/man* %changelog +* Wed Jun 19 2024 yueyuankun - 1:2.12-17 +- Type:requirement +- CVE:NA +- SUG:NA +- DESC:Add gfxterm_background and serial modules to grub.efi + * Mon Jun 17 2024 wangziliang - 1:2.12-16 - Type:bugfix - CVE:NA -- Gitee From c051464e49ad72e214de4c08f7ee3fb64862bc6d Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Thu, 20 Jun 2024 07:06:15 +0000 Subject: [PATCH 20/26] fix log printing in tpcm_kunpeng module Signed-off-by: Qiumiao Zhang (cherry picked from commit b991af1095137f6b9bb0a3d45c90293abd1beb0c) --- add-TPCM-support-with-ipmi-channel.patch | 6 +++--- grub2.spec | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/add-TPCM-support-with-ipmi-channel.patch b/add-TPCM-support-with-ipmi-channel.patch index 29b1017..9bb9e40 100644 --- a/add-TPCM-support-with-ipmi-channel.patch +++ b/add-TPCM-support-with-ipmi-channel.patch @@ -399,9 +399,9 @@ index 0000000..57a4cea + grub_dprintf ("tpcm", "tpcm control switch turned off, ignore excute_ipmi_cmd failure.\n"); + else + { -+ err = grub_error (GRUB_ERR_BUG, -+ "excute_ipmi_cmd failed, request sub_cmd:0x%x, ret:%lu\n", -+ request_data->SubCmd, status); ++ err = GRUB_ERR_BUG; ++ grub_dprintf ("tpcm", "excute_ipmi_cmd failed, request sub_cmd:0x%x, ret:%lu\n", ++ request_data->SubCmd, status); + } + goto fail; + } diff --git a/grub2.spec b/grub2.spec index cf8fb66..a75cb87 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 17 +Release: 18 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,6 +447,12 @@ fi %{_datadir}/man/man* %changelog +* Wed Jun 5 2024 zhangqiumiao - 1:2.12-18 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:fix log printing in tpcm_kunpeng module + * Wed Jun 19 2024 yueyuankun - 1:2.12-17 - Type:requirement - CVE:NA -- Gitee From 4444af68de5a9fa588a296537208ff24f7c78212 Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Mon, 24 Jun 2024 11:39:54 +0000 Subject: [PATCH 21/26] fix log printing in tpcm_kunpeng module again Signed-off-by: Qiumiao Zhang --- add-TPCM-support-with-ipmi-channel.patch | 10 +++++----- grub2.spec | 10 ++++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/add-TPCM-support-with-ipmi-channel.patch b/add-TPCM-support-with-ipmi-channel.patch index 9bb9e40..364fb00 100644 --- a/add-TPCM-support-with-ipmi-channel.patch +++ b/add-TPCM-support-with-ipmi-channel.patch @@ -399,9 +399,9 @@ index 0000000..57a4cea + grub_dprintf ("tpcm", "tpcm control switch turned off, ignore excute_ipmi_cmd failure.\n"); + else + { -+ err = GRUB_ERR_BUG; -+ grub_dprintf ("tpcm", "excute_ipmi_cmd failed, request sub_cmd:0x%x, ret:%lu\n", -+ request_data->SubCmd, status); ++ err = grub_error (GRUB_ERR_BUG, ++ "excute_ipmi_cmd failed, request sub_cmd:0x%x, ret:%lu\n", ++ request_data->SubCmd, status); + } + goto fail; + } @@ -458,8 +458,8 @@ index 0000000..57a4cea + &response_length, NULL); + if (status != GRUB_EFI_SUCCESS) + { -+ grub_printf ("excute_ipmi_cmd failed, request sub_cmd:%d, ret:%lu\n", -+ request_data.SubCmd, status); ++ grub_dprintf ("tpcm", "excute_ipmi_cmd failed, request sub_cmd:%d, ret:%lu\n", ++ request_data.SubCmd, status); + /* if we excute_ipmi_cmd, it could be the fllowing results: + * 1. uefi have this interface, but did not implement it. + * 2. uefi have implemented, but bmc did not support TPCM diff --git a/grub2.spec b/grub2.spec index a75cb87..3c036e8 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 18 +Release: 19 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -447,7 +447,13 @@ fi %{_datadir}/man/man* %changelog -* Wed Jun 5 2024 zhangqiumiao - 1:2.12-18 +* Mon Jun 24 2024 zhangqiumiao - 1:2.12-19 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:fix log printing in tpcm_kunpeng module again + +* Wed Jun 19 2024 zhangqiumiao - 1:2.12-18 - Type:bugfix - CVE:NA - SUG:NA -- Gitee From c4d6cf415d328a02cd9fc6d0020316da58091f18 Mon Sep 17 00:00:00 2001 From: peng_zou Date: Tue, 25 Jun 2024 14:40:36 +0800 Subject: [PATCH 22/26] add support for ppc64le (cherry picked from commit b4e3f33334d50d143781e09d69171aaf786e30a4) --- grub2.spec | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/grub2.spec b/grub2.spec index 3c036e8..7d216e4 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 19 +Release: 20 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -182,6 +182,10 @@ git add grub-core/tests/lib/functional_test.c git commit -m "Disable partial grub_func_test cases" %build +%ifarch ppc64le +export CFLAGS="$CFLAGS -fno-stack-protector" +%endif + %if 0%{with_efi_arch} %{expand:%do_primary_efi_build %%{grubefiarch} %%{grubefiname} %%{grubeficdname} %%{_target_platform} %%{efi_target_cflags} %%{efi_host_cflags}} %endif @@ -206,6 +210,9 @@ mv %{_builddir}/grub-%{version}/grub-%{grubefiarch}-%{tarversion}/%{grubeficdnam %endif %check +%ifarch ppc64le +%global grubefiarch powerpc-ieee1275 +%endif pushd %{_builddir}/%{?buildsubdir}/grub-%{grubefiarch}-%{tarversion}/grub-core make check popd @@ -447,6 +454,12 @@ fi %{_datadir}/man/man* %changelog +* Tue Jun 25 2024 peng.zou - 1:2.12-20 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:add support for ppc64le + * Mon Jun 24 2024 zhangqiumiao - 1:2.12-19 - Type:bugfix - CVE:NA -- Gitee From 963ffbe46243abcef7a5dc6a55a029560a06508c Mon Sep 17 00:00:00 2001 From: yueyuankun Date: Mon, 1 Jul 2024 18:18:46 +0800 Subject: [PATCH 23/26] Export all variables from the initial context when creating a submenu. (cherry picked from commit ffc10c83b2bb50085e13b652a35e39d3fdedfe3f) --- ...bles-from-the-initial-context-when-c.patch | 44 +++++++++++++++++++ grub.patches | 1 + grub2.spec | 8 +++- 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 backport-Export-all-variables-from-the-initial-context-when-c.patch diff --git a/backport-Export-all-variables-from-the-initial-context-when-c.patch b/backport-Export-all-variables-from-the-initial-context-when-c.patch new file mode 100644 index 0000000..4e32260 --- /dev/null +++ b/backport-Export-all-variables-from-the-initial-context-when-c.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 22 Jan 2019 15:40:25 +0100 +Subject: [PATCH] Export all variables from the initial context when creating a + submenu + +When a submenu is created, only the exported variables are copied to the +new menu context. But we want the variables to be global, so export lets +export all variables to the new created submenu. + +Also, don't unset the default variable when a new submenu is created. + +Signed-off-by: Javier Martinez Canillas +--- + grub-core/normal/context.c | 2 +- + grub-core/normal/menu.c | 2 -- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c +index ee53d4a68e5..87edd254c44 100644 +--- a/grub-core/normal/context.c ++++ b/grub-core/normal/context.c +@@ -99,7 +99,7 @@ grub_env_new_context (int export_all) + grub_err_t + grub_env_context_open (void) + { +- return grub_env_new_context (0); ++ return grub_env_new_context (1); + } + + int grub_extractor_level = 0; +diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c +index 4a02aadb01c..fe2e77a43e2 100644 +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -375,8 +375,6 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) + + if (ptr && ptr[0] && ptr[1]) + grub_env_set ("default", ptr + 1); +- else +- grub_env_unset ("default"); + + grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args); + diff --git a/grub.patches b/grub.patches index fdf4fd2..cb56119 100644 --- a/grub.patches +++ b/grub.patches @@ -234,3 +234,4 @@ Patch233: LoongArch-Add-back-compatibility-for-linux-kernel.patch Patch234: Fix-that-patch-28dcf48482-introduced-old-code.patch Patch235: backport-CVE-2021-46848-lib-libtasn1-Fix-ETYPE_OK-off-by-one-array.patch Patch236: backport-disk-mdraid1x_linux-Prevent-infinite-recursion.patch +Patch237: backport-Export-all-variables-from-the-initial-context-when-c.patch diff --git a/grub2.spec b/grub2.spec index 7d216e4..a6e5088 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 20 +Release: 21 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -454,6 +454,12 @@ fi %{_datadir}/man/man* %changelog +* Fri Jun 28 2024 yueyuankun - 1:2.12-21 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:Export all variables from the initial context when creating a submenu + * Tue Jun 25 2024 peng.zou - 1:2.12-20 - Type:bugfix - CVE:NA -- Gitee From f1fa5c163631d7661975cf19643f434126301599 Mon Sep 17 00:00:00 2001 From: peng_zou Date: Mon, 15 Jul 2024 14:57:35 +0800 Subject: [PATCH 24/26] remove BuildRequires:pesign >= 0.99-8 and fix bug about petitboot doesn't ignore EFI entries for ppc64le (cherry picked from commit 234d66e79a2dfbbad011ff2d36619b2a5bc0f5d9) --- grub.patches | 1 + ...petitboot-doesn-t-ignore-EFI-entries.patch | 33 +++++++++++++++++++ grub2.spec | 10 +++++- 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 grub2-ppc64le-fix-bug-about-petitboot-doesn-t-ignore-EFI-entries.patch diff --git a/grub.patches b/grub.patches index cb56119..4e989f5 100644 --- a/grub.patches +++ b/grub.patches @@ -235,3 +235,4 @@ Patch234: Fix-that-patch-28dcf48482-introduced-old-code.patch Patch235: backport-CVE-2021-46848-lib-libtasn1-Fix-ETYPE_OK-off-by-one-array.patch Patch236: backport-disk-mdraid1x_linux-Prevent-infinite-recursion.patch Patch237: backport-Export-all-variables-from-the-initial-context-when-c.patch +Patch238: grub2-ppc64le-fix-bug-about-petitboot-doesn-t-ignore-EFI-entries.patch diff --git a/grub2-ppc64le-fix-bug-about-petitboot-doesn-t-ignore-EFI-entries.patch b/grub2-ppc64le-fix-bug-about-petitboot-doesn-t-ignore-EFI-entries.patch new file mode 100644 index 0000000..bf9968e --- /dev/null +++ b/grub2-ppc64le-fix-bug-about-petitboot-doesn-t-ignore-EFI-entries.patch @@ -0,0 +1,33 @@ +From 801733fd3971ee681146f9eb6381cbaf78c3d4c4 Mon Sep 17 00:00:00 2001 +From: peng_zou +Date: Mon, 15 Jul 2024 14:45:16 +0800 +Subject: [PATCH] fix bug about petitboot doesn't ignore EFI entries for + ppc64le + +--- + util/grub.d/95_textmode.in | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/util/grub.d/95_textmode.in b/util/grub.d/95_textmode.in +index d6c1dbf..9171f95 100644 +--- a/util/grub.d/95_textmode.in ++++ b/util/grub.d/95_textmode.in +@@ -1,12 +1,13 @@ + #!/bin/sh + + cat <= 0.99-8 %endif +%endif %if %{?_with_ccache: 1}%{?!_with_ccache: 0} BuildRequires: ccache %endif @@ -454,6 +456,12 @@ fi %{_datadir}/man/man* %changelog +* Mon Jul 15 2024 peng.zou - 1:2.12-22 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:remove BuildRequires:pesign >= 0.99-8 and fix bug about petitboot doesn't ignore EFI entries for ppc64le + * Fri Jun 28 2024 yueyuankun - 1:2.12-21 - Type:bugfix - CVE:NA -- Gitee From 535c553a789a09cefbd39fd67b95c996e5ae2cf0 Mon Sep 17 00:00:00 2001 From: wangyueliang Date: Fri, 26 Jul 2024 14:54:08 +0800 Subject: [PATCH 25/26] Inherit 'Add BLS Support' patch from grub-2.06 (cherry picked from commit 1c3e5b182f63ce0a6a3450e8dce9e8fb390ac83a) --- ...g-module-to-parse-Boot-Loader-Specif.patch | 1613 +++++++++++++++++ 0061-Add-BLS-support-to-grub-mkconfig.patch | 394 ++++ 0064-Add-grub2-switch-to-blscfg.patch | 400 ++++ grub.macros | 2 +- grub.patches | 3 + grub2.spec | 10 +- 6 files changed, 2419 insertions(+), 3 deletions(-) create mode 100644 0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch create mode 100644 0061-Add-BLS-support-to-grub-mkconfig.patch create mode 100644 0064-Add-grub2-switch-to-blscfg.patch diff --git a/0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch b/0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch new file mode 100644 index 0000000..7e7e21f --- /dev/null +++ b/0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch @@ -0,0 +1,1613 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 22 Jan 2013 06:31:38 +0100 +Subject: [PATCH] blscfg: add blscfg module to parse Boot Loader Specification + snippets + +The BootLoaderSpec (BLS) defines a scheme where different bootloaders can +share a format for boot items and a configuration directory that accepts +these common configurations as drop-in files. + +Signed-off-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +[wjt: some cleanups and fixes] +Signed-off-by: Will Thompson +--- + grub-core/Makefile.core.def | 11 + + grub-core/commands/blscfg.c | 1177 ++++++++++++++++++++++++++++++++ + grub-core/commands/legacycfg.c | 5 +- + grub-core/commands/loadenv.c | 77 +-- + grub-core/commands/loadenv.h | 93 +++ + grub-core/commands/menuentry.c | 20 +- + grub-core/normal/main.c | 6 + + include/grub/compiler.h | 2 + + include/grub/menu.h | 13 + + include/grub/normal.h | 2 +- + 10 files changed, 1324 insertions(+), 82 deletions(-) + create mode 100644 grub-core/commands/blscfg.c + create mode 100644 grub-core/commands/loadenv.h + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 7f025e5..e968583 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -846,6 +846,16 @@ module = { + common = commands/blocklist.c; + }; + ++module = { ++ name = blscfg; ++ common = commands/blscfg.c; ++ common = commands/loadenv.h; ++ enable = powerpc_ieee1275; ++ enable = efi; ++ enable = i386_pc; ++ enable = emu; ++}; ++ + module = { + name = boot; + common = commands/boot.c; +@@ -1028,6 +1038,7 @@ module = { + module = { + name = loadenv; + common = commands/loadenv.c; ++ common = commands/loadenv.h; + common = lib/envblk.c; + }; + +diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c +new file mode 100644 +index 0000000..7132555 +--- /dev/null ++++ b/grub-core/commands/blscfg.c +@@ -0,0 +1,1177 @@ ++/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/ ++ ++/* bls.c - implementation of the boot loader spec */ ++ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * ++ * 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++#include "loadenv.h" ++ ++#define GRUB_BLS_CONFIG_PATH "/loader/entries/" ++#ifdef GRUB_MACHINE_EMU ++#define GRUB_BOOT_DEVICE "/boot" ++#else ++#define GRUB_BOOT_DEVICE "($root)" ++#endif ++ ++struct keyval ++{ ++ const char *key; ++ char *val; ++}; ++ ++static struct bls_entry *entries = NULL; ++ ++#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries) ++ ++static int bls_add_keyval(struct bls_entry *entry, char *key, char *val) ++{ ++ char *k, *v; ++ struct keyval **kvs, *kv; ++ int new_n = entry->nkeyvals + 1; ++ ++ kvs = grub_realloc (entry->keyvals, new_n * sizeof (struct keyval *)); ++ if (!kvs) ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "couldn't find space for BLS entry"); ++ entry->keyvals = kvs; ++ ++ kv = grub_malloc (sizeof (struct keyval)); ++ if (!kv) ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "couldn't find space for BLS entry"); ++ ++ k = grub_strdup (key); ++ if (!k) ++ { ++ grub_free (kv); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "couldn't find space for BLS entry"); ++ } ++ ++ v = grub_strdup (val); ++ if (!v) ++ { ++ grub_free (k); ++ grub_free (kv); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "couldn't find space for BLS entry"); ++ } ++ ++ kv->key = k; ++ kv->val = v; ++ ++ entry->keyvals[entry->nkeyvals] = kv; ++ grub_dprintf("blscfg", "new keyval at %p:%s:%s\n", entry->keyvals[entry->nkeyvals], k, v); ++ entry->nkeyvals = new_n; ++ ++ return 0; ++} ++ ++/* Find they value of the key named by keyname. If there are allowed to be ++ * more than one, pass a pointer to an int set to -1 the first time, and pass ++ * the same pointer through each time after, and it'll return them in sorted ++ * order as defined in the BLS fragment file */ ++static char *bls_get_val(struct bls_entry *entry, const char *keyname, int *last) ++{ ++ int idx, start = 0; ++ struct keyval *kv = NULL; ++ ++ if (last) ++ start = *last + 1; ++ ++ for (idx = start; idx < entry->nkeyvals; idx++) { ++ kv = entry->keyvals[idx]; ++ ++ if (!grub_strcmp (keyname, kv->key)) ++ break; ++ } ++ ++ if (idx == entry->nkeyvals) { ++ if (last) ++ *last = -1; ++ return NULL; ++ } ++ ++ if (last) ++ *last = idx; ++ ++ return kv->val; ++} ++ ++#define goto_return(x) ({ ret = (x); goto finish; }) ++ ++/* compare alpha and numeric segments of two versions */ ++/* return 1: a is newer than b */ ++/* 0: a and b are the same version */ ++/* -1: b is newer than a */ ++static int vercmp(const char * a, const char * b) ++{ ++ char oldch1, oldch2; ++ char *abuf, *bbuf; ++ char *str1, *str2; ++ char * one, * two; ++ int rc; ++ int isnum; ++ int ret = 0; ++ ++ grub_dprintf("blscfg", "%s comparing %s and %s\n", __func__, a, b); ++ if (!grub_strcmp(a, b)) ++ return 0; ++ ++ abuf = grub_malloc(grub_strlen(a) + 1); ++ bbuf = grub_malloc(grub_strlen(b) + 1); ++ str1 = abuf; ++ str2 = bbuf; ++ grub_strcpy(str1, a); ++ grub_strcpy(str2, b); ++ ++ one = str1; ++ two = str2; ++ ++ /* loop through each version segment of str1 and str2 and compare them */ ++ while (*one || *two) { ++ while (*one && !grub_isalnum(*one) && *one != '~' && *one != '+') one++; ++ while (*two && !grub_isalnum(*two) && *two != '~' && *two != '+') two++; ++ ++ /* handle the tilde separator, it sorts before everything else */ ++ if (*one == '~' || *two == '~') { ++ if (*one != '~') goto_return (1); ++ if (*two != '~') goto_return (-1); ++ one++; ++ two++; ++ continue; ++ } ++ ++ /* ++ * Handle plus separator. Concept is the same as tilde, ++ * except that if one of the strings ends (base version), ++ * the other is considered as higher version. ++ */ ++ if (*one == '+' || *two == '+') { ++ if (!*one) return -1; ++ if (!*two) return 1; ++ if (*one != '+') goto_return (1); ++ if (*two != '+') goto_return (-1); ++ one++; ++ two++; ++ continue; ++ } ++ ++ /* If we ran to the end of either, we are finished with the loop */ ++ if (!(*one && *two)) break; ++ ++ str1 = one; ++ str2 = two; ++ ++ /* grab first completely alpha or completely numeric segment */ ++ /* leave one and two pointing to the start of the alpha or numeric */ ++ /* segment and walk str1 and str2 to end of segment */ ++ if (grub_isdigit(*str1)) { ++ while (*str1 && grub_isdigit(*str1)) str1++; ++ while (*str2 && grub_isdigit(*str2)) str2++; ++ isnum = 1; ++ } else { ++ while (*str1 && grub_isalpha(*str1)) str1++; ++ while (*str2 && grub_isalpha(*str2)) str2++; ++ isnum = 0; ++ } ++ ++ /* save character at the end of the alpha or numeric segment */ ++ /* so that they can be restored after the comparison */ ++ oldch1 = *str1; ++ *str1 = '\0'; ++ oldch2 = *str2; ++ *str2 = '\0'; ++ ++ /* this cannot happen, as we previously tested to make sure that */ ++ /* the first string has a non-null segment */ ++ if (one == str1) goto_return(-1); /* arbitrary */ ++ ++ /* take care of the case where the two version segments are */ ++ /* different types: one numeric, the other alpha (i.e. empty) */ ++ /* numeric segments are always newer than alpha segments */ ++ /* XXX See patch #60884 (and details) from bugzilla #50977. */ ++ if (two == str2) goto_return (isnum ? 1 : -1); ++ ++ if (isnum) { ++ grub_size_t onelen, twolen; ++ /* this used to be done by converting the digit segments */ ++ /* to ints using atoi() - it's changed because long */ ++ /* digit segments can overflow an int - this should fix that. */ ++ ++ /* throw away any leading zeros - it's a number, right? */ ++ while (*one == '0') one++; ++ while (*two == '0') two++; ++ ++ /* whichever number has more digits wins */ ++ onelen = grub_strlen(one); ++ twolen = grub_strlen(two); ++ if (onelen > twolen) goto_return (1); ++ if (twolen > onelen) goto_return (-1); ++ } ++ ++ /* grub_strcmp will return which one is greater - even if the two */ ++ /* segments are alpha or if they are numeric. don't return */ ++ /* if they are equal because there might be more segments to */ ++ /* compare */ ++ rc = grub_strcmp(one, two); ++ if (rc) goto_return (rc < 1 ? -1 : 1); ++ ++ /* restore character that was replaced by null above */ ++ *str1 = oldch1; ++ one = str1; ++ *str2 = oldch2; ++ two = str2; ++ } ++ ++ /* this catches the case where all numeric and alpha segments have */ ++ /* compared identically but the segment sepparating characters were */ ++ /* different */ ++ if ((!*one) && (!*two)) goto_return (0); ++ ++ /* whichever version still has characters left over wins */ ++ if (!*one) goto_return (-1); else goto_return (1); ++ ++finish: ++ grub_free (abuf); ++ grub_free (bbuf); ++ return ret; ++} ++ ++/* returns name/version/release */ ++/* NULL string pointer returned if nothing found */ ++static void ++split_package_string (char *package_string, char **name, ++ char **version, char **release) ++{ ++ char *package_version, *package_release; ++ ++ /* Release */ ++ package_release = grub_strrchr (package_string, '-'); ++ ++ if (package_release != NULL) ++ *package_release++ = '\0'; ++ ++ *release = package_release; ++ ++ if (name == NULL) ++ { ++ *version = package_string; ++ } ++ else ++ { ++ /* Version */ ++ package_version = grub_strrchr(package_string, '-'); ++ ++ if (package_version != NULL) ++ *package_version++ = '\0'; ++ ++ *version = package_version; ++ /* Name */ ++ *name = package_string; ++ } ++ ++ /* Bubble up non-null values from release to name */ ++ if (name != NULL && *name == NULL) ++ { ++ *name = (*version == NULL ? *release : *version); ++ *version = *release; ++ *release = NULL; ++ } ++ if (*version == NULL) ++ { ++ *version = *release; ++ *release = NULL; ++ } ++} ++ ++static int ++split_cmp(char *nvr0, char *nvr1, int has_name) ++{ ++ int ret = 0; ++ char *name0, *version0, *release0; ++ char *name1, *version1, *release1; ++ ++ split_package_string(nvr0, has_name ? &name0 : NULL, &version0, &release0); ++ split_package_string(nvr1, has_name ? &name1 : NULL, &version1, &release1); ++ ++ if (has_name) ++ { ++ ret = vercmp(name0 == NULL ? "" : name0, ++ name1 == NULL ? "" : name1); ++ if (ret != 0) ++ return ret; ++ } ++ ++ ret = vercmp(version0 == NULL ? "" : version0, ++ version1 == NULL ? "" : version1); ++ if (ret != 0) ++ return ret; ++ ++ ret = vercmp(release0 == NULL ? "" : release0, ++ release1 == NULL ? "" : release1); ++ return ret; ++} ++ ++/* return 1: e0 is newer than e1 */ ++/* 0: e0 and e1 are the same version */ ++/* -1: e1 is newer than e0 */ ++static int bls_cmp(const struct bls_entry *e0, const struct bls_entry *e1) ++{ ++ char *id0, *id1; ++ int r; ++ ++ id0 = grub_strdup(e0->filename); ++ id1 = grub_strdup(e1->filename); ++ ++ r = split_cmp(id0, id1, 1); ++ ++ grub_free(id0); ++ grub_free(id1); ++ ++ return r; ++} ++ ++static void list_add_tail(struct bls_entry *head, struct bls_entry *item) ++{ ++ item->next = head; ++ if (head->prev) ++ head->prev->next = item; ++ item->prev = head->prev; ++ head->prev = item; ++} ++ ++static int bls_add_entry(struct bls_entry *entry) ++{ ++ struct bls_entry *e, *last = NULL; ++ int rc; ++ ++ if (!entries) { ++ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); ++ entries = entry; ++ return 0; ++ } ++ ++ FOR_BLS_ENTRIES(e) { ++ rc = bls_cmp(entry, e); ++ ++ if (!rc) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ if (rc == 1) { ++ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); ++ list_add_tail (e, entry); ++ if (e == entries) { ++ entries = entry; ++ entry->prev = NULL; ++ } ++ return 0; ++ } ++ last = e; ++ } ++ ++ if (last) { ++ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); ++ last->next = entry; ++ entry->prev = last; ++ } ++ ++ return 0; ++} ++ ++struct read_entry_info { ++ const char *devid; ++ const char *dirname; ++ grub_file_t file; ++}; ++ ++static int read_entry ( ++ const char *filename, ++ const struct grub_dirhook_info *dirhook_info UNUSED, ++ void *data) ++{ ++ grub_size_t m = 0, n, clip = 0; ++ int rc = 0; ++ char *p = NULL; ++ grub_file_t f = NULL; ++ struct bls_entry *entry; ++ struct read_entry_info *info = (struct read_entry_info *)data; ++ ++ grub_dprintf ("blscfg", "filename: \"%s\"\n", filename); ++ ++ n = grub_strlen (filename); ++ ++ if (info->file) ++ { ++ f = info->file; ++ } ++ else ++ { ++ if (filename[0] == '.') ++ return 0; ++ ++ if (n <= 5) ++ return 0; ++ ++ if (grub_strcmp (filename + n - 5, ".conf") != 0) ++ return 0; ++ ++ p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename); ++ ++ f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG); ++ if (!f) ++ goto finish; ++ } ++ ++ entry = grub_zalloc (sizeof (*entry)); ++ if (!entry) ++ goto finish; ++ ++ if (info->file) ++ { ++ char *slash; ++ ++ if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0) ++ clip = 5; ++ ++ slash = grub_strrchr (filename, '/'); ++ if (!slash) ++ slash = grub_strrchr (filename, '\\'); ++ ++ while (*slash == '/' || *slash == '\\') ++ slash++; ++ ++ m = slash ? slash - filename : 0; ++ } ++ else ++ { ++ m = 0; ++ clip = 5; ++ } ++ n -= m; ++ ++ entry->filename = grub_strndup(filename + m, n - clip); ++ if (!entry->filename) ++ goto finish; ++ ++ entry->filename[n - 5] = '\0'; ++ ++ for (;;) ++ { ++ char *buf; ++ char *separator; ++ ++ buf = grub_file_getline (f); ++ if (!buf) ++ break; ++ ++ while (buf && buf[0] && (buf[0] == ' ' || buf[0] == '\t')) ++ buf++; ++ if (buf[0] == '#') ++ continue; ++ ++ separator = grub_strchr (buf, ' '); ++ ++ if (!separator) ++ separator = grub_strchr (buf, '\t'); ++ ++ if (!separator || separator[1] == '\0') ++ { ++ grub_free (buf); ++ break; ++ } ++ ++ separator[0] = '\0'; ++ ++ do { ++ separator++; ++ } while (*separator == ' ' || *separator == '\t'); ++ ++ rc = bls_add_keyval (entry, buf, separator); ++ grub_free (buf); ++ if (rc < 0) ++ break; ++ } ++ ++ if (!rc) ++ bls_add_entry(entry); ++ ++finish: ++ if (p) ++ grub_free (p); ++ ++ if (f) ++ grub_file_close (f); ++ ++ return 0; ++} ++ ++static grub_envblk_t saved_env = NULL; ++ ++static int UNUSED ++save_var (const char *name, const char *value, void *whitelist UNUSED) ++{ ++ const char *val = grub_env_get (name); ++ grub_dprintf("blscfg", "saving \"%s\"\n", name); ++ ++ if (val) ++ grub_envblk_set (saved_env, name, value); ++ ++ return 0; ++} ++ ++static int UNUSED ++unset_var (const char *name, const char *value UNUSED, void *whitelist) ++{ ++ grub_dprintf("blscfg", "restoring \"%s\"\n", name); ++ if (! whitelist) ++ { ++ grub_env_unset (name); ++ return 0; ++ } ++ ++ if (test_whitelist_membership (name, ++ (const grub_env_whitelist_t *) whitelist)) ++ grub_env_unset (name); ++ ++ return 0; ++} ++ ++static char **bls_make_list (struct bls_entry *entry, const char *key, int *num) ++{ ++ int last = -1; ++ char *val; ++ ++ int nlist = 0; ++ char **list = NULL; ++ ++ list = grub_malloc (sizeof (char *)); ++ if (!list) ++ return NULL; ++ list[0] = NULL; ++ ++ while (1) ++ { ++ char **new; ++ ++ val = bls_get_val (entry, key, &last); ++ if (!val) ++ break; ++ ++ new = grub_realloc (list, (nlist + 2) * sizeof (char *)); ++ if (!new) ++ break; ++ ++ list = new; ++ list[nlist++] = val; ++ list[nlist] = NULL; ++ } ++ ++ if (!nlist) ++ { ++ grub_free (list); ++ return NULL; ++ } ++ ++ if (num) ++ *num = nlist; ++ ++ return list; ++} ++ ++static char *field_append(bool is_var, char *buffer, const char *start, const char *end) ++{ ++ char *tmp = grub_strndup(start, end - start + 1); ++ const char *field = tmp; ++ int term = is_var ? 2 : 1; ++ ++ if (is_var) { ++ field = grub_env_get (tmp); ++ if (!field) ++ return buffer; ++ } ++ ++ if (!buffer) ++ buffer = grub_zalloc (grub_strlen(field) + term); ++ else ++ buffer = grub_realloc (buffer, grub_strlen(buffer) + grub_strlen(field) + term); ++ ++ if (!buffer) ++ return NULL; ++ ++ tmp = buffer + grub_strlen(buffer); ++ tmp = grub_stpcpy (tmp, field); ++ ++ if (is_var) ++ tmp = grub_stpcpy (tmp, " "); ++ ++ return buffer; ++} ++ ++static char *expand_val(const char *value) ++{ ++ char *buffer = NULL; ++ const char *start = value; ++ const char *end = value; ++ bool is_var = false; ++ ++ if (!value) ++ return NULL; ++ ++ while (*value) { ++ if (*value == '$') { ++ if (start != end) { ++ buffer = field_append(is_var, buffer, start, end); ++ if (!buffer) ++ return NULL; ++ } ++ ++ is_var = true; ++ start = value + 1; ++ } else if (is_var) { ++ if (!grub_isalnum(*value) && *value != '_') { ++ buffer = field_append(is_var, buffer, start, end); ++ is_var = false; ++ start = value; ++ if (*start == ' ') ++ start++; ++ } ++ } ++ ++ end = value; ++ value++; ++ } ++ ++ if (start != end) { ++ buffer = field_append(is_var, buffer, start, end); ++ if (!buffer) ++ return NULL; ++ } ++ ++ return buffer; ++} ++ ++static char **early_initrd_list (const char *initrd) ++{ ++ int nlist = 0; ++ char **list = NULL; ++ char *separator; ++ ++ while ((separator = grub_strchr (initrd, ' '))) ++ { ++ list = grub_realloc (list, (nlist + 2) * sizeof (char *)); ++ if (!list) ++ return NULL; ++ ++ list[nlist++] = grub_strndup(initrd, separator - initrd); ++ list[nlist] = NULL; ++ initrd = separator + 1; ++ } ++ ++ list = grub_realloc (list, (nlist + 2) * sizeof (char *)); ++ if (!list) ++ return NULL; ++ ++ list[nlist++] = grub_strndup(initrd, grub_strlen(initrd)); ++ list[nlist] = NULL; ++ ++ return list; ++} ++ ++static void create_entry (struct bls_entry *entry) ++{ ++ int argc = 0; ++ const char **argv = NULL; ++ ++ char *title = NULL; ++ char *clinux = NULL; ++ char *options = NULL; ++ char **initrds = NULL; ++ char *initrd = NULL; ++ const char *early_initrd = NULL; ++ char **early_initrds = NULL; ++ char *initrd_prefix = NULL; ++ char *devicetree = NULL; ++ char *dt = NULL; ++ char *id = entry->filename; ++ char *dotconf = id; ++ char *hotkey = NULL; ++ ++ char *users = NULL; ++ char **classes = NULL; ++ ++ char **args = NULL; ++ ++ char *src = NULL; ++ int i, index; ++ bool add_dt_prefix = false; ++ ++ grub_dprintf("blscfg", "%s got here\n", __func__); ++ clinux = bls_get_val (entry, "linux", NULL); ++ if (!clinux) ++ { ++ grub_dprintf ("blscfg", "Skipping file %s with no 'linux' key.\n", entry->filename); ++ goto finish; ++ } ++ ++ /* ++ * strip the ".conf" off the end before we make it our "id" field. ++ */ ++ do ++ { ++ dotconf = grub_strstr(dotconf, ".conf"); ++ } while (dotconf != NULL && dotconf[5] != '\0'); ++ if (dotconf) ++ dotconf[0] = '\0'; ++ ++ title = bls_get_val (entry, "title", NULL); ++ options = expand_val (bls_get_val (entry, "options", NULL)); ++ ++ if (!options) ++ options = expand_val (grub_env_get("default_kernelopts")); ++ ++ initrds = bls_make_list (entry, "initrd", NULL); ++ ++ devicetree = expand_val (bls_get_val (entry, "devicetree", NULL)); ++ ++ if (!devicetree) ++ { ++ devicetree = expand_val (grub_env_get("devicetree")); ++ add_dt_prefix = true; ++ } ++ ++ hotkey = bls_get_val (entry, "grub_hotkey", NULL); ++ users = expand_val (bls_get_val (entry, "grub_users", NULL)); ++ classes = bls_make_list (entry, "grub_class", NULL); ++ args = bls_make_list (entry, "grub_arg", &argc); ++ ++ argc += 1; ++ argv = grub_malloc ((argc + 1) * sizeof (char *)); ++ argv[0] = title ? title : clinux; ++ for (i = 1; i < argc; i++) ++ argv[i] = args[i-1]; ++ argv[argc] = NULL; ++ ++ early_initrd = grub_env_get("early_initrd"); ++ ++ grub_dprintf ("blscfg", "adding menu entry for \"%s\" with id \"%s\"\n", ++ title, id); ++ if (early_initrd) ++ { ++ early_initrds = early_initrd_list(early_initrd); ++ if (!early_initrds) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto finish; ++ } ++ ++ if (initrds != NULL && initrds[0] != NULL) ++ { ++ initrd_prefix = grub_strrchr (initrds[0], '/'); ++ initrd_prefix = grub_strndup(initrds[0], initrd_prefix - initrds[0] + 1); ++ } ++ else ++ { ++ initrd_prefix = grub_strrchr (clinux, '/'); ++ initrd_prefix = grub_strndup(clinux, initrd_prefix - clinux + 1); ++ } ++ ++ if (!initrd_prefix) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto finish; ++ } ++ } ++ ++ if (early_initrds || initrds) ++ { ++ int initrd_size = sizeof ("initrd"); ++ char *tmp; ++ ++ for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) ++ initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \ ++ + grub_strlen(initrd_prefix) \ ++ + grub_strlen (early_initrds[i]) + 1; ++ ++ for (i = 0; initrds != NULL && initrds[i] != NULL; i++) ++ initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \ ++ + grub_strlen (initrds[i]) + 1; ++ initrd_size += 1; ++ ++ initrd = grub_malloc (initrd_size); ++ if (!initrd) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto finish; ++ } ++ ++ tmp = grub_stpcpy(initrd, "initrd"); ++ for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) ++ { ++ grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]); ++ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); ++ tmp = grub_stpcpy (tmp, initrd_prefix); ++ tmp = grub_stpcpy (tmp, early_initrds[i]); ++ grub_free(early_initrds[i]); ++ } ++ ++ for (i = 0; initrds != NULL && initrds[i] != NULL; i++) ++ { ++ grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]); ++ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); ++ tmp = grub_stpcpy (tmp, initrds[i]); ++ } ++ tmp = grub_stpcpy (tmp, "\n"); ++ } ++ ++ if (devicetree) ++ { ++ char *prefix = NULL; ++ int dt_size; ++ ++ if (add_dt_prefix) ++ { ++ prefix = grub_strrchr (clinux, '/'); ++ prefix = grub_strndup(clinux, prefix - clinux + 1); ++ if (!prefix) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto finish; ++ } ++ } ++ ++ dt_size = sizeof("devicetree " GRUB_BOOT_DEVICE) + grub_strlen(devicetree) + 1; ++ ++ if (add_dt_prefix) ++ { ++ dt_size += grub_strlen(prefix); ++ } ++ ++ dt = grub_malloc (dt_size); ++ if (!dt) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto finish; ++ } ++ char *tmp = dt; ++ tmp = grub_stpcpy (dt, "devicetree"); ++ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); ++ if (add_dt_prefix) ++ tmp = grub_stpcpy (tmp, prefix); ++ tmp = grub_stpcpy (tmp, devicetree); ++ tmp = grub_stpcpy (tmp, "\n"); ++ ++ grub_free(prefix); ++ } ++ ++ grub_dprintf ("blscfg2", "devicetree %s for id:\"%s\"\n", dt, id); ++ ++ const char *sdval = grub_env_get("save_default"); ++ bool savedefault = ((NULL != sdval) && (grub_strcmp(sdval, "true") == 0)); ++ src = grub_xasprintf ("%sload_video\n" ++ "set gfxpayload=keep\n" ++ "insmod gzio\n" ++ "linux %s%s%s%s\n" ++ "%s%s", ++ savedefault ? "savedefault\n" : "", ++ GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "", ++ initrd ? initrd : "", dt ? dt : ""); ++ ++ grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, 0, &index, entry); ++ grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id); ++ ++finish: ++ grub_free (dt); ++ grub_free (initrd); ++ grub_free (initrd_prefix); ++ grub_free (early_initrds); ++ grub_free (devicetree); ++ grub_free (initrds); ++ grub_free (options); ++ grub_free (classes); ++ grub_free (args); ++ grub_free (argv); ++ grub_free (src); ++} ++ ++struct find_entry_info { ++ const char *dirname; ++ const char *devid; ++ grub_device_t dev; ++ grub_fs_t fs; ++}; ++ ++/* ++ * info: the filesystem object the file is on. ++ */ ++static int find_entry (struct find_entry_info *info) ++{ ++ struct read_entry_info read_entry_info; ++ grub_fs_t blsdir_fs = NULL; ++ grub_device_t blsdir_dev = NULL; ++ const char *blsdir = info->dirname; ++ int fallback = 0; ++ int r = 0; ++ ++ if (!blsdir) { ++ blsdir = grub_env_get ("blsdir"); ++ if (!blsdir) ++ blsdir = GRUB_BLS_CONFIG_PATH; ++ } ++ ++ read_entry_info.file = NULL; ++ read_entry_info.dirname = blsdir; ++ ++ grub_dprintf ("blscfg", "scanning blsdir: %s\n", blsdir); ++ ++ blsdir_dev = info->dev; ++ blsdir_fs = info->fs; ++ read_entry_info.devid = info->devid; ++ ++read_fallback: ++ r = blsdir_fs->fs_dir (blsdir_dev, read_entry_info.dirname, read_entry, ++ &read_entry_info); ++ if (r != 0) { ++ grub_dprintf ("blscfg", "read_entry returned error\n"); ++ grub_err_t e; ++ do ++ { ++ e = grub_error_pop(); ++ } while (e); ++ } ++ ++ if (r && !info->dirname && !fallback) { ++ read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH; ++ grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n", ++ blsdir, read_entry_info.dirname); ++ fallback = 1; ++ goto read_fallback; ++ } ++ ++ return 0; ++} ++ ++static grub_err_t ++bls_load_entries (const char *path) ++{ ++ grub_size_t len; ++ grub_fs_t fs; ++ grub_device_t dev; ++ static grub_err_t r; ++ const char *devid = NULL; ++ char *blsdir = NULL; ++ struct find_entry_info info = { ++ .dev = NULL, ++ .fs = NULL, ++ .dirname = NULL, ++ }; ++ struct read_entry_info rei = { ++ .devid = NULL, ++ .dirname = NULL, ++ }; ++ ++ if (path) { ++ len = grub_strlen (path); ++ if (grub_strcmp (path + len - 5, ".conf") == 0) { ++ rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG); ++ if (!rei.file) ++ return grub_errno; ++ /* ++ * read_entry() closes the file ++ */ ++ return read_entry(path, NULL, &rei); ++ } else if (path[0] == '(') { ++ devid = path + 1; ++ ++ blsdir = grub_strchr (path, ')'); ++ if (!blsdir) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Filepath isn't correct")); ++ ++ *blsdir = '\0'; ++ blsdir = blsdir + 1; ++ } ++ } ++ ++ if (!devid) { ++#ifdef GRUB_MACHINE_EMU ++ devid = "host"; ++#else ++ devid = grub_env_get ("root"); ++#endif ++ if (!devid) ++ return grub_error (GRUB_ERR_FILE_NOT_FOUND, ++ N_("variable `%s' isn't set"), "root"); ++ } ++ ++ grub_dprintf ("blscfg", "opening %s\n", devid); ++ dev = grub_device_open (devid); ++ if (!dev) ++ return grub_errno; ++ ++ grub_dprintf ("blscfg", "probing fs\n"); ++ fs = grub_fs_probe (dev); ++ if (!fs) ++ { ++ r = grub_errno; ++ goto finish; ++ } ++ ++ info.dirname = blsdir; ++ info.devid = devid; ++ info.dev = dev; ++ info.fs = fs; ++ find_entry(&info); ++ ++finish: ++ if (dev) ++ grub_device_close (dev); ++ ++ return r; ++} ++ ++static bool ++is_default_entry(const char *def_entry, struct bls_entry *entry, int idx) ++{ ++ const char *title; ++ int def_idx; ++ ++ if (!def_entry) ++ return false; ++ ++ if (grub_strcmp(def_entry, entry->filename) == 0) ++ return true; ++ ++ title = bls_get_val(entry, "title", NULL); ++ ++ if (title && grub_strcmp(def_entry, title) == 0) ++ return true; ++ ++ def_idx = (int)grub_strtol(def_entry, NULL, 0); ++ if (grub_errno == GRUB_ERR_BAD_NUMBER) { ++ grub_errno = GRUB_ERR_NONE; ++ return false; ++ } ++ ++ if (def_idx == idx) ++ return true; ++ ++ return false; ++} ++ ++static grub_err_t ++bls_create_entries (bool show_default, bool show_non_default, char *entry_id) ++{ ++ const char *def_entry = NULL; ++ struct bls_entry *entry = NULL; ++ int idx = 0; ++ ++ def_entry = grub_env_get("default"); ++ ++ grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__); ++ FOR_BLS_ENTRIES(entry) { ++ if (entry->visible) { ++ idx++; ++ continue; ++ } ++ ++ if ((show_default && is_default_entry(def_entry, entry, idx)) || ++ (show_non_default && !is_default_entry(def_entry, entry, idx)) || ++ (entry_id && grub_strcmp(entry_id, entry->filename) == 0)) { ++ create_entry(entry); ++ entry->visible = 1; ++ } ++ idx++; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, ++ int argc, char **args) ++{ ++ grub_err_t r; ++ char *path = NULL; ++ char *entry_id = NULL; ++ bool show_default = true; ++ bool show_non_default = true; ++ ++ if (argc == 1) { ++ if (grub_strcmp (args[0], "default") == 0) { ++ show_non_default = false; ++ } else if (grub_strcmp (args[0], "non-default") == 0) { ++ show_default = false; ++ } else if (args[0][0] == '(') { ++ path = args[0]; ++ } else { ++ entry_id = args[0]; ++ show_default = false; ++ show_non_default = false; ++ } ++ } ++ ++ r = bls_load_entries(path); ++ if (r) ++ return r; ++ ++ return bls_create_entries(show_default, show_non_default, entry_id); ++} ++ ++static grub_extcmd_t cmd; ++static grub_extcmd_t oldcmd; ++ ++GRUB_MOD_INIT(blscfg) ++{ ++ grub_dprintf("blscfg", "%s got here\n", __func__); ++ cmd = grub_register_extcmd ("blscfg", ++ grub_cmd_blscfg, ++ 0, ++ NULL, ++ N_("Import Boot Loader Specification snippets."), ++ NULL); ++ oldcmd = grub_register_extcmd ("bls_import", ++ grub_cmd_blscfg, ++ 0, ++ NULL, ++ N_("Import Boot Loader Specification snippets."), ++ NULL); ++} ++ ++GRUB_MOD_FINI(blscfg) ++{ ++ grub_unregister_extcmd (cmd); ++ grub_unregister_extcmd (oldcmd); ++} +diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c +index 54e08a1..3cb8aab 100644 +--- a/grub-core/commands/legacycfg.c ++++ b/grub-core/commands/legacycfg.c +@@ -143,7 +143,7 @@ legacy_file (const char *filename) + args[0] = oldname; + grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy", + NULL, NULL, +- entrysrc, 0, 0); ++ entrysrc, 0, 0, NULL, NULL); + grub_free (args); + entrysrc[0] = 0; + grub_free (oldname); +@@ -205,7 +205,8 @@ legacy_file (const char *filename) + } + args[0] = entryname; + grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, +- NULL, NULL, entrysrc, 0, 0); ++ NULL, NULL, entrysrc, 0, 0, NULL, ++ NULL); + grub_free (args); + } + +diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c +index 1664458..dfcb19e 100644 +--- a/grub-core/commands/loadenv.c ++++ b/grub-core/commands/loadenv.c +@@ -28,6 +28,8 @@ + #include + #include + ++#include "loadenv.h" ++ + GRUB_MOD_LICENSE ("GPLv3+"); + + static const struct grub_arg_option options[] = +@@ -79,81 +81,6 @@ open_envblk_file (char *filename, + return file; + } + +-static grub_envblk_t +-read_envblk_file (grub_file_t file) +-{ +- grub_off_t offset = 0; +- char *buf; +- grub_size_t size = grub_file_size (file); +- grub_envblk_t envblk; +- +- buf = grub_malloc (size); +- if (! buf) +- return 0; +- +- while (size > 0) +- { +- grub_ssize_t ret; +- +- ret = grub_file_read (file, buf + offset, size); +- if (ret <= 0) +- { +- grub_free (buf); +- return 0; +- } +- +- size -= ret; +- offset += ret; +- } +- +- envblk = grub_envblk_open (buf, offset); +- if (! envblk) +- { +- grub_free (buf); +- grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block"); +- return 0; +- } +- +- return envblk; +-} +- +-struct grub_env_whitelist +-{ +- grub_size_t len; +- char **list; +-}; +-typedef struct grub_env_whitelist grub_env_whitelist_t; +- +-static int +-test_whitelist_membership (const char* name, +- const grub_env_whitelist_t* whitelist) +-{ +- grub_size_t i; +- +- for (i = 0; i < whitelist->len; i++) +- if (grub_strcmp (name, whitelist->list[i]) == 0) +- return 1; /* found it */ +- +- return 0; /* not found */ +-} +- +-/* Helper for grub_cmd_load_env. */ +-static int +-set_var (const char *name, const char *value, void *whitelist) +-{ +- if (! whitelist) +- { +- grub_env_set (name, value); +- return 0; +- } +- +- if (test_whitelist_membership (name, +- (const grub_env_whitelist_t *) whitelist)) +- grub_env_set (name, value); +- +- return 0; +-} +- + static grub_err_t + grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args) + { +diff --git a/grub-core/commands/loadenv.h b/grub-core/commands/loadenv.h +new file mode 100644 +index 0000000..952f461 +--- /dev/null ++++ b/grub-core/commands/loadenv.h +@@ -0,0 +1,93 @@ ++/* loadenv.c - command to load/save environment variable. */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. ++ * ++ * 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 . ++ */ ++ ++static grub_envblk_t UNUSED ++read_envblk_file (grub_file_t file) ++{ ++ grub_off_t offset = 0; ++ char *buf; ++ grub_size_t size = grub_file_size (file); ++ grub_envblk_t envblk; ++ ++ buf = grub_malloc (size); ++ if (! buf) ++ return 0; ++ ++ while (size > 0) ++ { ++ grub_ssize_t ret; ++ ++ ret = grub_file_read (file, buf + offset, size); ++ if (ret <= 0) ++ { ++ grub_free (buf); ++ return 0; ++ } ++ ++ size -= ret; ++ offset += ret; ++ } ++ ++ envblk = grub_envblk_open (buf, offset); ++ if (! envblk) ++ { ++ grub_free (buf); ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block"); ++ return 0; ++ } ++ ++ return envblk; ++} ++ ++struct grub_env_whitelist ++{ ++ grub_size_t len; ++ char **list; ++}; ++typedef struct grub_env_whitelist grub_env_whitelist_t; ++ ++static int UNUSED ++test_whitelist_membership (const char* name, ++ const grub_env_whitelist_t* whitelist) ++{ ++ grub_size_t i; ++ ++ for (i = 0; i < whitelist->len; i++) ++ if (grub_strcmp (name, whitelist->list[i]) == 0) ++ return 1; /* found it */ ++ ++ return 0; /* not found */ ++} ++ ++/* Helper for grub_cmd_load_env. */ ++static int UNUSED ++set_var (const char *name, const char *value, void *whitelist) ++{ ++ if (! whitelist) ++ { ++ grub_env_set (name, value); ++ return 0; ++ } ++ ++ if (test_whitelist_membership (name, ++ (const grub_env_whitelist_t *) whitelist)) ++ grub_env_set (name, value); ++ ++ return 0; ++} +diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c +index c369137..9da1478 100644 +--- a/grub-core/commands/menuentry.c ++++ b/grub-core/commands/menuentry.c +@@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char **args, + char **classes, const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, +- int submenu, int hidden) ++ int submenu, int hidden, int *index, struct bls_entry *bls) + { + int menu_hotkey = 0; + char **menu_args = NULL; +@@ -149,9 +149,12 @@ grub_normal_add_menu_entry (int argc, const char **args, + if (! menu_title) + goto fail; + ++ grub_dprintf ("menu", "id:\"%s\"\n", id); ++ grub_dprintf ("menu", "title:\"%s\"\n", menu_title); + menu_id = grub_strdup (id ? : menu_title); + if (! menu_id) + goto fail; ++ grub_dprintf ("menu", "menu_id:\"%s\"\n", menu_id); + + /* Save argc, args to pass as parameters to block arg later. */ + menu_args = grub_calloc (argc + 1, sizeof (char *)); +@@ -170,8 +173,12 @@ grub_normal_add_menu_entry (int argc, const char **args, + } + + /* Add the menu entry at the end of the list. */ ++ int ind=0; + while (*last) +- last = &(*last)->next; ++ { ++ ind++; ++ last = &(*last)->next; ++ } + + *last = grub_zalloc (sizeof (**last)); + if (! *last) +@@ -189,9 +196,12 @@ grub_normal_add_menu_entry (int argc, const char **args, + (*last)->sourcecode = menu_sourcecode; + (*last)->submenu = submenu; + (*last)->hidden = hidden; ++ (*last)->bls = bls; + + if (!hidden) + menu->size++; ++ if (index) ++ *index = ind; + + return GRUB_ERR_NONE; + +@@ -290,7 +300,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) + ctxt->state[2].arg, 0, + ctxt->state[3].arg, + ctxt->extcmd->cmd->name[0] == 's', +- ctxt->extcmd->cmd->name[0] == 'h'); ++ ctxt->extcmd->cmd->name[0] == 'h', ++ NULL, NULL); + + src = args[argc - 1]; + args[argc - 1] = NULL; +@@ -308,7 +319,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) + users, + ctxt->state[2].arg, prefix, src + 1, + ctxt->extcmd->cmd->name[0] == 's', +- ctxt->extcmd->cmd->name[0] == 'h'); ++ ctxt->extcmd->cmd->name[0] == 'h', NULL, ++ NULL); + + src[len - 1] = ch; + args[argc - 1] = src; +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 321db8c..f3e14bf 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -71,6 +72,11 @@ grub_normal_free_menu (grub_menu_t menu) + grub_free (entry->args); + } + ++ if (entry->bls) ++ { ++ entry->bls->visible = 0; ++ } ++ + grub_free ((void *) entry->id); + grub_free ((void *) entry->users); + grub_free ((void *) entry->title); +diff --git a/include/grub/compiler.h b/include/grub/compiler.h +index 0c55193..441a9ec 100644 +--- a/include/grub/compiler.h ++++ b/include/grub/compiler.h +@@ -56,4 +56,6 @@ + # define CLANG_PREREQ(maj,min) 0 + #endif + ++#define UNUSED __attribute__((__unused__)) ++ + #endif /* ! GRUB_COMPILER_HEADER */ +diff --git a/include/grub/menu.h b/include/grub/menu.h +index eb8a86b..4308082 100644 +--- a/include/grub/menu.h ++++ b/include/grub/menu.h +@@ -20,6 +20,16 @@ + #ifndef GRUB_MENU_HEADER + #define GRUB_MENU_HEADER 1 + ++struct bls_entry ++{ ++ struct bls_entry *next; ++ struct bls_entry *prev; ++ struct keyval **keyvals; ++ int nkeyvals; ++ char *filename; ++ int visible; ++}; ++ + struct grub_menu_entry_class + { + char *name; +@@ -62,6 +72,9 @@ struct grub_menu_entry + + /* The next element. */ + struct grub_menu_entry *next; ++ ++ /* BLS used to populate the entry */ ++ struct bls_entry *bls; + }; + typedef struct grub_menu_entry *grub_menu_entry_t; + +diff --git a/include/grub/normal.h b/include/grub/normal.h +index bcb4124..8c712a9 100644 +--- a/include/grub/normal.h ++++ b/include/grub/normal.h +@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, + const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, +- int submenu, int hidden); ++ int submenu, int hidden, int *index, struct bls_entry *bls); + + grub_err_t + grub_normal_set_password (const char *user, const char *password); +-- +2.43.0 + diff --git a/0061-Add-BLS-support-to-grub-mkconfig.patch b/0061-Add-BLS-support-to-grub-mkconfig.patch new file mode 100644 index 0000000..bd7c3db --- /dev/null +++ b/0061-Add-BLS-support-to-grub-mkconfig.patch @@ -0,0 +1,394 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 9 Dec 2016 15:40:29 -0500 +Subject: [PATCH] Add BLS support to grub-mkconfig + +GRUB now has BootLoaderSpec support, the user can choose to use this by +setting GRUB_ENABLE_BLSCFG to true in /etc/default/grub. On this setup, +the boot menu entries are not added to the grub.cfg, instead BLS config +files are parsed by blscfg command and the entries created dynamically. + +A 10_linux_bls grub.d snippet to generate menu entries from BLS files +is also added that can be used on platforms where the bootloader doesn't +have BLS support and only can parse a normal grub configuration file. + +Portions of the 10_linux_bls were taken from the ostree-grub-generator +script that's included in the OSTree project. + +Fixes to support multi-devices and generate a BLS section even if no +kernels are found in the boot directory were proposed by Yclept Nemo +and Tom Gundersen respectively. + +Signed-off-by: Peter Jones +[javierm: remove outdated URL for BLS document] +Signed-off-by: Javier Martinez Canillas +Signed-off-by: Robbie Harwood +--- + util/grub-mkconfig.8 | 4 + + util/grub-mkconfig.in | 9 +- + util/grub-mkconfig_lib.in | 22 +++- + util/grub.d/10_linux.in | 222 +++++++++++++++++++++++++++++++++++++- + 4 files changed, 251 insertions(+), 6 deletions(-) + +diff --git a/util/grub-mkconfig.8 b/util/grub-mkconfig.8 +index a2d1f57..434fa4d 100644 +--- a/util/grub-mkconfig.8 ++++ b/util/grub-mkconfig.8 +@@ -13,5 +13,9 @@ + \fB--output\fR=\fIFILE\fR + Write generated output to \fIFILE\fR. + ++.TP ++\fB--no-grubenv-update\fR ++Do not update variables in the grubenv file. ++ + .SH SEE ALSO + .BR "info grub" +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index f939872..212bbcf 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -50,6 +50,8 @@ grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" + export TEXTDOMAIN=@PACKAGE@ + export TEXTDOMAINDIR="@localedir@" + ++export GRUB_GRUBENV_UPDATE="yes" ++ + . "${pkgdatadir}/grub-mkconfig_lib" + + # Usage: usage +@@ -59,6 +61,7 @@ usage () { + gettext "Generate a grub config file"; echo + echo + print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")" ++ print_option_help "--no-grubenv-update" "$(gettext "do not update variables in the grubenv file")" + print_option_help "-h, --help" "$(gettext "print this message and exit")" + print_option_help "-V, --version" "$(gettext "print the version information and exit")" + echo +@@ -94,6 +97,9 @@ do + --output=*) + grub_cfg=`echo "$option" | sed 's/--output=//'` + ;; ++ --no-grubenv-update) ++ GRUB_GRUBENV_UPDATE="no" ++ ;; + -*) + gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 + usage +@@ -305,7 +311,8 @@ export GRUB_DEFAULT \ + GRUB_DISABLE_SUBMENU \ + SUSE_BTRFS_SNAPSHOT_BOOTING \ + SUSE_CMDLINE_XENEFI \ +- SUSE_REMOVE_LINUX_ROOT_PARAM ++ SUSE_REMOVE_LINUX_ROOT_PARAM \ ++ GRUB_ENABLE_BLSCFG + + if test "x${grub_cfg}" != "x"; then + rm -f "${grub_cfg}.new" +diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in +index 22fb766..5db4337 100644 +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -30,6 +30,9 @@ fi + if test "x$grub_file" = x; then + grub_file="${bindir}/@grub_file@" + fi ++if test "x$grub_editenv" = x; then ++ grub_editenv="${bindir}/@grub_editenv@" ++fi + if test "x$grub_mkrelpath" = x; then + grub_mkrelpath="${bindir}/@grub_mkrelpath@" + fi +@@ -123,8 +126,19 @@ EOF + fi + } + ++prepare_grub_to_access_device_with_variable () ++{ ++ device_variable="$1" ++ shift ++ prepare_grub_to_access_device "$@" ++ unset "device_variable" ++} ++ + prepare_grub_to_access_device () + { ++ if [ -z "$device_variable" ]; then ++ device_variable="root" ++ fi + old_ifs="$IFS" + IFS=' + ' +@@ -159,18 +173,18 @@ prepare_grub_to_access_device () + # otherwise set root as per value in device.map. + fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`" + if [ "x$fs_hint" != x ]; then +- echo "set root='$fs_hint'" ++ echo "set ${device_variable}='$fs_hint'" + fi + if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then + hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints= + if [ "x$hints" != x ]; then + echo "if [ x\$feature_platform_search_hint = xy ]; then" +- echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" ++ echo " search --no-floppy --fs-uuid --set=${device_variable} ${hints} ${fs_uuid}" + echo "else" +- echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" ++ echo " search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" + echo "fi" + else +- echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}" ++ echo "search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" + fi + fi + IFS="$old_ifs" +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 467accb..af09e65 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -88,6 +88,223 @@ case x"$GRUB_FS" in + ;; + esac + ++populate_header_warn() ++{ ++if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then ++ bls_parser="10_linux script" ++else ++ bls_parser="blscfg command" ++fi ++cat </dev/null | tac)) || : ++ ++ echo "${files[@]}" ++} ++ ++update_bls_cmdline() ++{ ++ local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" ++ local -a files=($(get_sorted_bls)) ++ ++ for bls in "${files[@]}"; do ++ local options="${cmdline}" ++ if [ -z "${bls##*debug*}" ]; then ++ options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}" ++ fi ++ options="$(echo "${options}" | sed -e 's/\//\\\//g')" ++ sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf" ++ done ++} ++ ++populate_menu() ++{ ++ local -a files=($(get_sorted_bls)) ++ ++ gettext_printf "Generating boot entries from BLS files...\n" >&2 ++ ++ for bls in "${files[@]}"; do ++ read_config "${blsdir}/${bls}.conf" ++ ++ menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n" ++ menu="${menu}\t linux ${linux} ${options}\n" ++ if [ -n "${initrd}" ] ; then ++ menu="${menu}\t initrd ${boot_prefix}${initrd}\n" ++ fi ++ menu="${menu}}\n\n" ++ done ++ # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation ++ printf "$menu" ++} ++ ++# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed. ++if [ -z "${GRUB_ENABLE_BLSCFG}" ] && [ -z "$(which new-kernel-pkg 2> /dev/null)" ]; then ++ GRUB_ENABLE_BLSCFG="true" ++fi ++ ++if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then ++ if [ x$dirname = x/ ]; then ++ if [ -z "${prepare_root_cache}" ]; then ++ prepare_grub_to_access_device ${GRUB_DEVICE} ++ fi ++ else ++ if [ -z "${prepare_boot_cache}" ]; then ++ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} ++ fi ++ fi ++ ++ if [ -d /sys/firmware/efi ]; then ++ bootefi_device="`${grub_probe} --target=device /boot/efi/`" ++ prepare_grub_to_access_device_with_variable boot ${bootefi_device} ++ else ++ boot_device="`${grub_probe} --target=device /boot/`" ++ prepare_grub_to_access_device_with_variable boot ${boot_device} ++ fi ++ ++ arch="$(uname -m)" ++ if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then ++ ++ BLS_POPULATE_MENU="true" ++ petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot" ++ ++ if test -e ${petitboot_path}; then ++ read -r -d '' petitboot_version < ${petitboot_path} ++ petitboot_version="$(echo ${petitboot_version//v})" ++ ++ if test -n ${petitboot_version}; then ++ major_version="$(echo ${petitboot_version} | cut -d . -f1)" ++ minor_version="$(echo ${petitboot_version} | cut -d . -f2)" ++ ++ re='^[0-9]+$' ++ if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] && ++ ([[ ${major_version} -gt 1 ]] || ++ [[ ${major_version} -eq 1 && ++ ${minor_version} -ge 8 ]]); then ++ BLS_POPULATE_MENU="false" ++ fi ++ fi ++ fi ++ fi ++ ++ populate_header_warn ++ ++ cat << EOF ++# The kernelopts variable should be defined in the grubenv file. But to ensure that menu ++# entries populated from BootLoaderSpec files that use this variable work correctly even ++# without a grubenv file, define a fallback kernelopts variable if this has not been set. ++# ++# The kernelopts variable in the grubenv file can be modified using the grubby tool or by ++# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX ++# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both ++# the kernelopts variable in the grubenv file and the fallback kernelopts variable. ++if [ -z "\${kernelopts}" ]; then ++ set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" ++fi ++EOF ++ ++ update_bls_cmdline ++ ++ if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then ++ populate_menu ++ else ++ cat << EOF ++ ++insmod blscfg ++blscfg ++EOF ++ fi ++ ++ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then ++ blsdir="/boot/loader/entries" ++ [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})" ++ if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then ++ blsdir=$(make_system_path_relative_to_its_root "${blsdir}") ++ if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then ++ ${grub_editenv} - set blsdir="${blsdir}" ++ fi ++ fi ++ ++ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then ++ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ++ fi ++ ++ if [ -n "${GRUB_DEFAULT_DTB}" ]; then ++ ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}" ++ fi ++ ++ if [ -n "${GRUB_SAVEDEFAULT}" ]; then ++ ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}" ++ fi ++ fi ++ ++ exit 0 ++fi ++ + mktitle () + { + local title_type +@@ -152,6 +369,7 @@ linux_entry () + if [ -z "$boot_device_id" ]; then + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi ++ + if [ x$type != xsimple ] ; then + title=$(mktitle "$type" "$version") + if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then +@@ -373,7 +591,9 @@ for linux in ${reverse_sorted_list}; do + for i in ${initrd}; do + initrd_display="${initrd_display} ${dirname}/${i}" + done +- gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 ++ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then ++ gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 ++ fi + fi + + config= +-- +2.43.0 + diff --git a/0064-Add-grub2-switch-to-blscfg.patch b/0064-Add-grub2-switch-to-blscfg.patch new file mode 100644 index 0000000..d48bf89 --- /dev/null +++ b/0064-Add-grub2-switch-to-blscfg.patch @@ -0,0 +1,400 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 15 Mar 2018 14:12:40 -0400 +Subject: [PATCH] Add grub2-switch-to-blscfg + +Signed-off-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +[jhlavac: Use ${etcdefaultgrub} instead of /etc/default/grub] +Signed-off-by: Jan Hlavac +--- + Makefile.util.def | 7 + + util/grub-switch-to-blscfg.8 | 33 ++++ + util/grub-switch-to-blscfg.in | 317 ++++++++++++++++++++++++++++++++++ + 3 files changed, 357 insertions(+) + create mode 100644 util/grub-switch-to-blscfg.8 + create mode 100644 util/grub-switch-to-blscfg.in + +diff --git a/Makefile.util.def b/Makefile.util.def +index b6ba07b..ae3df11 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -1463,6 +1463,13 @@ program = { + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + }; + ++script = { ++ name = grub-switch-to-blscfg; ++ common = util/grub-switch-to-blscfg.in; ++ mansection = 8; ++ installdir = sbin; ++}; ++ + program = { + name = grub-glue-efi; + mansection = 1; +diff --git a/util/grub-switch-to-blscfg.8 b/util/grub-switch-to-blscfg.8 +new file mode 100644 +index 0000000..9a88628 +--- /dev/null ++++ b/util/grub-switch-to-blscfg.8 +@@ -0,0 +1,33 @@ ++.TH GRUB-SWITCH-TO-BLSCFG 1 "Wed Feb 26 2014" ++.SH NAME ++\fBgrub-switch-to-blscfg\fR \(em Switch to using BLS config files. ++ ++.SH SYNOPSIS ++\fBgrub-switch-to-blscfg\fR [--grub-directory=\fIDIR\fR] [--config-file=\fIFILE\fR] [--grub-defaults=\fIFILE\fR] ++ ++.SH DESCRIPTION ++\fBgrub-switch-to-blscfg\fR reconfigures grub-mkconfig to use BLS-style config files, and then regenerates the GRUB configuration. ++ ++.SH OPTIONS ++.TP ++--grub-directory=\fIDIR\fR ++Search for grub.cfg under \fIDIR\fR. The default value is \fI/boot/efi/EFI/\fBVENDOR\fR on UEFI machines and \fI/boot/grub2\fR elsewhere. ++ ++.TP ++--config-file=\fIFILE\fR ++The grub config file to use. The default value is \fI/etc/grub2-efi.cfg\fR on UEFI machines and \fI/etc/grub2.cfg\fR elsewhere. Symbolic links will be followed. ++ ++.TP ++--grub-defaults=\fIFILE\fR ++The defaults file for grub-mkconfig. The default value is \fI/etc/default/grub\fR. ++ ++.TP ++--bls-directory=\fIDIR\fR ++Create BootLoaderSpec fragments in \fIDIR\fR. The default value is \fI/boot/loader/entries\fR. ++ ++.TP ++--backup-suffix=\fSUFFIX\fR ++The suffix to use for saved backup files. The default value is \fI.bak\fR. ++ ++.SH SEE ALSO ++.BR "info grub" +diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in +new file mode 100644 +index 0000000..a851424 +--- /dev/null ++++ b/util/grub-switch-to-blscfg.in +@@ -0,0 +1,317 @@ ++#! /bin/sh ++# ++# Set a default boot entry for GRUB. ++# Copyright (C) 2004,2009 Free Software Foundation, Inc. ++# ++# 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 . ++ ++#set -eu ++ ++# Initialize some variables. ++prefix=@prefix@ ++exec_prefix=@exec_prefix@ ++sbindir=@sbindir@ ++bindir=@bindir@ ++sysconfdir="@sysconfdir@" ++PACKAGE_NAME=@PACKAGE_NAME@ ++PACKAGE_VERSION=@PACKAGE_VERSION@ ++datarootdir="@datarootdir@" ++datadir="@datadir@" ++if [ ! -v pkgdatadir ]; then ++ pkgdatadir="${datadir}/@PACKAGE@" ++fi ++ ++self=`basename $0` ++ ++grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" ++grub_editenv=${bindir}/@grub_editenv@ ++etcdefaultgrub=/etc/default/grub ++ ++eval "$("${grub_get_kernel_settings}")" || true ++ ++EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') ++if [ -d /sys/firmware/efi/efivars/ ]; then ++ startlink=/etc/grub2-efi.cfg ++ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` ++else ++ startlink=/etc/grub2.cfg ++ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` ++fi ++ ++blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'` ++ ++backupsuffix=.bak ++ ++arch="$(uname -m)" ++ ++export TEXTDOMAIN=@PACKAGE@ ++export TEXTDOMAINDIR="@localedir@" ++ ++. "${pkgdatadir}/grub-mkconfig_lib" ++ ++# Usage: usage ++# Print the usage. ++usage () { ++ gettext_printf "Usage: %s\n" "$self" ++ gettext "Switch to BLS config files.\n"; echo ++ echo ++ print_option_help "-h, --help" "$(gettext "print this message and exit")" ++ print_option_help "-V, --version" "$(gettext "print the version information and exit")" ++ echo ++ print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix" ++ print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir" ++ print_option_help "--config-file=$(gettext "FILE")" "$startlink" ++ print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub" ++ print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir" ++ # echo ++ # gettext "Report bugs to ."; echo ++} ++ ++argument () { ++ opt=$1 ++ shift ++ ++ if test $# -eq 0; then ++ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 ++ exit 1 ++ fi ++ echo $1 ++} ++ ++# Check the arguments. ++while test $# -gt 0 ++do ++ option=$1 ++ shift ++ ++ case "$option" in ++ -h | --help) ++ usage ++ exit 0 ;; ++ -V | --version) ++ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" ++ exit 0 ;; ++ ++ --backup-suffix) ++ backupsuffix=`argument $option "$@"` ++ shift ++ ;; ++ --backup-suffix=*) ++ backupsuffix=`echo "$option" | sed 's/--backup-suffix=//'` ++ ;; ++ ++ --bls-directory) ++ blsdir=`argument $option "$@"` ++ shift ++ ;; ++ --bls-directory=*) ++ blsdir=`echo "$option" | sed 's/--bls-directory=//'` ++ ;; ++ ++ --config-file) ++ startlink=`argument $option "$@"` ++ shift ++ ;; ++ --config-file=*) ++ startlink=`echo "$option" | sed 's/--config-file=//'` ++ ;; ++ ++ --grub-defaults) ++ etcdefaultgrub=`argument $option "$@"` ++ shift ++ ;; ++ --grub-defaults=*) ++ etcdefaultgrub=`echo "$option" | sed 's/--grub-defaults=//'` ++ ;; ++ ++ --grub-directory) ++ grubdir=`argument $option "$@"` ++ shift ++ ;; ++ --grub-directory=*) ++ grubdir=`echo "$option" | sed 's/--grub-directory=//'` ++ ;; ++ ++ *) ++ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 ++ usage ++ exit 1 ++ ;; ++ esac ++done ++ ++find_grub_cfg() { ++ local candidate="" ++ while [ -e "${candidate}" -o $# -gt 0 ] ++ do ++ if [ ! -e "${candidate}" ] ; then ++ candidate="$1" ++ shift ++ fi ++ ++ if [ -L "${candidate}" ]; then ++ candidate="$(realpath "${candidate}")" ++ fi ++ ++ if [ -f "${candidate}" ]; then ++ export GRUB_CONFIG_FILE="${candidate}" ++ return 0 ++ fi ++ done ++ return 1 ++} ++ ++if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then ++ gettext_printf "Couldn't find config file\n" 1>&2 ++ exit 1 ++fi ++ ++if [ ! -d "${blsdir}" ]; then ++ install -m 700 -d "${blsdir}" ++fi ++ ++if [ -f /etc/machine-id ]; then ++ MACHINE_ID=$(cat /etc/machine-id) ++else ++ MACHINE_ID=$(dmesg | sha256sum) ++fi ++ ++mkbls() { ++ local kernelver=$1 && shift ++ local datetime=$1 && shift ++ local kernelopts=$1 && shift ++ ++ local debugname="" ++ local debugid="" ++ local flavor="" ++ ++ if [ "$kernelver" == *\+* ] ; then ++ local flavor=-"${kernelver##*+}" ++ if [ "${flavor}" == "-debug" ]; then ++ local debugname=" with debugging" ++ local debugid="-debug" ++ fi ++ fi ++ ( ++ source /etc/os-release ++ ++ cat <"${bls_target}" ++ ++ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then ++ bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")" ++ cp -aT "${bls_target}" "${bls_debug}" ++ title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')" ++ options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')" ++ sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}" ++ sed -i -e "s/^options.*/options ${options}/" "${bls_debug}" ++ fi ++ done ++ ++ if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then ++ mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf" ++ fi ++} ++ ++# The grub2 EFI binary is not copied to the ESP as a part of an ostree ++# transaction. Make sure a grub2 version with BLS support is installed ++# but only do this if the blsdir is not set, to make sure that the BLS ++# parsing module will search for the BLS snippets in the default path. ++if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \ ++ ! ${grub_editenv} - list | grep -q blsdir && \ ++ mountpoint -q /boot; then ++ grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)" ++ install -m 700 ${grub_binary} ${grubdir} || exit 1 ++ # Create a hidden file to indicate that grub2 now has BLS support. ++ touch /boot/grub2/.grub2-blscfg-supported ++fi ++ ++GENERATE=0 ++if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \ ++ | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then ++ if ! sed -i"${backupsuffix}" \ ++ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=true,' \ ++ "${etcdefaultgrub}" ; then ++ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" ++ exit 1 ++ fi ++ GENERATE=1 ++elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then ++ if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then ++ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" ++ exit 1 ++ fi ++ GENERATE=1 ++fi ++ ++if [ "${GENERATE}" -eq 1 ] ; then ++ copy_bls ++ ++ if [ $arch = "x86_64" ] && [ ! -d /sys/firmware/efi ]; then ++ mod_dir="i386-pc" ++ elif [ $arch = "ppc64" -o $arch = "ppc64le" ] && [ ! -d /sys/firmware/opal ]; then ++ mod_dir="powerpc-ieee1275" ++ fi ++ ++ if [ -n "${mod_dir}" ]; then ++ for mod in blscfg increment; do ++ install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1 ++ done ++ fi ++ ++ cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}" ++ if ! grub2-mkconfig -o "${GRUB_CONFIG_FILE}" ; then ++ install -m 700 "${GRUB_CONFIG_FILE}${backupsuffix}" "${GRUB_CONFIG_FILE}" ++ sed -i"${backupsuffix}" \ ++ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=false,' \ ++ "${etcdefaultgrub}" ++ gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}" ++ exit 1 ++ fi ++fi ++ ++# Bye. ++exit 0 +-- +2.43.0 + diff --git a/grub.macros b/grub.macros index 48a3dc3..2b299db 100644 --- a/grub.macros +++ b/grub.macros @@ -439,7 +439,7 @@ install -m 700 %{3}.orig %{3} \ %endif %define do_efi_build_images() \ -GRUB_MODULES=" all_video boot btrfs \\\ +GRUB_MODULES=" all_video boot blscfg btrfs \\\ cat configfile cryptodisk \\\ echo efifwsetup efinet ext2 f2fs \\\ fat font gcry_rijndael gcry_rsa gcry_serpent \\\ diff --git a/grub.patches b/grub.patches index 4e989f5..73c747e 100644 --- a/grub.patches +++ b/grub.patches @@ -236,3 +236,6 @@ Patch235: backport-CVE-2021-46848-lib-libtasn1-Fix-ETYPE_OK-off-by-one-arr Patch236: backport-disk-mdraid1x_linux-Prevent-infinite-recursion.patch Patch237: backport-Export-all-variables-from-the-initial-context-when-c.patch Patch238: grub2-ppc64le-fix-bug-about-petitboot-doesn-t-ignore-EFI-entries.patch +Patch239: 0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch +Patch240: 0061-Add-BLS-support-to-grub-mkconfig.patch +Patch241: 0064-Add-grub2-switch-to-blscfg.patch diff --git a/grub2.spec b/grub2.spec index 190d88b..2062b41 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 22 +Release: 23 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -348,7 +348,7 @@ fi %files tools %defattr(-,root,root) %{_sbindir}/%{name}-mkconfig -#%{_sbindir}/%{name}-switch-to-blscfg +%{_sbindir}/%{name}-switch-to-blscfg #%{_sbindir}/%{name}-rpm-sort %{_sbindir}/%{name}-reboot %{_sbindir}/%{name}-install @@ -456,6 +456,12 @@ fi %{_datadir}/man/man* %changelog +* Wed Jul 24 2024 wangyueliang - 1:2.12-23 +- Type:requirement +- CVE:NA +- SUG:NA +- DESC:Inherit 'Add BLS Support' patch from grub-2.06 + * Mon Jul 15 2024 peng.zou - 1:2.12-22 - Type:bugfix - CVE:NA -- Gitee From a7bed1ec2784c3fbbd87a370d45c82c4fc351109 Mon Sep 17 00:00:00 2001 From: chench00 Date: Tue, 6 Aug 2024 20:21:15 +0800 Subject: [PATCH 26/26] add support for hygon tpcm --- ...wfeature-tpcm-add-hygon-tpcm-support.patch | 374 ++++++++++++++++++ grub.macros | 3 + grub.patches | 1 + grub2.spec | 8 +- 4 files changed, 385 insertions(+), 1 deletion(-) create mode 100644 0001-newfeature-tpcm-add-hygon-tpcm-support.patch diff --git a/0001-newfeature-tpcm-add-hygon-tpcm-support.patch b/0001-newfeature-tpcm-add-hygon-tpcm-support.patch new file mode 100644 index 0000000..d914d2d --- /dev/null +++ b/0001-newfeature-tpcm-add-hygon-tpcm-support.patch @@ -0,0 +1,374 @@ +From da39c467f634f19ce913d8454b9a1be6d0f5f82a Mon Sep 17 00:00:00 2001 +From: chench +Date: Thu, 5 Dec 2023 20:37:04 +0800 +Subject: [PATCH] newfeature: tpcm: add tpcm support + +--- + grub-core/Makefile.core.def | 7 ++ + grub-core/commands/efi/tpcm_hygon.c | 163 ++++++++++++++++++++++++++++ + grub-core/commands/tpcm_hygon.c | 100 +++++++++++++++++ + include/grub/efi/tpcm_hygon.h | 42 ++++++++ + include/grub/err.h | 3 +- + 5 files changed, 314 insertions(+), 1 deletion(-) + create mode 100755 grub-core/commands/efi/tpcm_hygon.c + create mode 100755 grub-core/commands/tpcm_hygon.c + create mode 100644 include/grub/efi/tpcm_hygon.h + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 4fb34b1..681f65a 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2623,6 +2623,13 @@ module = { + enable = efi; + }; + ++module = { ++ name = tpcm_hygon; ++ common = commands/tpcm_hygon.c; ++ efi = commands/efi/tpcm_hygon.c; ++ enable = x86_64_efi; ++}; ++ + module = { + name = tr; + common = commands/tr.c; +diff --git a/grub-core/commands/efi/tpcm_hygon.c b/grub-core/commands/efi/tpcm_hygon.c +new file mode 100755 +index 0000000..ffe86ef +--- /dev/null ++++ b/grub-core/commands/efi/tpcm_hygon.c +@@ -0,0 +1,163 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2018 Free Software Foundation, Inc. ++ * ++ * 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 . ++ * ++ * EFI TPCM support code. ++ */ ++ ++#include ++#include ++ ++ ++static grub_uint32_t g_measured_id = STAGE_START; ++ ++/* ++ get_tpcm_stage: ++ TPCM does not make a distinction with the type of ++ measured target, so we use g_measured_id directly ++ for the stage. ++ */ ++static grub_uint32_t get_tpcm_stage(void) ++{ ++ grub_uint32_t stage = STAGE_INVALID; ++ ++ stage = g_measured_id; ++ ++ if (stage < STAGE_START || stage > STAGE_END) ++ stage = STAGE_INVALID; ++ ++ return stage; ++} ++ ++/* ++ update_measured_id: ++ update g_measured_id +1 every time measured, and g_measured_id ++ will never be decreased. ++ */ ++static void update_measured_id(void) ++{ ++ g_measured_id++; ++} ++ ++/* ++ measure_memory: ++ measure the memery region--(addr, size) through the TPCM protocol. ++ if TPCM protocol is not exist in BIOS, it will return SUCC to keep ++ compatible with non-measurement-support bios; if TPCM protocol is ++ exist but not enabled, it will also return SUCC. ++ */ ++static grub_err_t measure_memory(enum grub_file_type type __attribute__((unused)), ++ char *desc, ++ grub_addr_t addr, ++ grub_size_t size) ++{ ++ grub_efi_handle_t *handles = 0; ++ grub_efi_uintn_t num_handles; ++ grub_efi_handle_t grub_c2p_handle = 0; ++ grub_err_t test_c2p_err = GRUB_ERR_BAD_OS; ++ grub_guid_t c2p_guid = C2PGUID; ++ grub_uint32_t measure_result = 0; ++ grub_uint32_t control_result = 0; ++ grub_efi_boolean_t verify_enable = 0; ++ grub_size_t desc_len = 0; ++ ++ handles = grub_efi_locate_handle(GRUB_EFI_BY_PROTOCOL, &c2p_guid, NULL, &num_handles); ++ if (handles && (num_handles > 0)) ++ { ++ struct c2p_protocol *c2p; ++ ++ grub_c2p_handle = handles[0]; ++ grub_dprintf("tpcm_hygon", "measue memory addr 0x%lx size 0x%lx \n", addr, size); ++ c2p = grub_efi_open_protocol(grub_c2p_handle, &c2p_guid, ++ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (c2p) ++ { ++ verify_enable = c2p->verify_is_enabled (c2p); ++ if (verify_enable) ++ { ++ struct addr_range range; ++ grub_efi_status_t status = 0; ++ grub_uint32_t stage = STAGE_INVALID; ++ ++ range.start = addr; ++ range.length = size; ++ ++ stage = get_tpcm_stage(); ++ if (stage != STAGE_INVALID) ++ { ++ desc_len = grub_strlen(desc) + 1; ++ status = c2p->verify_raw (c2p, stage, (grub_uint64_t)desc, desc_len, 1, &range, &measure_result, &control_result); ++ if ((!status) && ((control_result & MEASURE_ACTION_MASK) == 0) ) ++ { ++ grub_dprintf("tpcm_hygon", "verify_raw success. stage[%d]desc:[%s]\n", stage, desc); ++ test_c2p_err = GRUB_ERR_NONE; ++ } ++ else ++ { ++ grub_dprintf("tpcm_hygon", "verify_raw error\n"); ++ while(1) ++ { ++ grub_error(GRUB_ERR_TPCM_VERIFY, "tpcm verify error. stage[%d]desc[%s]\n", stage, desc); ++ asm volatile ("hlt"); ++ } ++ } ++ } ++ else { ++ grub_dprintf ("tpcm_hygon", "invalid stage\n"); ++ } ++ ++ update_measured_id(); ++ ++ } ++ else { ++ grub_dprintf ("tpcm_hygon", "image verify not enabled\n"); ++ test_c2p_err = GRUB_ERR_NONE; ++ } ++ } ++ else ++ grub_dprintf ("tpcm_hygon", "open c2p protocol failed\n"); ++ } ++ else ++ { ++ // keep compatible with non-measurement-support bios. ++ grub_dprintf("tpcm_hygon", "not found C2P protocol\n"); ++ test_c2p_err = GRUB_ERR_NONE; ++ } ++ ++ return test_c2p_err; ++} ++ ++/* ++ grub_tpcm_measure_memory: ++ */ ++grub_err_t grub_tpcm_measure_memory(void *context, grub_addr_t buf, grub_size_t size) ++{ ++ char *p_context = (char *)context; ++ char *p, *p_desc; ++ char tmp[TPCM_MAX_BUF_SIZE] = {'0'}; ++ enum grub_file_type type; ++ ++ if (!p_context) ++ return GRUB_ERR_BUG; ++ ++ p = grub_strchr(p_context, '|'); ++ p_desc = p + 1; ++ grub_memcpy(tmp, p_context, (p-p_context)); ++ type = grub_strtoul(tmp, 0, 10); ++ ++ return measure_memory(type, p_desc, buf, size); ++} ++ +diff --git a/grub-core/commands/tpcm_hygon.c b/grub-core/commands/tpcm_hygon.c +new file mode 100755 +index 0000000..564ab85 +--- /dev/null ++++ b/grub-core/commands/tpcm_hygon.c +@@ -0,0 +1,100 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2018 Free Software Foundation, Inc. ++ * ++ * 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 . ++ * ++ * Core TPCM support code. ++ */ ++ ++ ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static char context_buf[TPCM_MAX_BUF_SIZE]; ++ ++static grub_err_t grub_tpcm_verify_init(grub_file_t io, ++ enum grub_file_type type, ++ void **context, ++ enum grub_verify_flags *flags) ++{ ++ grub_memset(context_buf, 0, TPCM_MAX_BUF_SIZE); ++ grub_snprintf(context_buf, TPCM_MAX_BUF_SIZE, "%d|%s", (type & GRUB_FILE_TYPE_MASK), io->name); ++ *context = context_buf; ++ *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t grub_tpcm_verify_write(void *context, void *buf , grub_size_t size ) ++{ ++ return grub_tpcm_measure_memory(context, (grub_addr_t)buf, size); ++} ++ ++static grub_err_t grub_tpcm_verify_string (char *str, enum grub_verify_string_type type) ++{ ++ const char *prefix = NULL; ++ char *description, *context; ++ grub_err_t status; ++ ++ switch (type) ++ { ++ case GRUB_VERIFY_KERNEL_CMDLINE: ++ prefix = "kernel_cmdline: "; ++ break; ++ case GRUB_VERIFY_MODULE_CMDLINE: ++ prefix = "module_cmdline: "; ++ break; ++ case GRUB_VERIFY_COMMAND: ++ prefix = "grub_cmd: "; ++ break; ++ } ++ ++ context = grub_zalloc(grub_strlen (str) + grub_strlen (prefix) + 1 + 4); //4 for type ++ if (!context) ++ return grub_errno; ++ ++ grub_snprintf(context, 4, "%d|", (type & GRUB_FILE_TYPE_MASK)); ++ description = context + grub_strlen(context); ++ grub_memcpy(description, prefix, grub_strlen (prefix)); ++ grub_memcpy(description + grub_strlen (prefix), str, grub_strlen (str) + 1); ++ ++ status = grub_tpcm_measure_memory(context, (grub_addr_t)str, grub_strlen(str)); ++ ++ grub_free(context); ++ ++ return status; ++} ++ ++struct grub_file_verifier grub_tpcm_verifier = { ++ .name = "tpcm_hygon", ++ .init = grub_tpcm_verify_init, ++ .write = grub_tpcm_verify_write, ++ .verify_string = grub_tpcm_verify_string, ++}; ++ ++GRUB_MOD_INIT (tpcm_hygon) ++{ ++ grub_verifier_register(&grub_tpcm_verifier); ++} ++ ++GRUB_MOD_FINI (tpcm_hygon) ++{ ++ grub_verifier_unregister(&grub_tpcm_verifier); ++} ++ +diff --git a/include/grub/efi/tpcm_hygon.h b/include/grub/efi/tpcm_hygon.h +new file mode 100644 +index 0000000..523d19c +--- /dev/null ++++ b/include/grub/efi/tpcm_hygon.h +@@ -0,0 +1,42 @@ ++#ifndef GRUB_EFI_TPCM_HEADER ++#define GRUB_EFI_TPCM_HEADER 1 ++ ++#include ++#include ++#include ++ ++#define C2PGUID {0xf89ab5cd, 0x2829, 0x422f, {0xa5, 0xf3, 0x03, 0x28, 0xe0, 0x6c, 0xfc, 0xbb}} ++#define MEASURE_RESULT_MASK (0xff00) ++#define MEASURE_RESULT_SHIFT (16) ++#define MEASURE_ACTION_MASK (0x1) ++#define TPCM_MAX_BUF_SIZE 128 ++ ++/* ++ stage layout: ++ 2000~2999: +1 every time ++*/ ++ ++#define STAGE_START 2000 ++#define STAGE_END 2999 ++#define STAGE_INVALID 3000 ++ ++struct addr_range { ++ grub_uint64_t start; ++ grub_uint64_t length; ++}; ++struct c2p_protocol { ++ grub_efi_status_t (__grub_efi_api *verify_raw) (struct c2p_protocol *this, ++ grub_uint32_t measure_stage, ++ grub_uint64_t image_info, ++ grub_uint32_t image_info_size, ++ grub_uint32_t num_addr_range, ++ struct addr_range ranges[], ++ grub_uint32_t *measure_result, ++ grub_uint32_t *control_result); ++ grub_efi_boolean_t (__grub_efi_api *verify_is_enabled)(struct c2p_protocol *this); ++}; ++typedef struct c2p_protocol c2p_protocol_t; ++ ++grub_err_t grub_tpcm_measure_memory(void *context, grub_addr_t buf, grub_size_t size); ++ ++#endif +diff --git a/include/grub/err.h b/include/grub/err.h +index b68bbec..2f10ac0 100644 +--- a/include/grub/err.h ++++ b/include/grub/err.h +@@ -73,7 +73,8 @@ typedef enum + GRUB_ERR_NET_NO_DOMAIN, + GRUB_ERR_EOF, + GRUB_ERR_BAD_SIGNATURE, +- GRUB_ERR_BAD_FIRMWARE ++ GRUB_ERR_BAD_FIRMWARE, ++ GRUB_ERR_TPCM_VERIFY + } + grub_err_t; + +-- +2.27.0 + diff --git a/grub.macros b/grub.macros index 2b299db..eaae986 100644 --- a/grub.macros +++ b/grub.macros @@ -454,6 +454,9 @@ GRUB_MODULES=" all_video boot blscfg btrfs \\\ search_label serial sleep test tftp \\\ video xfs " \ GRUB_MODULES+=%{efi_modules} \ +%if "%{1}" == "x86_64-efi" \ +GRUB_MODULES+=" tpcm_hygon " \ +%endif \ %{expand:%%{mkimage %{1} %{2} %{3} %{4}}} \ %{nil} diff --git a/grub.patches b/grub.patches index 73c747e..cdaa74b 100644 --- a/grub.patches +++ b/grub.patches @@ -239,3 +239,4 @@ Patch238: grub2-ppc64le-fix-bug-about-petitboot-doesn-t-ignore-EFI-entries Patch239: 0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch Patch240: 0061-Add-BLS-support-to-grub-mkconfig.patch Patch241: 0064-Add-grub2-switch-to-blscfg.patch +Patch242: 0001-newfeature-tpcm-add-hygon-tpcm-support.patch diff --git a/grub2.spec b/grub2.spec index 2062b41..f324e08 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 23 +Release: 24 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -456,6 +456,12 @@ fi %{_datadir}/man/man* %changelog +* Fri Aug 2 2024 chench - 1:2.12-24 +- Type:requirement +- CVE:NA +- SUG:NA +- DESC:add support for hygon tpcm + * Wed Jul 24 2024 wangyueliang - 1:2.12-23 - Type:requirement - CVE:NA -- Gitee