diff -r -u -p -N grub-1.92/conf/powerpc-ieee1275.rmk grub-1.92ppcmtb/conf/powerpc-ieee1275.rmk --- grub-1.92/conf/powerpc-ieee1275.rmk 2005-12-25 10:00:34.000000000 -0600 +++ grub-1.92ppcmtb/conf/powerpc-ieee1275.rmk 2005-12-30 09:02:06.000000000 -0600 @@ -86,7 +86,9 @@ pkgdata_MODULES = halt.mod \ linux.mod \ normal.mod \ reboot.mod \ - suspend.mod + suspend.mod \ + _multiboot.mod \ + multiboot.mod # For _linux.mod. _linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c @@ -117,4 +119,12 @@ reboot_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_SOURCES = commands/ieee1275/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) +# For _mulitboot.mod +_multiboot_mod_SOURCES = loader/powerpc/ieee1275/multiboot.c +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) + +# For multiboot.mod +multiboot_mod_SOURCES = loader/powerpc/ieee1275/multiboot_normal.c +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) + include $(srcdir)/conf/common.mk diff -r -u -p -N grub-1.92/include/grub/powerpc/ieee1275/loader.h grub-1.92ppcmtb/include/grub/powerpc/ieee1275/loader.h --- grub-1.92/include/grub/powerpc/ieee1275/loader.h 2005-01-31 15:44:35.000000000 -0600 +++ grub-1.92ppcmtb/include/grub/powerpc/ieee1275/loader.h 2005-12-30 09:02:06.000000000 -0600 @@ -30,4 +30,8 @@ void grub_linux_fini (void); void grub_linux_normal_init (void); void grub_linux_normal_fini (void); +/* for multiboot powerpc */ +void grub_rescue_cmd_multiboot (int argc, char *argv[]); +void grub_rescue_cmd_module (int argc, char *argv[]); + #endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff -r -u -p -N grub-1.92/loader/powerpc/ieee1275/multiboot.c grub-1.92ppcmtb/loader/powerpc/ieee1275/multiboot.c --- grub-1.92/loader/powerpc/ieee1275/multiboot.c 1969-12-31 18:00:00.000000000 -0600 +++ grub-1.92ppcmtb/loader/powerpc/ieee1275/multiboot.c 2005-12-30 09:02:06.000000000 -0600 @@ -0,0 +1,397 @@ +/* multiboot.c - boot a multiboot OS image. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_dl_t my_mod; +static struct grub_multiboot_info *mbi; +static grub_addr_t entry; + +typedef void (*kernel_entry_t) (struct grub_multiboot_info *, unsigned long, + void *); + +static grub_err_t +grub_multiboot_boot (void) +{ + kernel_entry_t kernel; + + grub_dprintf ("loader", "Jumping to entry point: 0x%x\n", entry); + + kernel = (kernel_entry_t) entry; + kernel (mbi, GRUB_MB_MAGIC2, grub_ieee1275_entry_fn); + + /* Not reached. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_multiboot_unload (void) +{ + if (mbi) + { + unsigned int i; + for (i = 0; i < mbi->mods_count; i++) + { + grub_free ((void *) + ((struct grub_mod_list *) mbi->mods_addr)[i].mod_start); + grub_free ((void *) + ((struct grub_mod_list *) mbi->mods_addr)[i].cmdline); + } + grub_free ((void *) mbi->mods_addr); + grub_free ((void *) mbi->cmdline); + grub_free (mbi); + } + + + mbi = 0; + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +static void +grub_ieee1275_mbi_memory (struct grub_multiboot_info *info) +{ + grub_ieee1275_phandle_t memory; + struct grub_ieee1275_mem_region regions[4]; /* XXX Don't hardcode me. */ + int i; + + /* XXX Examine all memory nodes, not just the first. */ + if (-1 == grub_ieee1275_finddevice ("/memory", &memory)) + return; + + if (0 != grub_ieee1275_get_property (memory, "reg", ®ions, sizeof regions, 0)) + return; + + info->mem_lower = 0; + info->mem_upper = 0; + + for (i = 0; i < 4; i++) + info->mem_lower += regions[i].size; + + grub_dprintf ("loader", "multiboot.mem_lower = 0x%x\n", info->mem_lower); + + info->flags |= GRUB_MB_INFO_MEMORY; +} + +static void +grub_ieee1275_mbi_cmdline (struct grub_multiboot_info *info, int argc, char *argv[]) +{ + char *cmdline; + char *p; + int i; + int len; + + for (i = 0, len = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + + cmdline = p = grub_malloc (len); + if (!cmdline) + return; + + for (i = 0; i < argc; i++) + { + p = grub_stpcpy (p, argv[i]); + *(p++) = ' '; + } + + /* Remove the space after the last word. */ + *(--p) = '\0'; + + info->cmdline = (grub_uint32_t) cmdline; + grub_dprintf ("loader", "multiboot.cmdline = 0x%x\n", info->cmdline); + + info->flags |= GRUB_MB_INFO_CMDLINE; +} + +void +grub_rescue_cmd_multiboot (int argc, char *argv[]) +{ + grub_file_t file = 0; + char buffer[GRUB_MB_SEARCH]; + struct grub_multiboot_header *header; + grub_ssize_t len; + grub_size_t size; + int i; + Elf32_Ehdr *ehdr; + + grub_dl_ref (my_mod); + + grub_loader_unset(); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); + goto fail; + } + + file = grub_file_open (argv[0]); + if (!file) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); + goto fail; + } + + len = grub_file_read (file, buffer, GRUB_MB_SEARCH); + if (len < 32) + { + grub_error (GRUB_ERR_BAD_OS, "File too small"); + goto fail; + } + + /* Look for the multiboot header in the buffer. The header should + be at least 12 bytes and aligned on a 4-byte boundary. */ + for (header = (struct grub_multiboot_header *) buffer; + ((char *) header <= buffer + len - 12) || (header = 0); + header = (struct grub_multiboot_header *) ((char *)header + 4)) + { + if (header->magic == GRUB_MB_MAGIC + && !(header->magic + header->flags + header->checksum)) + break; + } + + if (header == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No multiboot header found"); + goto fail; + } + + if (header->flags & GRUB_MB_UNSUPPORTED) + { + grub_error (GRUB_ERR_UNKNOWN_OS, "Unsupported flag: 0x%x", header->flags); + goto fail; + } + + ehdr = (Elf32_Ehdr *) buffer; + + if (grub_dl_check_header (ehdr, sizeof(*ehdr))) + { + grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found"); + goto fail; + } + + if (ehdr->e_type != ET_EXEC) + { + grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type"); + goto fail; + } + + /* FIXME: Should we support program headers at strange locations? */ + if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > GRUB_MB_SEARCH) + { + grub_error (GRUB_ERR_UNKNOWN_OS, "Program header at a too high offset"); + goto fail; + } + + /* Determine the amount of memory that is required. */ + /* XXX discontiguous segments */ + size = 0; + for (i = 0; i < ehdr->e_phnum; i++) + { + Elf32_Phdr *phdr; + phdr = (Elf32_Phdr *) (buffer + ehdr->e_phoff + i * ehdr->e_phentsize); + + size += phdr->p_memsz; + } + if (-1 == grub_claimmap (ehdr->e_entry, size)) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%x bytes at 0x%x\n", + size, ehdr->e_entry); + goto fail; + } + + entry = ehdr->e_entry; + + /* Load every loadable segment in memory. */ + for (i = 0; i < ehdr->e_phnum; i++) + { + Elf32_Phdr *phdr; + phdr = (Elf32_Phdr *) (buffer + ehdr->e_phoff + i * ehdr->e_phentsize); + + if (phdr->p_type == PT_LOAD) + { + if (grub_file_seek (file, phdr->p_offset) == -1) + { + grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header"); + goto fail; + } + + grub_dprintf ("loader", "Loading segment %d at 0x%x, size 0x%x\n", i, + phdr->p_paddr, phdr->p_filesz); + + if (grub_file_read (file, (void *) phdr->p_paddr, phdr->p_filesz) + != (grub_ssize_t) phdr->p_filesz) + { + grub_error (GRUB_ERR_BAD_OS, "Couldn't read segment from file"); + goto fail; + } + + if (phdr->p_filesz < phdr->p_memsz) + grub_memset ((char *) phdr->p_paddr + phdr->p_filesz, 0, + phdr->p_memsz - phdr->p_filesz); + } + } + + mbi = grub_malloc (sizeof (struct grub_multiboot_info)); + if (!mbi) + goto fail; + + mbi->flags = 0; + + grub_ieee1275_mbi_memory (mbi); + grub_ieee1275_mbi_cmdline (mbi, argc, argv); + + mbi->flags |= GRUB_MB_INFO_BOOT_LOADER_NAME; + mbi->boot_loader_name = (grub_uint32_t) grub_strdup (PACKAGE_STRING); + + grub_loader_set (grub_multiboot_boot, grub_multiboot_unload); + + fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_free (mbi); + grub_dl_unref (my_mod); + } +} + +void +grub_rescue_cmd_module (int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size, len = 0; + char *module = 0, *cmdline = 0, *p; + int i; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + goto fail; + } + + if (!mbi) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the multiboot kernel first"); + goto fail; + } + + file = grub_file_open (argv[0]); + if (!file) + goto fail; + + size = grub_file_size (file); + module = grub_memalign (GRUB_MB_MOD_ALIGN, size); + if (!module) + goto fail; + + grub_dprintf ("loader", "Loading module %s at %p, size 0x%x\n", argv[0], + module, size); + + if (grub_file_read (file, module, size) != size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + for (i = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + + cmdline = p = grub_malloc (len); + if (!cmdline) + goto fail; + + for (i = 0; i < argc; i++) + { + p = grub_stpcpy (p, argv[i]); + *(p++) = ' '; + } + + /* Remove the space after the last word. */ + *(--p) = '\0'; + + if (mbi->flags & GRUB_MB_INFO_MODS) + { + struct grub_mod_list *modlist = (struct grub_mod_list *) mbi->mods_addr; + + modlist = grub_realloc (modlist, (mbi->mods_count + 1) * sizeof (struct grub_mod_list)); + + if (!modlist) + goto fail; + mbi->mods_addr = (grub_uint32_t) modlist; + modlist += mbi->mods_count; + modlist->mod_start = (grub_uint32_t) module; + modlist->mod_end = (grub_uint32_t) module + size; + modlist->cmdline = (grub_uint32_t) cmdline; + modlist->pad = 0; + mbi->mods_count++; + } + else + { + struct grub_mod_list *modlist = grub_malloc (sizeof (struct grub_mod_list)); + if (!modlist) + goto fail; + modlist->mod_start = (grub_uint32_t) module; + modlist->mod_end = (grub_uint32_t) module + size; + modlist->cmdline = (grub_uint32_t) cmdline; + modlist->pad = 0; + mbi->mods_count = 1; + mbi->mods_addr = (grub_uint32_t) modlist; + mbi->flags |= GRUB_MB_INFO_MODS; + } + + fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_free (module); + grub_free (cmdline); + } +} + + +GRUB_MOD_INIT(multiboot) +{ + grub_rescue_register_command ("multiboot", grub_rescue_cmd_multiboot, + "load a multiboot kernel"); + grub_rescue_register_command ("module", grub_rescue_cmd_module, + "load a multiboot module"); + my_mod = mod; +} + +GRUB_MOD_FINI(multiboot) +{ + grub_rescue_unregister_command ("multiboot"); + grub_rescue_unregister_command ("module"); +} + diff -r -u -p -N grub-1.92/loader/powerpc/ieee1275/multiboot_normal.c grub-1.92ppcmtb/loader/powerpc/ieee1275/multiboot_normal.c --- grub-1.92/loader/powerpc/ieee1275/multiboot_normal.c 1969-12-31 18:00:00.000000000 -0600 +++ grub-1.92ppcmtb/loader/powerpc/ieee1275/multiboot_normal.c 2005-12-30 09:02:06.000000000 -0600 @@ -0,0 +1,65 @@ +// loader/powerpc/ieee1275/multiboot_normal.c 2005-06-23 21:15:03.000000000 +/* multiboot_normal.c - boot another boot loader */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +static grub_err_t +grub_normal_cmd_multiboot (struct grub_arg_list *state __attribute__ +((unused)), + int argc, char **args) +{ + grub_rescue_cmd_multiboot (argc, args); + return grub_errno; +} + + +static grub_err_t +grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_module (argc, args); + return grub_errno; +} + +GRUB_MOD_INIT(multiboot_normal) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("multiboot", grub_normal_cmd_multiboot, + GRUB_COMMAND_FLAG_BOTH | + GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "multiboot FILE [ARGS...]", + "Load a multiboot kernel", 0); + + grub_register_command ("module", grub_normal_cmd_module, + GRUB_COMMAND_FLAG_BOTH | + GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "module FILE [ARGS...]", + "Load a multiboot module", 0); +} + +GRUB_MOD_FINI(multiboot_normal) +{ + grub_unregister_command ("multiboot"); + grub_unregister_command ("module"); +} diff -r -u -p -N grub-1.92/util/powerpc/ieee1275/grub-install.in grub-1.92ppcmtb/util/powerpc/ieee1275/grub-install.in --- grub-1.92/util/powerpc/ieee1275/grub-install.in 1969-12-31 18:00:00.000000000 -0600 +++ grub-1.92ppcmtb/util/powerpc/ieee1275/grub-install.in 2005-12-30 09:21:43.000000000 -0600 @@ -0,0 +1,189 @@ +#! /bin/sh + +# Install GRUB on your drive. +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc. +# +# This file 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 2 of the License, or +# (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Suite 330, Boston, MA 02110, USA. + +# This script uses `ofpathname', which is downloadable from +# http://ppc64-utils.ozlabs.org . + +# Initialize some variables. address@hidden@ address@hidden@ address@hidden@ address@hidden@ address@hidden@ address@hidden@ address@hidden@ address@hidden@ address@hidden@ address@hidden@ +pkgdatadir=${datadir}/${PACKAGE_TARNAME}/${host_cpu}-${host_vendor} + +grub_mkimage=${sbindir}/grub-mkimage +rootdir= +grub_prefix=/boot/grub +modules= + +install_device= +debug=no +update_nvram=yes + +ofpathname=/usr/sbin/ofpathname +nvsetenv=/sbin/nvsetenv + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --modules=*) + modules=`echo "$option" | sed 's/--modules=//'` ;; + --root-directory=*) + rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + --no-nvram) + update_nvram=no ;; + # This is an undocumented feature... + --debug) + debug=yes ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if test "x$install_device" != x; then + echo "More than one install_devices?" 1>&2 + usage + exit 1 + fi + install_device="${option}" ;; + esac +done + +# If the debugging feature is enabled, print commands. +if test $debug = yes; then + set -x +fi + +# Initialize these directories here, since ROOTDIR was initialized. +bootdir=${rootdir}/boot +grubdir=${bootdir}/grub + +set $grub_mkimage dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +# Find the partition at the right mount point. +install_device=`awk '$2 == '"\"$grubdir\""' { print $1 }' < /proc/mounts` +if test "x$install_device" = x; then + echo "$grubdir must be a mount point." + exit 1 +fi +# XXX warn on firmware-unreadable filesystems? + +# Create the GRUB directory if it is not present. +test -d "$bootdir" || mkdir "$bootdir" || exit 1 +test -d "$grubdir" || mkdir "$grubdir" || exit 1 + +# Copy the GRUB images to the GRUB directory. +for file in ${grubdir}/*.mod ${grubdir}/*.lst ; do + if test -f $file; then + rm -f $file || exit 1 + fi +done +for file in ${pkgdatadir}/*.mod ${pkgdatadir}/*.lst ; do + cp -f $file ${grubdir} || exit 1 +done + +# Create the core image with all modules, unless user specified a subset. +# XXX probe for partition map and filesystem? +if test "x$modules" = x; then + modules="$pkgdatadir"/*.mod +fi + +# Now perform the installation. +"$grub_mkimage" --output=${grubdir}/grub $modules || exit 1 + +if test $update_nvram = yes; then + set $ofpathname dummy + if test -f "$1"; then + : + else + echo "$1: Not found." 1>&2 + exit 1 + fi + + set $nvsetenv dummy + if test -f "$1"; then + : + else + echo "$1: Not found." 1>&2 + exit 1 + fi + + # Get the Open Firmware device tree path translation. + dev=`echo $install_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'` + partno=`echo $install_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'` + ofpath=`$ofpathname $dev` || { + echo "Couldn't find Open Firmware device tree path for $dev." + echo "You will have to set boot-device manually." + exit 1 + } + + # Point boot-device at the new grub install + "$nvsetenv" boot-device "$ofpath:$partno,"'\grub' || { + echo "$nvsetenv failed." + echo "You will have to set boot-device manually." + exit 1 + } +fi + +# Bye. +exit 0