From c7429be5d2b2281fdc5c76aecf47512b2f16ed53 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 12 Mar 2012 15:41:49 -0400 Subject: [PATCH] Handle some missed bits for newer autotools support (patch from khopp) - Handle PReP installation on PPC. --- grub-1.99-prep_install_v2.patch | 575 ++++++++++++++++++++++++++++++++ grub2.spec | 7 +- 2 files changed, 581 insertions(+), 1 deletion(-) create mode 100644 grub-1.99-prep_install_v2.patch diff --git a/grub-1.99-prep_install_v2.patch b/grub-1.99-prep_install_v2.patch new file mode 100644 index 0000000..4ca57cb --- /dev/null +++ b/grub-1.99-prep_install_v2.patch @@ -0,0 +1,575 @@ +From: Paulo Flabiano Smorigo +Date: Fri, 24 Feb 2012 17:26:02 -0400 +Subject: [PATCH] Pull in required v2 changes for PPC +--- + +diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c +index 2fbe809..9e80757 100644 +--- a/grub-core/kern/ieee1275/cmain.c ++++ b/grub-core/kern/ieee1275/cmain.c +@@ -60,6 +60,10 @@ grub_ieee1275_find_options (void) + int is_olpc = 0; + int is_qemu = 0; + ++#ifdef __sparc__ ++ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); ++#endif ++ + grub_ieee1275_finddevice ("/", &root); + grub_ieee1275_finddevice ("/options", &options); + grub_ieee1275_finddevice ("/openprom", &openprom); +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 682a8b5..13a160f 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -69,36 +69,45 @@ grub_translate_ieee1275_path (char *filepath) + } + + void +-grub_machine_set_prefix (void) ++grub_machine_get_bootlocation (char **device, char **path) + { + char bootpath[64]; /* XXX check length */ + char *filename; +- char *prefix; +- +- if (grub_prefix[0]) +- { +- grub_env_set ("prefix", grub_prefix); +- /* Prefix is hardcoded in the core image. */ +- return; +- } +- ++ char *type; ++ + if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, + sizeof (bootpath), 0)) + { + /* Should never happen. */ + grub_printf ("/chosen/bootpath property missing!\n"); +- grub_env_set ("prefix", ""); + return; + } + + /* Transform an OF device path to a GRUB path. */ + +- prefix = grub_ieee1275_encode_devname (bootpath); ++ type = grub_ieee1275_get_device_type (bootpath); ++ if (type && grub_strcmp (type, "network") == 0) ++ { ++ char *dev, *canon; ++ char *ptr; ++ dev = grub_ieee1275_get_aliasdevname (bootpath); ++ canon = grub_ieee1275_canonicalise_devname (dev); ++ ptr = canon + grub_strlen (canon) - 1; ++ while (ptr > canon && (*ptr == ',' || *ptr == ':')) ++ ptr--; ++ ptr++; ++ *ptr = 0; ++ ++ grub_free (dev); ++ grub_free (canon); ++ } ++ else ++ *device = grub_ieee1275_encode_devname (bootpath); ++ grub_free (type); + + filename = grub_ieee1275_get_filename (bootpath); + if (filename) + { +- char *newprefix; + char *lastslash = grub_strrchr (filename, '\\'); + + /* Truncate at last directory. */ +@@ -107,19 +116,9 @@ grub_machine_set_prefix (void) + *lastslash = '\0'; + grub_translate_ieee1275_path (filename); + +- newprefix = grub_xasprintf ("%s%s", prefix, filename); +- if (newprefix) +- { +- grub_free (prefix); +- prefix = newprefix; +- } ++ *path = filename; + } + } +- +- grub_env_set ("prefix", prefix); +- +- grub_free (filename); +- grub_free (prefix); + } + + /* Claim some available memory in the first /memory node. */ +@@ -192,22 +191,12 @@ static void grub_claim_heap (void) + grub_machine_mmap_iterate (heap_init); + } + +-static grub_uint64_t ieee1275_get_time_ms (void); +- +-void +-grub_machine_init (void) ++static void ++grub_parse_cmdline (void) + { +- char args[256]; + grub_ssize_t actual; ++ char args[256]; + +- grub_ieee1275_init (); +- +- grub_console_init_early (); +- grub_claim_heap (); +- grub_console_init_lately (); +- grub_ofdisk_init (); +- +- /* Process commandline. */ + if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args, + sizeof args, &actual) == 0 + && actual > 1) +@@ -240,6 +229,21 @@ grub_machine_init (void) + } + } + } ++} ++ ++static grub_uint64_t ieee1275_get_time_ms (void); ++ ++void ++grub_machine_init (void) ++{ ++ grub_ieee1275_init (); ++ ++ grub_console_init_early (); ++ grub_claim_heap (); ++ grub_console_init_lately (); ++ grub_ofdisk_init (); ++ ++ grub_parse_cmdline (); + + grub_install_get_time_ms (ieee1275_get_time_ms); + } +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c +index f5dc8ef..6aa57ea 100644 +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -27,6 +27,8 @@ enum grub_ieee1275_parse_type + { + GRUB_PARSE_FILENAME, + GRUB_PARSE_PARTITION, ++ GRUB_PARSE_DEVICE, ++ GRUB_PARSE_DEVICE_TYPE + }; + + /* Walk children of 'devpath', calling hook for each. */ +@@ -317,14 +319,9 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) + { + char type[64]; /* XXX check size. */ + char *device = grub_ieee1275_get_devname (path); +- char *args = grub_ieee1275_get_devargs (path); + char *ret = 0; + grub_ieee1275_phandle_t dev; + +- if (!args) +- /* Shouldn't happen. */ +- return 0; +- + /* We need to know what type of device it is in order to parse the full + file path properly. */ + if (grub_ieee1275_finddevice (device, &dev)) +@@ -339,49 +336,93 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) + goto fail; + } + +- if (!grub_strcmp ("block", type)) ++ switch (ptype) + { +- /* The syntax of the device arguments is defined in the CHRP and PReP +- IEEE1275 bindings: "[partition][,[filename]]". */ +- char *comma = grub_strchr (args, ','); ++ case GRUB_PARSE_DEVICE: ++ ret = grub_strdup (device); ++ break; ++ case GRUB_PARSE_DEVICE_TYPE: ++ ret = grub_strdup (type); ++ break; ++ case GRUB_PARSE_FILENAME: ++ { ++ char *comma; ++ char *args; ++ ++ if (grub_strcmp ("block", type) != 0) ++ goto unknown; ++ ++ args = grub_ieee1275_get_devargs (path); ++ if (!args) ++ /* Shouldn't happen. */ ++ return 0; + +- if (ptype == GRUB_PARSE_FILENAME) +- { +- if (comma) +- { +- char *filepath = comma + 1; +- +- /* Make sure filepath has leading backslash. */ +- if (filepath[0] != '\\') +- ret = grub_xasprintf ("\\%s", filepath); +- else +- ret = grub_strdup (filepath); ++ /* The syntax of the device arguments is defined in the CHRP and PReP ++ IEEE1275 bindings: "[partition][,[filename]]". */ ++ comma = grub_strchr (args, ','); ++ ++ if (comma) ++ { ++ char *filepath = comma + 1; ++ ++ /* Make sure filepath has leading backslash. */ ++ if (filepath[0] != '\\') ++ ret = grub_xasprintf ("\\%s", filepath); ++ else ++ ret = grub_strdup (filepath); + } ++ grub_free (args); + } +- else if (ptype == GRUB_PARSE_PARTITION) +- { +- if (!comma) +- ret = grub_strdup (args); +- else +- ret = grub_strndup (args, (grub_size_t)(comma - args)); +- } +- } +- else +- { +- /* XXX Handle net devices by configuring & registering a grub_net_dev +- here, then return its name? +- Example path: "net:,,,,,". */ ++ break; ++ case GRUB_PARSE_PARTITION: ++ { ++ char *comma; ++ char *args; ++ ++ if (grub_strcmp ("block", type) != 0) ++ goto unknown; ++ ++ args = grub_ieee1275_get_devargs (path); ++ if (!args) ++ /* Shouldn't happen. */ ++ return 0; ++ ++ comma = grub_strchr (args, ','); ++ if (!comma) ++ ret = grub_strdup (args); ++ else ++ ret = grub_strndup (args, (grub_size_t)(comma - args)); ++ /* Consistently provide numbered partitions to GRUB. ++ OpenBOOT traditionally uses alphabetical partition ++ specifiers. */ ++ if (ret[0] >= 'a' && ret[0] <= 'z') ++ ret[0] = '1' + (ret[0] - 'a'); ++ grub_free (args); ++ } ++ break; ++ default: ++ unknown: + grub_printf ("Unsupported type %s for device %s\n", type, device); + } + + fail: + grub_free (device); +- grub_free (args); + return ret; + } + + char * ++grub_ieee1275_get_device_type (const char *path) ++{ ++ return grub_ieee1275_parse_args (path, GRUB_PARSE_DEVICE_TYPE); ++} ++ ++char * ++grub_ieee1275_get_aliasdevname (const char *path) ++{ ++ return grub_ieee1275_parse_args (path, GRUB_PARSE_DEVICE); ++} ++ ++char * + grub_ieee1275_get_filename (const char *path) + { + return grub_ieee1275_parse_args (path, GRUB_PARSE_FILENAME); +@@ -403,10 +444,10 @@ grub_ieee1275_encode_devname (const char *path) + /* GRUB partition 1 is OF partition 0. */ + partno++; + +- encoding = grub_xasprintf ("(%s,%d)", device, partno); ++ encoding = grub_xasprintf ("%s,%d", device, partno); + } + else +- encoding = grub_xasprintf ("(%s)", device); ++ encoding = grub_xasprintf ("%s", device); + + grub_free (partition); + grub_free (device); +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index da71232..6820f4c 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -129,27 +129,74 @@ grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)), + return grub_strdup (val); + } + +-/* Set the root device according to the dl prefix. */ + static void +-grub_set_root_dev (void) ++grub_set_prefix_and_root (void) + { +- const char *prefix; ++ char *device = NULL; ++ char *path = NULL; ++ char *fwdevice = NULL; ++ char *fwpath = NULL; + + grub_register_variable_hook ("root", 0, grub_env_write_root); + +- prefix = grub_env_get ("prefix"); +- +- if (prefix) ++ { ++ char *pptr = NULL; ++ if (grub_prefix[0] == '(') ++ { ++ pptr = grub_strrchr (grub_prefix, ')'); ++ if (pptr) ++ { ++ device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1); ++ pptr++; ++ } ++ } ++ if (!pptr) ++ pptr = grub_prefix; ++ if (pptr[0]) ++ path = grub_strdup (pptr); ++ } ++ if ((!device || device[0] == ',' || !device[0]) || !path) ++ grub_machine_get_bootlocation (&fwdevice, &fwpath); ++ ++ if (!device && fwdevice) ++ device = fwdevice; ++ else if (fwdevice && (device[0] == ',' || !device[0])) + { +- char *dev; ++ /* We have a partition, but still need to fill in the drive. */ ++ char *comma, *new_device; ++ ++ comma = grub_strchr (fwdevice, ','); ++ if (comma) ++ { ++ char *drive = grub_strndup (fwdevice, comma - fwdevice); ++ new_device = grub_xasprintf ("%s%s", drive, device); ++ grub_free (drive); ++ } ++ else ++ new_device = grub_xasprintf ("%s%s", fwdevice, device); + +- dev = grub_file_get_device_name (prefix); +- if (dev) ++ grub_free (fwdevice); ++ grub_free (device); ++ device = new_device; ++ } ++ if (fwpath && !path) ++ path = fwpath; ++ if (device) ++ { ++ char *prefix; ++ ++ prefix = grub_xasprintf ("(%s)%s", device, path ? : ""); ++ if (prefix) + { +- grub_env_set ("root", dev); +- grub_free (dev); ++ grub_env_set ("prefix", prefix); ++ grub_free (prefix); + } ++ grub_env_set ("root", device); + } ++ ++ grub_free (device); ++ grub_free (path); ++ grub_print_error (); + } + + /* Load the normal mode module and execute the normal mode if possible. */ +@@ -159,7 +206,7 @@ grub_load_normal_mode (void) + /* Load the module. */ + grub_dl_load ("normal"); + +- /* Something went wrong. Print errors here to let user know why we're entering rescue mode. */ ++ /* Print errors if any. */ + grub_print_error (); + grub_errno = 0; + +@@ -187,8 +234,7 @@ grub_main (void) + + /* It is better to set the root device as soon as possible, + for convenience. */ +- grub_machine_set_prefix (); +- grub_set_root_dev (); ++ grub_set_prefix_and_root (); + grub_env_export ("root"); + grub_env_export ("prefix"); + +diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h +index 4c56cc2..fc977f5 100644 +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -195,7 +195,8 @@ char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path); + int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) + (struct grub_ieee1275_devalias * + alias)); +- ++char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); + char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path); ++char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path); + + #endif /* ! GRUB_IEEE1275_HEADER */ +diff --git a/include/grub/kernel.h b/include/grub/kernel.h +index 2ecc73d..09839de 100644 +--- a/include/grub/kernel.h ++++ b/include/grub/kernel.h +@@ -84,7 +84,8 @@ void grub_machine_init (void); + void EXPORT_FUNC(grub_machine_fini) (void); + + /* The machine-specific prefix initialization. */ +-void grub_machine_set_prefix (void); ++void ++grub_machine_get_bootlocation (char **device, char **path); + + /* Register all the exported symbols. This is automatically generated. */ + void grub_register_exported_symbols (void); +diff --git a/util/grub-install.in b/util/grub-install.in +index ff8bea8..cbf1e1e 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -271,7 +271,8 @@ if test "x$install_device" = x && ([ "${target_cpu}-${platform}" = "i386-pc" ] \ + fi + + if ! ([ "${target_cpu}-${platform}" = "i386-pc" ] \ +- || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ]); then ++ || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] \ ++ || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]); then + install_device= + fi + +@@ -522,11 +523,11 @@ if [ "x${devabstraction_module}" = "x" ] ; then + # Strip partition number + grub_partition="`echo "${grub_drive}" | sed -e 's/^[^,]*[,)]//; s/)$//'`" + grub_drive="`echo "${grub_drive}" | sed -e s/,[a-z0-9,]*//g`" +- if [ "$disk_module" = ata ] || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${target_cpu}-${platform}" != x"sparc64-ieee1275" ]) ; then ++ if [ "$disk_module" = ata ] || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]); then + # generic method (used on coreboot and ata mod) + uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`" + if [ "x${uuid}" = "x" ] ; then +- if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${target_cpu}-${platform}" != x"sparc64-ieee1275" ]; then ++ if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]; then + echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 + elif [ "$disk_module" = ata ]; then + echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 +@@ -540,11 +541,12 @@ if [ "x${devabstraction_module}" = "x" ] ; then + echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg" + config_opt="-c ${grubdir}/load.cfg " + modules="$modules search_fs_uuid" +- elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ]; then ++ else + # we need to hardcode the partition number in the core image's prefix. + if [ x"$grub_partition" = x ]; then + prefix_drive="()" + else ++ # Comma is already there + prefix_drive="(,$grub_partition)" + fi + fi +@@ -612,6 +614,30 @@ elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${pla + + # Point boot-device at the new grub install + boot_device="$ofpath:$partno,"`"$grub_mkrelpath" "${grubdir}/core.${imgext}" | sed 's,/,\\\\,g'` ++ ++ # If a install device is defined, copy the core.elf to PReP partition. ++ if [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ] \ ++ && [ -n "${install_device}" ]; then ++ if [ "$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t msdos_parttype)" != "41" ]; then ++ echo "The chosen partition is not a PReP partition." ++ exit 1 ++ fi ++ ++ # Check if device is with an ELF within or is blank ++ if [ "$(file -s "${install_device}" -b | awk '{ print $1 }')" = ELF ] || cmp -s -n $(blockdev --getsize64 ${install_device}) /dev/zero ${install_device} ; then ++ # Change boot device to the harddisk root ++ boot_device="$ofpath" ++ dd if="${grubdir}/core.${imgext}" of="${install_device}" status=noxfer || { ++ echo "Failed to copy Grub to the PReP partition." ++ exit 1 ++ } ++ else ++ echo "The PReP partition is not empty. If you are sure you want to use it, run dd to clear it:" ++ echo " dd if=/dev/zero of=${install_device}" ++ exit 1 ++ fi ++ fi ++ + "$nvsetenv" boot-device "$boot_device" || { + echo "$nvsetenv failed." + echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" +diff --git a/util/grub-probe.c b/util/grub-probe.c +index 0d5dac9..3512a79 100644 +--- a/util/grub-probe.c ++++ b/util/grub-probe.c +@@ -54,6 +54,7 @@ enum { + PRINT_DEVICE, + PRINT_PARTMAP, + PRINT_ABSTRACTION, ++ PRINT_MSDOS_PARTTYPE + }; + + int print = PRINT_FS; +@@ -221,6 +222,17 @@ probe (const char *path, char *device_name) + free (list); + list = tmp; + } ++ printf ("\n"); ++ goto end; ++ } ++ ++ if (print == PRINT_MSDOS_PARTTYPE) ++ { ++ if (dev->disk->partition ++ && strcmp(dev->disk->partition->partmap->name, "msdos") == 0) ++ printf ("%02x", dev->disk->partition->msdostype); ++ ++ printf ("\n"); + goto end; + } + +@@ -289,7 +301,7 @@ Probe device information for a given path (or device, if the -d option is given) + \n\ + -d, --device given argument is a system device, not a path\n\ + -m, --device-map=FILE use FILE as the device map [default=%s]\n\ +- -t, --target=(fs|fs_uuid|fs_label|drive|device|partmap|abstraction)\n\ ++ -t, --target=(fs|fs_uuid|fs_label|drive|device|partmap|abstraction|msdos_parttype)\n\ + print filesystem module, GRUB drive, system device, partition map module or abstraction module [default=fs]\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ +@@ -348,6 +360,8 @@ main (int argc, char *argv[]) + print = PRINT_PARTMAP; + else if (!strcmp (optarg, "abstraction")) + print = PRINT_ABSTRACTION; ++ else if (!strcmp (optarg, "msdos_parttype")) ++ print = PRINT_MSDOS_PARTTYPE; + else + usage (1); + break; diff --git a/grub2.spec b/grub2.spec index 1f6b01c..6b8bc3f 100644 --- a/grub2.spec +++ b/grub2.spec @@ -18,7 +18,7 @@ Name: grub2 Epoch: 1 Version: 1.99 -Release: 17%{?dist} +Release: 18%{?dist} Summary: Bootloader with support for Linux, Multiboot and more Group: System Environment/Base @@ -41,6 +41,7 @@ Patch7: grub-1.99-fix_grub-probe_call.patch Patch8: grub-1.99-handle-newer-autotools.patch Patch9: grub-1.99-gcc-4.7.0.patch Patch10: grub2-1.99-remove-serial.mod-test-from-00_header-748964.patch +Patch11: grub-1.99-prep_install_v2.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -380,6 +381,10 @@ fi %endif %changelog +* Mon Mar 12 2012 Peter Jones - 1.99-18 +- Handle some missed bits for newer autotools support (patch from khopp) +- Handle PReP installation on PPC. + * Wed Mar 07 2012 Peter Jones - 1.99-17 - Update for newer autotools and gcc 4.7.0 Related: rhbz#782144