From ce44826e79a92aaf21e19580d0580d29121d2260 Mon Sep 17 00:00:00 2001 From: Carles Pina i Estany Date: Tue, 13 Apr 2010 13:57:56 +0100 Subject: [PATCH 01/38] Enclose all translated strings in grub.cfg in single quotes, and escape them appropriately (Ubuntu bug #552921). * util/grub-mkconfig_lib.in (gettext_quoted): New function. * util/grub.d/10_hurd.in: Use it. * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Likewise. * util/grub.d/10_linux.in (linux_entry): Likewise. Also-By: Colin Watson --- ChangeLog | 11 +++++++++++ util/grub-mkconfig_lib.in | 4 ++++ util/grub.d/10_hurd.in | 8 ++++---- util/grub.d/10_kfreebsd.in | 6 +++--- util/grub.d/10_linux.in | 10 +++++----- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index d766bcd50..4be24c1b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-04-13 Carles Pina i Estany +2010-04-13 Colin Watson + + Enclose all translated strings in grub.cfg in single quotes, and + escape them appropriately (Ubuntu bug #552921). + + * util/grub-mkconfig_lib.in (gettext_quoted): New function. + * util/grub.d/10_hurd.in: Use it. + * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Likewise. + * util/grub.d/10_linux.in (linux_entry): Likewise. + 2010-04-11 Vladimir Serbinenko Fix cygwin compilation. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index bcd6baffb..a4151348c 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -188,3 +188,7 @@ version_find_latest () done echo "$a" } + +gettext_quoted () { + gettext "$@" | sed "s/'/'\\\\''/g" +} diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 5dbb11f22..8e16e7d9f 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -76,13 +76,13 @@ menuentry "${OS}" ${CLASS} { EOF prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" cat << EOF - echo $(gettext "Loading GNU Mach ...") + echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} EOF save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" cat << EOF - echo $(gettext "Loading the Hurd ...") + echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\ --multiboot-command-line='\${kernel-command-line}' \\ --host-priv-port='\${host-port}' \\ @@ -98,13 +98,13 @@ menuentry "${OS} (recovery mode)" { EOF prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" cat << EOF - echo $(gettext "Loading GNU Mach ...") + echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s EOF save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" cat << EOF - echo $(gettext "Loading the Hurd ...") + echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} \\ --multiboot-command-line='\${kernel-command-line}' \\ --host-priv-port='\${host-port}' \\ diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 43651c82b..5ab546282 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -44,15 +44,15 @@ kfreebsd_entry () version="$2" recovery="$3" # not used yet args="$4" # not used yet - title="$(gettext "%s, with kFreeBSD %s")" - printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}" + title="$(gettext_quoted "%s, with kFreeBSD %s")" + printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" save_default_entry | sed -e "s/^/\t/" if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi printf '%s\n' "${prepare_boot_cache}" cat << EOF - echo $(printf "$(gettext "Loading kernel of FreeBSD %s ...")" ${version}) + echo '$(printf "$(gettext_quoted "Loading kernel of FreeBSD %s ...")" ${version})' kfreebsd ${rel_dirname}/${basename} EOF diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 8dc0df5d9..e691cae86 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -56,11 +56,11 @@ linux_entry () recovery="$3" args="$4" if ${recovery} ; then - title="$(gettext "%s, with Linux %s (recovery mode)")" + title="$(gettext_quoted "%s, with Linux %s (recovery mode)")" else - title="$(gettext "%s, with Linux %s")" + title="$(gettext_quoted "%s, with Linux %s")" fi - printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}" + printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" save_default_entry | sed -e "s/^/\t/" # Use ELILO's generic "efifb" when it's known to be available. @@ -83,12 +83,12 @@ EOF fi printf '%s\n' "${prepare_boot_cache}" cat << EOF - echo $(printf "$(gettext "Loading Linux %s ...")" ${version}) + echo '$(printf "$(gettext_quoted "Loading Linux %s ...")" ${version})' linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} EOF if test -n "${initrd}" ; then cat << EOF - echo $(gettext "Loading initial ramdisk ...") + echo '$(gettext_quoted "Loading initial ramdisk ...")' initrd ${rel_dirname}/${initrd} EOF fi From 4e6da157dd218f4d4c262e875d0b7fd55b8048ae Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 13 Apr 2010 20:58:12 +0530 Subject: [PATCH 02/38] fix and testcase for \$ in grub script dquote strings --- conf/tests.rmk | 5 ++++- script/yylex.l | 11 ++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/conf/tests.rmk b/conf/tests.rmk index 11e5f2a1a..d48bc3dd9 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -65,6 +65,9 @@ grub_script_blanklines_SOURCES = tests/grub_script_blanklines.in check_SCRIPTS += grub_script_final_semicolon grub_script_final_semicolon_SOURCES = tests/grub_script_final_semicolon.in +check_SCRIPTS += grub_script_dollar +grub_script_dollar_SOURCES = tests/grub_script_dollar.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -79,7 +82,7 @@ SCRIPTED_TESTS += grub_script_while1 SCRIPTED_TESTS += grub_script_if SCRIPTED_TESTS += grub_script_blanklines SCRIPTED_TESTS += grub_script_final_semicolon - +SCRIPTED_TESTS += grub_script_dollar # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/script/yylex.l b/script/yylex.l index 0cf33c951..29aa5c2e3 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -211,7 +211,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); } \\ | - [^\"\'$\\]+ { COPY (yytext, yyleng); } + [^\"\'\$\\]+ { COPY (yytext, yyleng); } <> { yy_pop_state (yyscanner); yypop_buffer_state (yyscanner); @@ -254,6 +254,11 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ } { + \\\$ { COPY ("$", 1); } + \\\\ { COPY ("\\", 1); } + \\\" { COPY ("\"", 1); } + \\\n { /* ignore */ } + [^\"\$\\\n]+ { COPY (yytext, yyleng); } \" { yy_pop_state (yyscanner); ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); @@ -262,10 +267,6 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ yy_push_state (VAR, yyscanner); ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); } - \\\\ { COPY ("\\", 1); } - \\\" { COPY ("\"", 1); } - \\\n { /* ignore */ } - [^\"$\\\n]+ { COPY (yytext, yyleng); } (.|\n) { COPY (yytext, yyleng); } } From ae45b7bad4a382479344d7d06d97a9132f75ab9c Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 13 Apr 2010 21:01:56 +0530 Subject: [PATCH 03/38] add missing testcase --- tests/grub_script_dollar.in | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tests/grub_script_dollar.in diff --git a/tests/grub_script_dollar.in b/tests/grub_script_dollar.in new file mode 100644 index 000000000..3819b8bc9 --- /dev/null +++ b/tests/grub_script_dollar.in @@ -0,0 +1,5 @@ +#! /bin/sh -e + +@builddir@/grub-script-check << EOF +echo "\\\$" +EOF From 851395d8659fc58532797e6b45646e58845d50cf Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 14 Apr 2010 13:38:05 +0530 Subject: [PATCH 04/38] fix uninitialized warning --- loader/i386/bsdXX.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/loader/i386/bsdXX.c b/loader/i386/bsdXX.c index b4d574821..cd5ba85dc 100644 --- a/loader/i386/bsdXX.c +++ b/loader/i386/bsdXX.c @@ -80,7 +80,7 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc, { Elf_Ehdr e; Elf_Shdr *s; - char *shdr; + char *shdr = 0; grub_addr_t curload, module; grub_err_t err; @@ -148,7 +148,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[], { Elf_Ehdr e; Elf_Shdr *s; - char *shdr; + char *shdr = 0; grub_addr_t curload, module; grub_err_t err; @@ -223,7 +223,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end) grub_err_t err; Elf_Ehdr e; Elf_Shdr *s; - char *shdr; + char *shdr = 0; unsigned symoff, stroff, symsize, strsize; grub_addr_t curload; grub_freebsd_addr_t symstart, symend, symentsize, dynamic; From 0b45630927f0bb4f48589adbc1011b12b103be19 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 14 Apr 2010 13:59:58 +0100 Subject: [PATCH 05/38] Restore TEXTDOMAINDIR correction from r1889, lost apparently by mistake in r2156. Noticed by Anthony Fok. * util/grub.d/10_kfreebsd.in (TEXTDOMAINDIR): Set to lowercased @localedir@. * util/grub.d/10_linux.in (TEXTDOMAINDIR): Likewise. --- ChangeLog | 9 +++++++++ util/grub.d/10_kfreebsd.in | 2 +- util/grub.d/10_linux.in | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e0f3485d..1ac1ae6ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-04-14 Colin Watson + + Restore TEXTDOMAINDIR correction from r1889, lost apparently by + mistake in r2156. Noticed by Anthony Fok. + + * util/grub.d/10_kfreebsd.in (TEXTDOMAINDIR): Set to lowercased + @localedir@. + * util/grub.d/10_linux.in (TEXTDOMAINDIR): Likewise. + 2010-04-14 BVK Chaitanya Fix a spurious, uninitialized variable warning. diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 5ab546282..f63421617 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -23,7 +23,7 @@ libdir=@libdir@ . ${libdir}/grub/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ -export TEXTDOMAINDIR=@LOCALEDIR@ +export TEXTDOMAINDIR=@localedir@ CLASS="--class os" diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index e691cae86..802d59f51 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -23,7 +23,7 @@ libdir=@libdir@ . ${libdir}/grub/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ -export TEXTDOMAINDIR=@LOCALEDIR@ +export TEXTDOMAINDIR=@localedir@ CLASS="--class gnu-linux --class gnu --class os" From ebfe7eb4dd2467091e7018d6879d1ccf32cdeb6c Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sat, 17 Apr 2010 17:17:36 +0200 Subject: [PATCH 06/38] * Makefile.in: Add missing localedir setting. --- ChangeLog | 4 ++++ Makefile.in | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1ac1ae6ce..a89f7e6cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-17 Christian Franke + + * Makefile.in: Add missing localedir setting. + 2010-04-14 Colin Watson Restore TEXTDOMAINDIR correction from r1889, lost apparently by diff --git a/Makefile.in b/Makefile.in index e253af6c9..29f997213 100644 --- a/Makefile.in +++ b/Makefile.in @@ -35,6 +35,7 @@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ +localedir = @localedir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ From 0973daeb380d6d1ef26a10feb28be4ef5140c861 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 17 Apr 2010 18:58:56 +0200 Subject: [PATCH 07/38] * disk/lvm.c (grub_lvm_memberlist): Issue an error if pv->disk = 0. --- ChangeLog | 4 ++++ disk/lvm.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index a89f7e6cc..87c72cd43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-17 Vladimir Serbinenko + + * disk/lvm.c (grub_lvm_memberlist): Issue an error if pv->disk = 0. + 2010-04-17 Christian Franke * Makefile.in: Add missing localedir setting. diff --git a/disk/lvm.c b/disk/lvm.c index 2c54ca3b3..c2ae82df2 100644 --- a/disk/lvm.c +++ b/disk/lvm.c @@ -24,6 +24,10 @@ #include #include +#ifdef GRUB_UTIL +#include +#endif + static struct grub_lvm_vg *vg_list; static int lv_count; @@ -68,6 +72,9 @@ grub_lvm_memberlist (grub_disk_t disk) if (lv->vg->pvs) for (pv = lv->vg->pvs; pv; pv = pv->next) { + if (!pv->disk) + grub_util_error ("Couldn't find PV %s. Check your device.map", + pv->name); tmp = grub_malloc (sizeof (*tmp)); tmp->disk = pv->disk; tmp->next = list; From 0b830b8f5edf78db51a04ff2d9bde4006057829a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 12:59:04 +0200 Subject: [PATCH 08/38] * util/hostdisk.c (make_device_name): Change to new partition naming. --- ChangeLog | 4 ++++ util/hostdisk.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 87c72cd43..9d2277f28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-18 Vladimir Serbinenko + + * util/hostdisk.c (make_device_name): Change to new partition naming. + 2010-04-17 Vladimir Serbinenko * disk/lvm.c (grub_lvm_memberlist): Issue an error if pv->disk = 0. diff --git a/util/hostdisk.c b/util/hostdisk.c index 79652625d..a8e418046 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -861,7 +861,7 @@ make_device_name (int drive, int dos_part, int bsd_part) dos_part_str = xasprintf (",%d", dos_part + 1); if (bsd_part >= 0) - bsd_part_str = xasprintf (",%c", bsd_part + 'a'); + bsd_part_str = xasprintf (",%d", bsd_part + 1); ret = xasprintf ("%s%s%s", map[drive].drive, dos_part_str ? : "", From a9e6ff28d277b5e925b73b2ca6bb4a190a9dac1d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 13:00:06 +0200 Subject: [PATCH 09/38] * po/POTFILES: Renamed multiboot_loader.c to multiboot.c --- ChangeLog | 4 ++++ po/POTFILES | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9d2277f28..6f39713a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-18 Vladimir Serbinenko + + * po/POTFILES: Renamed multiboot_loader.c to multiboot.c + 2010-04-18 Vladimir Serbinenko * util/hostdisk.c (make_device_name): Change to new partition naming. diff --git a/po/POTFILES b/po/POTFILES index 5fabb0634..0dfc3c041 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -62,7 +62,7 @@ loader/i386/linux.c loader/i386/pc/chainloader.c loader/i386/pc/linux.c loader/i386/xnu.c -loader/multiboot_loader.c +loader/multiboot.c loader/powerpc/ieee1275/linux.c loader/sparc64/ieee1275/linux.c loader/xnu.c From 6e86896ed8bd6ce55592092c30e0c087d902cae8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 14:02:13 +0200 Subject: [PATCH 10/38] Use ofpathname in grub-setup on sparc --- conf/powerpc-ieee1275.rmk | 7 ++++ conf/sparc64-ieee1275.rmk | 1 + include/grub/util/hostdisk.h | 3 ++ include/grub/util/ofpath.h | 2 +- util/hostdisk.c | 6 ++++ util/{sparc64 => }/ieee1275/grub-ofpathname.c | 0 util/ieee1275/ofpath.c | 2 +- util/sparc64/ieee1275/grub-setup.c | 34 ++++--------------- 8 files changed, 26 insertions(+), 29 deletions(-) rename util/{sparc64 => }/ieee1275/grub-ofpathname.c (100%) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index d5968ac8e..d7d477327 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -25,6 +25,13 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic +# Utilities. +sbin_UTILITIES = grub-ofpathname + +# For grub-ofpathname. +grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ + util/ieee1275/ofpath.c util/misc.c gnulib/progname.c + # Scripts. sbin_SCRIPTS = grub-install bin_SCRIPTS = grub-mkrescue diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 72f947f6a..a92e66a80 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -50,6 +50,7 @@ grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ + util/ieee1275/ofpath.c \ util/misc.c util/getroot.c kern/device.c kern/disk.c \ kern/err.c kern/misc.c kern/parser.c kern/partition.c \ kern/file.c kern/fs.c kern/env.c kern/list.c \ diff --git a/include/grub/util/hostdisk.h b/include/grub/util/hostdisk.h index 21efb0d17..246046ee0 100644 --- a/include/grub/util/hostdisk.h +++ b/include/grub/util/hostdisk.h @@ -20,8 +20,11 @@ #ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER #define GRUB_BIOSDISK_MACHINE_UTIL_HEADER 1 +#include + void grub_util_biosdisk_init (const char *dev_map); void grub_util_biosdisk_fini (void); char *grub_util_biosdisk_get_grub_dev (const char *os_dev); +const char *grub_util_biosdisk_get_osdev (grub_disk_t disk); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h index 78f24d784..b43c523cb 100644 --- a/include/grub/util/ofpath.h +++ b/include/grub/util/ofpath.h @@ -1,6 +1,6 @@ #ifndef GRUB_OFPATH_MACHINE_UTIL_HEADER #define GRUB_OFPATH_MACHINE_UTIL_HEADER 1 -char *grub_util_devname_to_ofpath (char *devname); +char *grub_util_devname_to_ofpath (const char *devname); #endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */ diff --git a/util/hostdisk.c b/util/hostdisk.c index a8e418046..8be487461 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -1352,3 +1352,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return make_device_name (drive, -1, -1); #endif } + +const char * +grub_util_biosdisk_get_osdev (grub_disk_t disk) +{ + return map[disk->id].device; +} diff --git a/util/sparc64/ieee1275/grub-ofpathname.c b/util/ieee1275/grub-ofpathname.c similarity index 100% rename from util/sparc64/ieee1275/grub-ofpathname.c rename to util/ieee1275/grub-ofpathname.c diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index 79a0e8be5..fa0d48cf9 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -368,7 +368,7 @@ strip_trailing_digits (const char *p) } char * -grub_util_devname_to_ofpath (char *devname) +grub_util_devname_to_ofpath (const char *devname) { char *name_buf, *device, *devnode, *devicenode, *ofpath; diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index c39ea853f..cfd58a08f 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -103,28 +104,6 @@ grub_refresh (void) fflush (stdout); } -static char *compute_dest_ofpath (const char *dest) -{ - int len = strlen (dest); - char *res, *p, c; - - res = xmalloc (len); - p = res; - while ((c = *dest++) != '\0') - { - if (c == '\\' && *dest == ',') - { - *p++ = ','; - dest++; - } - else - *p++ = c; - } - *p++ = '\0'; - - return res; -} - static void setup (const char *prefix, const char *dir, const char *boot_file, const char *core_file, @@ -195,8 +174,6 @@ setup (const char *prefix, const char *dir, last_length = length; } - dest_ofpath = compute_dest_ofpath (dest); - /* Read the boot image by the OS service. */ boot_path = grub_util_get_path (dir, boot_file); boot_size = grub_util_get_image_size (boot_path); @@ -229,8 +206,7 @@ setup (const char *prefix, const char *dir, + GRUB_DISK_SECTOR_SIZE - sizeof (*block)); - grub_util_info ("root is `%s', dest is `%s', and dest_ofpath is `%s'", - root, dest, dest_ofpath); + grub_util_info ("root is `%s', dest is `%s'", root, dest); /* Open the root device and the destination device. */ grub_util_info ("Opening root"); @@ -243,6 +219,11 @@ setup (const char *prefix, const char *dir, if (! dest_dev) grub_util_error ("%s", grub_errmsg); + dest_ofpath + = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (dest_dev->disk)); + + grub_util_info ("dest_ofpath is `%s'", dest_ofpath); + grub_util_info ("setting the root device to `%s'", root); if (grub_env_set ("root", root) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); @@ -449,7 +430,6 @@ init_info (struct grub_setup_info *gp) gp->dev_map = NULL; gp->root_dev = NULL; gp->prefix = NULL; - gp->dest_dev = NULL; } static int From d0faf8a1b3c0a8e21b4ef17e10118a8b336a216c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 16:31:27 +0200 Subject: [PATCH 11/38] Correct path to grub-ofpathname --- conf/sparc64-ieee1275.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index a92e66a80..c82bd81f3 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -70,7 +70,7 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ grub_setup_init.c # For grub-ofpathname. -grub_ofpathname_SOURCES = util/sparc64/ieee1275/grub-ofpathname.c \ +grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ util/ieee1275/ofpath.c util/misc.c gnulib/progname.c # Scripts. From ee9056d097bafe2324d4adaf912364aa9e7fd296 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 16:35:08 +0200 Subject: [PATCH 12/38] Support cross-disk installs. On non-cross-disk retrieve bootpath from chosen/bootpath --- boot/sparc64/ieee1275/boot.S | 16 ++++++++++++++++ include/grub/sparc64/ieee1275/boot.h | 4 ++-- util/sparc64/ieee1275/grub-setup.c | 27 +++++++++++++++++++-------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/boot/sparc64/ieee1275/boot.S b/boot/sparc64/ieee1275/boot.S index 167406017..4008b1b54 100644 --- a/boot/sparc64/ieee1275/boot.S +++ b/boot/sparc64/ieee1275/boot.S @@ -152,6 +152,22 @@ boot_continue: call console_write mov GRUB_NAME_LEN, %o3 + GET_ABS(boot_path, %o3) + ldub [%o3], %o1 + brnz,pn %o1, bootpath_known + mov 4, %g1 + + /* getprop(chosen_node, "bootpath", &buffer, buffer_size) */ + GET_ABS(prom_getprop_name, %o0) + mov 1, %o5 + mov CHOSEN_NODE_REG, %o1 + GET_ABS(prom_bootpath_name, %o2) + mov (kernel_sector - boot_path), %o4 + call prom_call + stx %g1, [%l1 + 256] + +bootpath_known: + /* Open up the boot_path, and use that handle to read the * first block of the GRUB kernel image. * diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index e1c1aa675..7b2137664 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -43,9 +43,9 @@ #define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x0a -#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80 +#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END (0x80 - 40) -#define GRUB_BOOT_MACHINE_KERNEL_SECTOR 0x88 +#define GRUB_BOOT_MACHINE_KERNEL_SECTOR (0x80 - 40) #define GRUB_BOOT_MACHINE_CODE_END \ (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index cfd58a08f..97cc89301 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -114,7 +114,7 @@ setup (const char *prefix, const char *dir, size_t boot_size, core_size; grub_uint16_t core_sectors; grub_device_t root_dev, dest_dev; - char *boot_devpath, *dest_ofpath; + char *boot_devpath; grub_disk_addr_t *kernel_sector; struct boot_blocklist *first_block, *block; char *tmp_img; @@ -219,11 +219,6 @@ setup (const char *prefix, const char *dir, if (! dest_dev) grub_util_error ("%s", grub_errmsg); - dest_ofpath - = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (dest_dev->disk)); - - grub_util_info ("dest_ofpath is `%s'", dest_ofpath); - grub_util_info ("setting the root device to `%s'", root); if (grub_env_set ("root", root) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); @@ -332,6 +327,24 @@ setup (const char *prefix, const char *dir, != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE) grub_util_error ("failed to read the rest sectors of the core image"); + if (file->device->disk->id != dest_dev->disk->id) + { + const char *dest_ofpath; + dest_ofpath + = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (file->device->disk)); + grub_util_info ("dest_ofpath is `%s'", dest_ofpath); + strncpy (boot_devpath, dest_ofpath, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1); + boot_devpath[GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1] = 0; + } + else + { + grub_util_info ("non cross-disk install"); + memset (boot_devpath, 0, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH); + } + grub_file_close (file); free (core_path); @@ -339,8 +352,6 @@ setup (const char *prefix, const char *dir, *kernel_sector = grub_cpu_to_be64 (first_sector); - strcpy(boot_devpath, dest_ofpath); - grub_util_info ("boot device path %s, prefix is %s, dest is %s", boot_devpath, prefix, dest); From b076cdc730408d5d5ae0c6279b2560e3de1582fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 18:22:58 +0200 Subject: [PATCH 13/38] Shave off bytes to compensate boot.img size increase --- boot/sparc64/ieee1275/boot.S | 73 +++++++++++++--------------- include/grub/sparc64/ieee1275/boot.h | 4 +- util/sparc64/ieee1275/grub-setup.c | 10 ++-- 3 files changed, 42 insertions(+), 45 deletions(-) diff --git a/boot/sparc64/ieee1275/boot.S b/boot/sparc64/ieee1275/boot.S index 4008b1b54..f08258f47 100644 --- a/boot/sparc64/ieee1275/boot.S +++ b/boot/sparc64/ieee1275/boot.S @@ -45,8 +45,9 @@ boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR * load address plus the size of the prepended A.OUT header (32 bytes). */ boot_path: - . = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR -kernel_sector: .xword 2 + . = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE +boot_path_end: +kernel_byte: .xword (2 << 9) kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR prom_finddev_name: .asciz "finddevice" @@ -77,11 +78,23 @@ prom_error: /* %o0: OF call name * %o1: input arg 1 */ -prom_call_1_1: - mov 1, %g1 - ba prom_call - mov 1, %o5 +prom_call_1_1_o2: + clr %o2 + ba prom_call_x_1 + mov 1, %g1 +prom_call_getprop: + mov 4, %g1 + stx %g1, [%l1 + 256] + mov CHOSEN_NODE_REG, %o1 + ba prom_call_x_1 + GET_ABS(prom_getprop_name, %o0) + +prom_call_3_1_o1: + ba prom_call_3_1 + mov BOOTDEV_REG, %o1 + + /* %o2: message string * %o3: message length */ @@ -95,8 +108,9 @@ console_write: * %o2: input arg 2 * %o3: input arg 3 */ -prom_call_3_1: +prom_call_3_1: mov 3, %g1 +prom_call_x_1: mov 1, %o5 /* fallthru */ @@ -126,23 +140,17 @@ boot_continue: * chosen_node = prom_finddevice("/chosen") */ GET_ABS(prom_finddev_name, %o0) - GET_ABS(prom_chosen_path, %o1) - call prom_call_1_1 - clr %o2 + call prom_call_1_1_o2 + GET_ABS(prom_chosen_path, %o1) ldx [%l1 + 0x20], CHOSEN_NODE_REG brz CHOSEN_NODE_REG, prom_error /* getprop(chosen_node, "stdout", &buffer, buffer_size) */ - GET_ABS(prom_getprop_name, %o0) - mov 4, %g1 - mov 1, %o5 - mov CHOSEN_NODE_REG, %o1 - GET_ABS(prom_stdout_name, %o2) + GET_ABS(prom_stdout_name, %o2) add %l1, 256, %o3 - mov 1024, %o4 - call prom_call - stx %g1, [%l1 + 256] + call prom_call_getprop + mov 1024, %o4 lduw [%l1 + 256], STDOUT_NODE_REG brz,pn STDOUT_NODE_REG, prom_error @@ -155,16 +163,11 @@ boot_continue: GET_ABS(boot_path, %o3) ldub [%o3], %o1 brnz,pn %o1, bootpath_known - mov 4, %g1 /* getprop(chosen_node, "bootpath", &buffer, buffer_size) */ - GET_ABS(prom_getprop_name, %o0) - mov 1, %o5 - mov CHOSEN_NODE_REG, %o1 - GET_ABS(prom_bootpath_name, %o2) - mov (kernel_sector - boot_path), %o4 - call prom_call - stx %g1, [%l1 + 256] + GET_ABS(prom_bootpath_name, %o2) + call prom_call_getprop + mov (boot_path_end - boot_path), %o4 bootpath_known: @@ -174,9 +177,8 @@ bootpath_known: * bootdev_handle = open(boot_path) */ GET_ABS(prom_open_name, %o0) - GET_ABS(boot_path, %o1) - call prom_call_1_1 - clr %o2 + call prom_call_1_1_o2 + GET_ABS(boot_path, %o1) ldx [%l1 + 0x20], BOOTDEV_REG brz,pn BOOTDEV_REG, prom_open_error @@ -184,28 +186,23 @@ bootpath_known: /* Since we have 64-bit cells, the high cell of the seek offset * is zero and the low cell is the entire value. * - * seek(bootdev, 0, *kernel_sector << 9) + * seek(bootdev, 0, *kernel_byte) */ GET_ABS(prom_seek_name, %o0) - mov BOOTDEV_REG, %o1 clr %o2 - LDX_ABS(kernel_sector, 0x00, %o3) - call prom_call_3_1 - sllx %o3, 9, %o3 + call prom_call_3_1_o1 + LDX_ABS(kernel_byte, 0x00, %o3) /* read(bootdev, *kernel_address, 512) */ GET_ABS(prom_read_name, %o0) - mov BOOTDEV_REG, %o1 LDUW_ABS(kernel_address, 0x00, %o2) - call prom_call_3_1 + call prom_call_3_1_o1 mov 512, %o3 LDUW_ABS(kernel_address, 0x00, %o2) jmpl %o2, %o7 nop -1: ba,a 1b - . = _start + GRUB_BOOT_MACHINE_CODE_END /* the last 4 bytes in the sector 0 contain the signature */ diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 7b2137664..9671c6900 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -43,9 +43,9 @@ #define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x0a -#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END (0x80 - 40) +#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80 -#define GRUB_BOOT_MACHINE_KERNEL_SECTOR (0x80 - 40) +#define GRUB_BOOT_MACHINE_KERNEL_BYTE 0x80 #define GRUB_BOOT_MACHINE_CODE_END \ (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 97cc89301..34a006d7f 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -115,7 +115,7 @@ setup (const char *prefix, const char *dir, grub_uint16_t core_sectors; grub_device_t root_dev, dest_dev; char *boot_devpath; - grub_disk_addr_t *kernel_sector; + grub_disk_addr_t *kernel_byte; struct boot_blocklist *first_block, *block; char *tmp_img; int i; @@ -187,9 +187,9 @@ setup (const char *prefix, const char *dir, boot_devpath = (char *) (boot_img + GRUB_BOOT_AOUT_HEADER_SIZE + GRUB_BOOT_MACHINE_BOOT_DEVPATH); - kernel_sector = (grub_disk_addr_t *) (boot_img - + GRUB_BOOT_AOUT_HEADER_SIZE - + GRUB_BOOT_MACHINE_KERNEL_SECTOR); + kernel_byte = (grub_disk_addr_t *) (boot_img + + GRUB_BOOT_AOUT_HEADER_SIZE + + GRUB_BOOT_MACHINE_KERNEL_BYTE); core_path = grub_util_get_path (dir, core_file); core_size = grub_util_get_image_size (core_path); @@ -350,7 +350,7 @@ setup (const char *prefix, const char *dir, free (core_path); free (tmp_img); - *kernel_sector = grub_cpu_to_be64 (first_sector); + *kernel_byte = grub_cpu_to_be64 (first_sector << GRUB_DISK_SECTOR_BITS); grub_util_info ("boot device path %s, prefix is %s, dest is %s", boot_devpath, prefix, dest); From 38e55e905886e905f0a7d966e0a61cb50c86909f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sun, 18 Apr 2010 19:57:50 +0200 Subject: [PATCH 14/38] TARGET_IMG_LDFLAGS_AC now always expects a number appended to it. Fixed grub_prefix in grub-mkconfig for NetBSD and OpenBSD. --- ChangeLog | 9 +++++++++ acinclude.m4 | 2 +- configure.ac | 4 ++-- util/grub-mkconfig.in | 18 +++++++++++++++--- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f39713a2..796d5614d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-04-18 Grégoire Sutre + + * util/grub-mkconfig.in: Corrected two == equality tests. + Set grub_prefix as in grub-install for NetBSD and OpenBSD. + * configure.ac: All definitions and uses of TARGET_IMG_LDFLAGS_AC now + expect a number appended to it. + * acinclude.m4 (grub_PROG_OBJCOPY_ABSOLUTE): ${TARGET_IMG_LDFLAGS_AC} + expects a number appended to it. + 2010-04-18 Vladimir Serbinenko * po/POTFILES: Renamed multiboot_loader.c to multiboot.c diff --git a/acinclude.m4 b/acinclude.m4 index 692404e20..72483b5d0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -93,7 +93,7 @@ else fi grub_cv_prog_objcopy_absolute=yes for link_addr in 0x2000 0x8000 0x7C00; do - if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then : + if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC}$link_addr conftest.o -o conftest.exec]); then : else AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr]) fi diff --git a/configure.ac b/configure.ac index 3116d6584..5b959fb01 100644 --- a/configure.ac +++ b/configure.ac @@ -360,7 +360,7 @@ else if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT} -Wl,-Ttext," - TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" + TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc -Wl,-Ttext," else TARGET_IMG_LDSCRIPT= TARGET_IMG_LDFLAGS='-Wl,-N -Wl,-Ttext,' @@ -515,7 +515,7 @@ grub_PROG_LD_BUILD_ID_NONE if test "x$target_cpu" = xi386; then if test ! -z "$TARGET_IMG_LDSCRIPT"; then # Check symbols provided by linker script. - CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100" + CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000,--defsym,___main=0x8100" fi if test "x$TARGET_APPLE_CC" != x1 ; then grub_CHECK_BSS_START_SYMBOL diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index b98bbc993..4e476ae06 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -24,10 +24,10 @@ sbindir=@sbindir@ libdir=@libdir@ sysconfdir=@sysconfdir@ package_version=@PACKAGE_VERSION@ +host_os=@host_os@ datarootdir=@datarootdir@ datadir=@datadir@ pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"` -grub_prefix=`echo /boot/grub | sed ${transform}` grub_cfg="" grub_mkconfig_dir=${sysconfdir}/grub.d @@ -75,6 +75,18 @@ done . ${libdir}/grub/grub-mkconfig_lib +case "$host_os" in +netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub + # instead of /boot/grub. + grub_prefix=`echo /grub | sed ${transform}` + ;; +*) + # Use /boot/grub by default. + grub_prefix=`echo /boot/grub | sed ${transform}` + ;; +esac + if [ "x$EUID" = "x" ] ; then EUID=`id -u` fi @@ -141,13 +153,13 @@ if [ "x${GRUB_TERMINAL}" != "x" ] ; then fi termoutdefault=0 -if [ "x${GRUB_TERMINAL_OUTPUT}" == x ]; then +if [ "x${GRUB_TERMINAL_OUTPUT}" = "x" ]; then GRUB_TERMINAL_OUTPUT=gfxterm; termoutdefault=1; fi for x in ${GRUB_TERMINAL_OUTPUT}; do - if [ x${x} == xgfxterm ]; then + if [ "x${x}" = "xgfxterm" ]; then # If this platform supports gfxterm, try to use it. if ! test -e ${grub_prefix}/gfxterm.mod ; then if [ "x$termoutdefault" != "x1" ]; then From 7428eb2cf6b0b7e5edf250713ae4d8ee65ca598d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 20:38:40 +0200 Subject: [PATCH 15/38] Revert useless and wrong parts --- conf/powerpc-ieee1275.rmk | 7 ------- util/sparc64/ieee1275/grub-setup.c | 1 + 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index d7d477327..d5968ac8e 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -25,13 +25,6 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic -# Utilities. -sbin_UTILITIES = grub-ofpathname - -# For grub-ofpathname. -grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ - util/ieee1275/ofpath.c util/misc.c gnulib/progname.c - # Scripts. sbin_SCRIPTS = grub-install bin_SCRIPTS = grub-mkrescue diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 34a006d7f..b511a96b2 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -441,6 +441,7 @@ init_info (struct grub_setup_info *gp) gp->dev_map = NULL; gp->root_dev = NULL; gp->prefix = NULL; + gp->dest_dev = NULL; } static int From a6a6609cfc7bc1d605cd16cd36800f5d905a5e22 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 20:38:59 +0200 Subject: [PATCH 16/38] ChangeLog --- ChangeLog.sparcfixes | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 ChangeLog.sparcfixes diff --git a/ChangeLog.sparcfixes b/ChangeLog.sparcfixes new file mode 100644 index 000000000..3e7bcbaf9 --- /dev/null +++ b/ChangeLog.sparcfixes @@ -0,0 +1,19 @@ +2010-04-18 Vladimir Serbinenko + + * boot/sparc64/ieee1275/boot.S: Various size-reducing changes. + Retrieve chosen/bootpath if bootpath isn't hardcoded. + * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Add + util/ieee1275/ofpath.c. + * util/sparc64/ieee1275/grub-ofpathname.c: Renamed to ... + * util/ieee1275/grub-ofpathname.c: ... this. All users updated + * include/grub/sparc64/ieee1275/boot.h + (GRUB_BOOT_MACHINE_KERNEL_SECTOR): Renamed to ... + (GRUB_BOOT_MACHINE_KERNEL_BYTE): ...this. Moved 8 bytes lower. + * util/hostdisk.c (grub_util_biosdisk_get_osdev): New function. + * util/ieee1275/ofpath.c (grub_util_devname_to_ofpath): Make argument + const char *. + * util/sparc64/ieee1275/grub-setup.c (compute_dest_ofpath): Removed. + (setup): Use KERNEL_BYTE instead of KERNEL_SECTOR. + Use grub_util_devname_to_ofpath. Zero-fill boot_devpath on same disk + install. + From 189593857c736841fb79cfabbcb280f690c3ab81 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 19 Apr 2010 02:41:48 +0200 Subject: [PATCH 17/38] * fs/udf.c (grub_udf_iterate_dir): Decode the Unicode filenames. --- ChangeLog | 4 ++++ fs/udf.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9c398603..ee2cf4079 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-19 Vladimir Serbinenko + + * fs/udf.c (grub_udf_iterate_dir): Decode the Unicode filenames. + 2010-04-18 Vladimir Serbinenko * boot/sparc64/ieee1275/boot.S: Various size-reducing changes. diff --git a/fs/udf.c b/fs/udf.c index cecb6eb78..725468f54 100644 --- a/fs/udf.c +++ b/fs/udf.c @@ -25,6 +25,7 @@ #include #include #include +#include #define GRUB_UDF_MAX_PDS 2 #define GRUB_UDF_MAX_PMS 6 @@ -745,19 +746,41 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, else { enum grub_fshelp_filetype type; - char filename[dirent.file_ident_length + 1]; + grub_uint8_t raw[dirent.file_ident_length]; + grub_uint16_t utf16[dirent.file_ident_length - 1]; + grub_uint8_t filename[dirent.file_ident_length * 2]; + grub_size_t utf16len; type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); if ((grub_udf_read_file (dir, 0, offset, - dirent.file_ident_length, filename)) + dirent.file_ident_length, + (char *) raw)) != dirent.file_ident_length) return 0; - filename[dirent.file_ident_length] = 0; - if (hook (&filename[1], type, child)) - return 1; + if (raw[0] == 8) + { + unsigned i; + utf16len = dirent.file_ident_length - 1; + for (i = 0; i < utf16len; i++) + utf16[i] = raw[i + 1]; + } + if (raw[0] == 16) + { + unsigned i; + utf16len = (dirent.file_ident_length - 1) / 2; + for (i = 0; i < utf16len; i++) + utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; + } + if (raw[0] == 8 || raw[0] == 16) + { + *grub_utf16_to_utf8 (filename, utf16, utf16len) = '\0'; + + if (hook ((char *) filename, type, child)) + return 1; + } } /* Align to dword boundary. */ From f48c87aae870fd859909d9e79b0d15e2b5db2d80 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 19 Apr 2010 03:28:55 +0200 Subject: [PATCH 18/38] * fs/udf.c (grub_udf_iterate_dir): Silence a spurious warning. --- ChangeLog | 4 ++++ fs/udf.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ee2cf4079..04e84a415 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-19 Vladimir Serbinenko + + * fs/udf.c (grub_udf_iterate_dir): Silence a spurious warning. + 2010-04-19 Vladimir Serbinenko * fs/udf.c (grub_udf_iterate_dir): Decode the Unicode filenames. diff --git a/fs/udf.c b/fs/udf.c index 725468f54..ad109bed9 100644 --- a/fs/udf.c +++ b/fs/udf.c @@ -749,7 +749,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, grub_uint8_t raw[dirent.file_ident_length]; grub_uint16_t utf16[dirent.file_ident_length - 1]; grub_uint8_t filename[dirent.file_ident_length * 2]; - grub_size_t utf16len; + grub_size_t utf16len = 0; type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); From 454c3001f20d7a6662db39f6e50728833eec3177 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 19 Apr 2010 15:15:59 +0530 Subject: [PATCH 19/38] fix emu build with grub-emu-pci and grub-emu-modules --- conf/any-emu.rmk | 3 ++- include/grub/libpciaccess.h | 26 ++++++++++++++++++++++++++ include/grub/util/misc.h | 7 ++++--- 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 include/grub/libpciaccess.h diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index ddc6b0fd4..d1e5754dc 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -14,7 +14,7 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ util/hostdisk.c util/getroot.c util/mm.c util/time.c \ \ gnulib/progname.c util/hostfs.c disk/host.c -kernel_img_HEADERS += datetime.h +kernel_img_HEADERS += datetime.h util/misc.h kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes @@ -88,6 +88,7 @@ pkglib_MODULES += pci.mod pci_mod_SOURCES = util/pci.c commands/lspci.c pci_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBPCIACCESS) +kernel_img_HEADERS += libpciaccess.h endif include $(srcdir)/conf/common.mk diff --git a/include/grub/libpciaccess.h b/include/grub/libpciaccess.h new file mode 100644 index 000000000..4d2b3bde5 --- /dev/null +++ b/include/grub/libpciaccess.h @@ -0,0 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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 . + */ + +void EXPORT_FUNC (pci_slot_match_iterator_create) (void); +void EXPORT_FUNC (pci_system_cleanup) (void); +void EXPORT_FUNC (pci_device_unmap_range) (void); +void EXPORT_FUNC (pci_iterator_destroy) (void); +void EXPORT_FUNC (pci_device_map_range) (void); +void EXPORT_FUNC (pci_device_cfg_read_u32) (void); +void EXPORT_FUNC (pci_device_next) (void); +void EXPORT_FUNC (pci_system_init) (void); diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 63d4dac6d..8b78b92ea 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -27,6 +27,7 @@ #include #include +#include #ifdef __NetBSD__ /* NetBSD uses /boot for its boot block. */ @@ -40,9 +41,9 @@ extern char *progname; extern int verbosity; -void grub_util_warn (const char *fmt, ...); -void grub_util_info (const char *fmt, ...); -void grub_util_error (const char *fmt, ...) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn)); void *xmalloc (size_t size); void *xrealloc (void *ptr, size_t size); From 0d2c20c6f15ec8c7bcc1e7f30c7f9e0f561deb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Mon, 19 Apr 2010 21:25:41 +0200 Subject: [PATCH 20/38] Add grub-mkconfig support for NetBSD. --- ChangeLog | 9 ++++ po/POTFILES-shell | 1 + util/grub-mkconfig.in | 3 ++ util/grub-mkconfig_lib.in | 8 +++- util/grub.d/10_netbsd.in | 86 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 util/grub.d/10_netbsd.in diff --git a/ChangeLog b/ChangeLog index 57565fcb3..a80606f46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-04-19 Grégoire Sutre + + Add grub-mkconfig support for NetBSD. + + * util/grub.d/10_netbsd.in: grub-mkconfig helper script for NetBSD. + * util/grub-mkconfig.in: export new NetBSD specific variables. + * po/POTFILES-shell: added 10_netbsd.in. + * util/grub-mkconfig_lib.in: check for gettext binary, default to echo. + 2010-04-19 BVK Chaitanya Fix emu build with grub-emu-pci and grub-emu-modules. diff --git a/po/POTFILES-shell b/po/POTFILES-shell index cb28d331b..90d2b978c 100644 --- a/po/POTFILES-shell +++ b/po/POTFILES-shell @@ -2,3 +2,4 @@ # Shell language are included here. util/grub.d/10_kfreebsd.in util/grub.d/10_linux.in +util/grub.d/10_netbsd.in diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 4e476ae06..85212f8fc 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -239,11 +239,14 @@ export GRUB_DEFAULT \ GRUB_DISTRIBUTOR \ GRUB_CMDLINE_LINUX \ GRUB_CMDLINE_LINUX_DEFAULT \ + GRUB_CMDLINE_NETBSD \ + GRUB_CMDLINE_NETBSD_DEFAULT \ GRUB_TERMINAL_INPUT \ GRUB_TERMINAL_OUTPUT \ GRUB_SERIAL_COMMAND \ GRUB_DISABLE_LINUX_UUID \ GRUB_DISABLE_LINUX_RECOVERY \ + GRUB_DISABLE_NETBSD_RECOVERY \ GRUB_GFXMODE \ GRUB_BACKGROUND \ GRUB_THEME \ diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index a4151348c..831bef846 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -31,6 +31,12 @@ if test "x$grub_mkrelpath" = x; then grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}` fi +if $(which gettext >/dev/null 2>/dev/null) ; then + gettext="gettext" +else + gettext="echo" +fi + grub_warn () { echo "Warning: $@" >&2 @@ -190,5 +196,5 @@ version_find_latest () } gettext_quoted () { - gettext "$@" | sed "s/'/'\\\\''/g" + $gettext "$@" | sed "s/'/'\\\\''/g" } diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in new file mode 100644 index 000000000..7e5fb34ad --- /dev/null +++ b/util/grub.d/10_netbsd.in @@ -0,0 +1,86 @@ +#! /bin/sh -e + +# grub-mkconfig helper script. +# Copyright (C) 2006,2007,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 . + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +libdir=@libdir@ +. ${libdir}/grub/grub-mkconfig_lib + +export TEXTDOMAIN=@PACKAGE@ +export TEXTDOMAINDIR=@localedir@ + +if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then + OS=NetBSD +else + OS="${GRUB_DISTRIBUTOR} NetBSD" +fi + +netbsd_entry () +{ + loader="$1" # "knetbsd" or "multiboot" + kernel="$2" # absolute path to the kernel file + recovery="$3" # is this is a recovery entry? + args="$4" # extra arguments appended to loader command + + kroot_device="$(echo ${GRUB_DEVICE} | sed -e 's,^/dev/r,,')" + if ${recovery} ; then + title="$(gettext_quoted "%s, with kernel %s (via %s, recovery mode)")" + else + title="$(gettext_quoted "%s, with kernel %s (via %s)")" + fi + + printf "menuentry \"${title}\" {\n" \ + "${OS}" "$(echo ${kernel} | sed -e 's,^.*/,,')" "${loader}" + printf "%s\n" "${prepare_boot_cache}" + case "${loader}" in + knetbsd) + printf "\tknetbsd %s -r %s %s\n" \ + "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}" + ;; + multiboot) + printf "\tmultiboot %s %s root=%s %s\n" \ + "${kernel}" "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}" + ;; + esac + printf "}\n" +} + +prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e 's,^, ,')" + +# We look for NetBSD kernels in / but not in subdirectories. We simply +# pick all statically linked ELF executable files (or links) in / with a +# name that starts with `netbsd'. +pattern="^ELF[^,]*executable.*statically linked" +for k in $(ls -t /netbsd*) ; do + if ! grub_file_is_not_garbage "$k" ; then + continue + fi + if ! ((file -bL "$k" | grep -q "${pattern}") || + (zcat "$k" | file -bL - | grep -q "${pattern}")) 2>/dev/null ; then + continue + fi + + echo "Found NetBSD kernel: $k" >&2 + netbsd_entry "knetbsd" "$k" false "${GRUB_CMDLINE_NETBSD_DEFAULT}" + netbsd_entry "multiboot" "$k" false "${GRUB_CMDLINE_NETBSD_DEFAULT}" + if [ "x${GRUB_DISABLE_NETBSD_RECOVERY}" != "xtrue" ]; then + netbsd_entry "knetbsd" "$k" true "-s" + netbsd_entry "multiboot" "$k" true "-s" + fi +done From 4ba8d3540af50879a797994939c4d8559772215a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 21 Apr 2010 21:26:56 +0200 Subject: [PATCH 21/38] * configure.ac: Refuse to compile for x86_64-efi is mcmodel=large is not supported. --- ChangeLog | 5 +++++ configure.ac | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a80606f46..a8fab4bcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-21 Vladimir Serbinenko + + * configure.ac: Refuse to compile for x86_64-efi is mcmodel=large + is not supported. + 2010-04-19 Grégoire Sutre Add grub-mkconfig support for NetBSD. diff --git a/configure.ac b/configure.ac index 5b959fb01..28b3c1d95 100644 --- a/configure.ac +++ b/configure.ac @@ -413,9 +413,7 @@ if test "$target_cpu"-"$platform" = x86_64-efi; then [grub_cv_cc_mcmodel=no]) ]) if test "x$grub_cv_cc_mcmodel" = xno; then - CFLAGS="$SAVED_CFLAGS -m64 -DMCMODEL_SMALL=1" - TARGET_CFLAGS="$TARGET_CFLAGS -DMCMODEL_SMALL=1" - AC_MSG_WARN([-mcmodel=large not supported. You won't be able to use the memory over 4GiB. Upgrade your gcc]) + AC_MSG_ERROR([-mcmodel=large not supported. Upgrade your gcc.]) else TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large" fi From f67dc308f6339cef658747870bfbbe31f4949e48 Mon Sep 17 00:00:00 2001 From: Jiro SEKIBA Date: Sat, 24 Apr 2010 22:09:08 +0200 Subject: [PATCH 22/38] Nilfs2 support. * conf/common.rmk (grub_probe_SOURCES): Add fs/nilfs2.c. (grub_fstest_SOURCES): Likewise. (pkglib_MODULES): Add nilfs2.mod. (nilfs2_mod_SOURCES): New variable. (nilfs2_mod_CFLAGS): Likewise. (nilfs2_mod_LDFLAGS): Likewise. * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. * fs/nilfs2.c: New file. --- ChangeLog | 14 + conf/common.rmk | 14 +- conf/i386-pc.rmk | 6 +- conf/sparc64-ieee1275.rmk | 6 +- fs/nilfs2.c | 1133 +++++++++++++++++++++++++++++++++++++ 5 files changed, 1163 insertions(+), 10 deletions(-) create mode 100644 fs/nilfs2.c diff --git a/ChangeLog b/ChangeLog index a8fab4bcc..ca82974e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-04-24 Jiro SEKIBA + + Nilfs2 support. + + * conf/common.rmk (grub_probe_SOURCES): Add fs/nilfs2.c. + (grub_fstest_SOURCES): Likewise. + (pkglib_MODULES): Add nilfs2.mod. + (nilfs2_mod_SOURCES): New variable. + (nilfs2_mod_CFLAGS): Likewise. + (nilfs2_mod_LDFLAGS): Likewise. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. + * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. + * fs/nilfs2.c: New file. + 2010-04-21 Vladimir Serbinenko * configure.ac: Refuse to compile for x86_64-efi is mcmodel=large diff --git a/conf/common.rmk b/conf/common.rmk index 8df232a0b..4b39e9b71 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -31,9 +31,9 @@ grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ \ partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \ partmap/sun.c partmap/sunpc.c partmap/gpt.c \ @@ -69,7 +69,7 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c \ fs/befs_be.c fs/tar.c \ \ @@ -298,6 +298,12 @@ minix_mod_SOURCES = fs/minix.c minix_mod_CFLAGS = $(COMMON_CFLAGS) minix_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For nilfs2.mod. +pkglib_MODULES += nilfs2.mod +nilfs2_mod_SOURCES = fs/nilfs2.c +nilfs2_mod_CFLAGS = $(COMMON_CFLAGS) +nilfs2_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For hfs.mod. hfs_mod_SOURCES = fs/hfs.c hfs_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index eace1e2da..a5a1b08ea 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -82,9 +82,9 @@ grub_setup_SOURCES = gnulib/progname.c \ \ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ \ partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ partmap/gpt.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index c82bd81f3..f0c9b0db7 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -58,9 +58,9 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ \ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ \ partmap/amiga.c partmap/apple.c partmap/msdos.c \ partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ diff --git a/fs/nilfs2.c b/fs/nilfs2.c new file mode 100644 index 000000000..7e0415d12 --- /dev/null +++ b/fs/nilfs2.c @@ -0,0 +1,1133 @@ +/* + * nilfs2.c - New Implementation of Log filesystem + * + * Written by Jiro SEKIBA + * + * Copyright (C) 2003,2004,2005,2007,2008,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 . + */ + + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NILFS_INODE_BMAP_SIZE 7 + +#define NILFS_SUPORT_REV 2 + +/* Magic value used to identify an nilfs2 filesystem. */ +#define NILFS2_SUPER_MAGIC 0x3434 +/* nilfs btree node flag. */ +#define NILFS_BTREE_NODE_ROOT 0x01 + +/* nilfs btree node level. */ +#define NILFS_BTREE_LEVEL_DATA 0 +#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) +#define NILFS_BTREE_LEVEL_MAX 14 + +struct grub_nilfs2_inode +{ + grub_uint64_t i_blocks; + grub_uint64_t i_size; + grub_uint64_t i_ctime; + grub_uint64_t i_mtime; + grub_uint32_t i_ctime_nsec; + grub_uint32_t i_mtime_nsec; + grub_uint32_t i_uid; + grub_uint32_t i_gid; + grub_uint16_t i_mode; + grub_uint16_t i_links_count; + grub_uint32_t i_flags; + grub_uint64_t i_bmap[NILFS_INODE_BMAP_SIZE]; +#define i_device_code i_bmap[0] + grub_uint64_t i_xattr; + grub_uint32_t i_generation; + grub_uint32_t i_pad; +}; + +struct grub_nilfs2_super_root +{ + grub_uint32_t sr_sum; + grub_uint16_t sr_bytes; + grub_uint16_t sr_flags; + grub_uint64_t sr_nongc_ctime; + struct grub_nilfs2_inode sr_dat; + struct grub_nilfs2_inode sr_cpfile; + struct grub_nilfs2_inode sr_sufile; +}; + +struct grub_nilfs2_super_block +{ + grub_uint32_t s_rev_level; + grub_uint16_t s_minor_rev_level; + grub_uint16_t s_magic; + grub_uint16_t s_bytes; + grub_uint16_t s_flags; + grub_uint32_t s_crc_seed; + grub_uint32_t s_sum; + grub_uint32_t s_log_block_size; + grub_uint64_t s_nsegments; + grub_uint64_t s_dev_size; + grub_uint64_t s_first_data_block; + grub_uint32_t s_blocks_per_segment; + grub_uint32_t s_r_segments_percentage; + grub_uint64_t s_last_cno; + grub_uint64_t s_last_pseg; + grub_uint64_t s_last_seq; + grub_uint64_t s_free_blocks_count; + grub_uint64_t s_ctime; + grub_uint64_t s_mtime; + grub_uint64_t s_wtime; + grub_uint16_t s_mnt_count; + grub_uint16_t s_max_mnt_count; + grub_uint16_t s_state; + grub_uint16_t s_errors; + grub_uint64_t s_lastcheck; + grub_uint32_t s_checkinterval; + grub_uint32_t s_creator_os; + grub_uint16_t s_def_resuid; + grub_uint16_t s_def_resgid; + grub_uint32_t s_first_ino; + grub_uint16_t s_inode_size; + grub_uint16_t s_dat_entry_size; + grub_uint16_t s_checkpoint_size; + grub_uint16_t s_segment_usage_size; + grub_uint8_t s_uuid[16]; + char s_volume_name[16]; + char s_last_mounted[64]; + grub_uint32_t s_c_interval; + grub_uint32_t s_c_block_max; + grub_uint32_t s_reserved[192]; +}; + +struct grub_nilfs2_dir_entry +{ + grub_uint64_t inode; + grub_uint16_t rec_len; + grub_uint8_t name_len; + grub_uint8_t file_type; +#if 0 /* followed by file name. */ + char name[NILFS_NAME_LEN]; + char pad; +#endif +} __attribute__ ((packed)); + +enum +{ + NILFS_FT_UNKNOWN, + NILFS_FT_REG_FILE, + NILFS_FT_DIR, + NILFS_FT_CHRDEV, + NILFS_FT_BLKDEV, + NILFS_FT_FIFO, + NILFS_FT_SOCK, + NILFS_FT_SYMLINK, + NILFS_FT_MAX +}; + +struct grub_nilfs2_finfo +{ + grub_uint64_t fi_ino; + grub_uint64_t fi_cno; + grub_uint32_t fi_nblocks; + grub_uint32_t fi_ndatablk; +}; + +struct grub_nilfs2_binfo_v +{ + grub_uint64_t bi_vblocknr; + grub_uint64_t bi_blkoff; +}; + +struct grub_nilfs2_binfo_dat +{ + grub_uint64_t bi_blkoff; + grub_uint8_t bi_level; + grub_uint8_t bi_pad[7]; +}; + +union grub_nilfs2_binfo +{ + struct grub_nilfs2_binfo_v bi_v; + struct grub_nilfs2_binfo_dat bi_dat; +}; + +struct grub_nilfs2_segment_summary +{ + grub_uint32_t ss_datasum; + grub_uint32_t ss_sumsum; + grub_uint32_t ss_magic; + grub_uint16_t ss_bytes; + grub_uint16_t ss_flags; + grub_uint64_t ss_seq; + grub_uint64_t ss_create; + grub_uint64_t ss_next; + grub_uint32_t ss_nblocks; + grub_uint32_t ss_nfinfo; + grub_uint32_t ss_sumbytes; + grub_uint32_t ss_pad; +}; + +struct grub_nilfs2_btree_node +{ + grub_uint8_t bn_flags; + grub_uint8_t bn_level; + grub_uint16_t bn_nchildren; + grub_uint32_t bn_pad; +}; + +struct grub_nilfs2_palloc_group_desc +{ + grub_uint32_t pg_nfrees; +}; + +struct grub_nilfs2_dat_entry +{ + grub_uint64_t de_blocknr; + grub_uint64_t de_start; + grub_uint64_t de_end; + grub_uint64_t de_rsv; +}; + +struct grub_nilfs2_snapshot_list +{ + grub_uint64_t ssl_next; + grub_uint64_t ssl_prev; +}; + +struct grub_nilfs2_cpfile_header +{ + grub_uint64_t ch_ncheckpoints; + grub_uint64_t ch_nsnapshots; + struct grub_nilfs2_snapshot_list ch_snapshot_list; +}; + +struct grub_nilfs2_checkpoint +{ + grub_uint32_t cp_flags; + grub_uint32_t cp_checkpoints_count; + struct grub_nilfs2_snapshot_list cp_snapshot_list; + grub_uint64_t cp_cno; + grub_uint64_t cp_create; + grub_uint64_t cp_nblk_inc; + grub_uint64_t cp_inodes_count; + grub_uint64_t cp_blocks_count; + struct grub_nilfs2_inode cp_ifile_inode; +}; + + +#define NILFS_BMAP_LARGE 0x1 +#define NILFS_BMAP_SIZE (NILFS_INODE_BMAP_SIZE * sizeof(grub_uint64_t)) + +/* nilfs extra padding for nonroot btree node. */ +#define NILFS_BTREE_NODE_EXTRA_PAD_SIZE (sizeof(grub_uint64_t)) +#define NILFS_BTREE_ROOT_SIZE NILFS_BMAP_SIZE +#define NILFS_BTREE_ROOT_NCHILDREN_MAX \ + ((NILFS_BTREE_ROOT_SIZE - sizeof(struct nilfs_btree_node)) / \ + (sizeof(grub_uint64_t) + sizeof(grub_uint64_t)) ) + + +struct grub_fshelp_node +{ + struct grub_nilfs2_data *data; + struct grub_nilfs2_inode inode; + grub_uint64_t ino; + int inode_read; +}; + +struct grub_nilfs2_data +{ + struct grub_nilfs2_super_block sblock; + struct grub_nilfs2_super_root sroot; + struct grub_nilfs2_inode ifile; + grub_disk_t disk; + struct grub_nilfs2_inode *inode; + struct grub_fshelp_node diropen; +}; + +/* Log2 size of nilfs2 block in 512 blocks. */ +#define LOG2_NILFS2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 1) + +/* Log2 size of nilfs2 block in bytes. */ +#define LOG2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 10) + +/* The size of an nilfs2 block in bytes. */ +#define NILFS2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE (data)) + +static grub_uint64_t +grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key); +static grub_dl_t my_mod; + + + +static inline unsigned long +grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data) +{ + return 1UL << (LOG2_BLOCK_SIZE (data) + 3); +} + +static inline grub_uint64_t +grub_nilfs2_palloc_group (struct grub_nilfs2_data *data, + grub_uint64_t nr, grub_uint32_t * offset) +{ + return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data), + offset); +} + +static inline grub_uint32_t +grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data) +{ + return NILFS2_BLOCK_SIZE (data) / + sizeof (struct grub_nilfs2_palloc_group_desc); +} + +static inline grub_uint32_t +grub_nilfs2_entries_per_block (struct grub_nilfs2_data *data, + unsigned long entry_size) +{ + return NILFS2_BLOCK_SIZE (data) / entry_size; +} + + +static inline grub_uint32_t +grub_nilfs2_blocks_per_group (struct grub_nilfs2_data *data, + unsigned long entry_size) +{ + return grub_div_roundup (grub_nilfs2_palloc_entries_per_group (data), + grub_nilfs2_entries_per_block (data, + entry_size)) + 1; +} + +static inline grub_uint32_t +grub_nilfs2_blocks_per_desc_block (struct grub_nilfs2_data *data, + unsigned long entry_size) +{ + return grub_nilfs2_palloc_groups_per_desc_block (data) * + grub_nilfs2_blocks_per_group (data, entry_size) + 1; +} + +static inline grub_uint32_t +grub_nilfs2_palloc_desc_block_offset (struct grub_nilfs2_data *data, + unsigned long group, + unsigned long entry_size) +{ + grub_uint32_t desc_block = + group / grub_nilfs2_palloc_groups_per_desc_block (data); + return desc_block * grub_nilfs2_blocks_per_desc_block (data, entry_size); +} + +static inline grub_uint32_t +grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data, + unsigned long group, + unsigned long entry_size) +{ + unsigned long desc_offset = group % + grub_nilfs2_palloc_groups_per_desc_block (data); + + return grub_nilfs2_palloc_desc_block_offset (data, group, entry_size) + 1 + + desc_offset * grub_nilfs2_blocks_per_group (data, entry_size); +} + +static inline grub_uint32_t +grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data, + grub_uint64_t nr, unsigned long entry_size) +{ + unsigned long group; + grub_uint32_t group_offset; + + group = grub_nilfs2_palloc_group (data, nr, &group_offset); + + return grub_nilfs2_palloc_bitmap_block_offset (data, group, + entry_size) + 1 + + group_offset / grub_nilfs2_entries_per_block (data, entry_size); + +} + +static inline struct grub_nilfs2_btree_node * +grub_nilfs2_btree_get_root (struct grub_nilfs2_inode *inode) +{ + return (struct grub_nilfs2_btree_node *) &inode->i_bmap[0]; +} + +static inline int +grub_nilfs2_btree_get_level (struct grub_nilfs2_btree_node *node) +{ + return node->bn_level; +} + +static inline grub_uint64_t * +grub_nilfs2_btree_node_dkeys (struct grub_nilfs2_btree_node *node) +{ + return (grub_uint64_t *) ((char *) (node + 1) + + ((node->bn_flags & NILFS_BTREE_NODE_ROOT) ? + 0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE)); +} + +static inline grub_uint64_t +grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node, + int index) +{ + return grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dkeys (node) + index)); +} + +static inline int +grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node, + grub_uint64_t key, int *indexp) +{ + grub_uint64_t nkey; + int index, low, high, s; + + low = 0; + high = grub_le_to_cpu16 (node->bn_nchildren) - 1; + index = 0; + s = 0; + while (low <= high) + { + index = (low + high) / 2; + nkey = grub_nilfs2_btree_node_get_key (node, index); + if (nkey == key) + { + *indexp = index; + return 1; + } + else if (nkey < key) + { + low = index + 1; + s = -1; + } + else + { + high = index - 1; + s = 1; + } + } + + if (node->bn_level > NILFS_BTREE_LEVEL_NODE_MIN) + { + if (s > 0 && index > 0) + index--; + } + else if (s < 0) + index++; + + *indexp = index; + return s == 0; +} + +static inline int +grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node) +{ + int node_children_max = ((NILFS2_BLOCK_SIZE (data) - + sizeof (struct grub_nilfs2_btree_node) - + NILFS_BTREE_NODE_EXTRA_PAD_SIZE) / + (sizeof (grub_uint64_t) + sizeof (grub_uint64_t))); + + return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max; +} + +static inline grub_uint64_t * +grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node) +{ + return (grub_uint64_t *) (grub_nilfs2_btree_node_dkeys (node) + + grub_nilfs2_btree_node_nchildren_max (data, + node)); +} + +static inline grub_uint64_t +grub_nilfs2_btree_node_get_ptr (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node, + int index) +{ + return + grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dptrs (data, node) + index)); +} + +static inline int +grub_nilfs2_btree_get_nonroot_node (struct grub_nilfs2_data *data, + grub_uint64_t ptr, void *block) +{ + grub_disk_t disk = data->disk; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + return grub_disk_read (disk, ptr * nilfs2_block_count, 0, + NILFS2_BLOCK_SIZE (data), block); +} + +static grub_uint64_t +grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, + struct grub_nilfs2_inode *inode, + grub_uint64_t key, int need_translate) +{ + struct grub_nilfs2_btree_node *node; + unsigned char block[NILFS2_BLOCK_SIZE (data)]; + grub_uint64_t ptr; + int level, found, index; + + node = grub_nilfs2_btree_get_root (inode); + level = grub_nilfs2_btree_get_level (node); + + found = grub_nilfs2_btree_node_lookup (node, key, &index); + ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + + for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) + { + grub_nilfs2_btree_get_nonroot_node (data, ptr, block); + if (grub_errno) + { + return -1; + } + node = (struct grub_nilfs2_btree_node *) block; + + if (node->bn_level != level) + { + grub_error (GRUB_ERR_BAD_FS, "btree level mismatch\n"); + return -1; + } + + if (!found) + found = grub_nilfs2_btree_node_lookup (node, key, &index); + else + index = 0; + + if (index < grub_nilfs2_btree_node_nchildren_max (data, node)) + { + ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + } + else + { + grub_error (GRUB_ERR_BAD_FS, "btree corruption\n"); + return -1; + } + } + + if (!found) + return -1; + + return ptr; +} + +static inline grub_uint64_t +grub_nilfs2_direct_lookup (struct grub_nilfs2_inode *inode, grub_uint64_t key) +{ + return grub_le_to_cpu64 (inode->i_bmap[1 + key]); +} + +static inline grub_uint64_t +grub_nilfs2_bmap_lookup (struct grub_nilfs2_data *data, + struct grub_nilfs2_inode *inode, + grub_uint64_t key, int need_translate) +{ + struct grub_nilfs2_btree_node *root = grub_nilfs2_btree_get_root (inode); + if (root->bn_flags & NILFS_BMAP_LARGE) + return grub_nilfs2_btree_lookup (data, inode, key, need_translate); + else + { + grub_uint64_t ptr; + ptr = grub_nilfs2_direct_lookup (inode, key); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + return ptr; + } +} + +static grub_uint64_t +grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key) +{ + struct grub_nilfs2_dat_entry entry; + grub_disk_t disk = data->disk; + grub_uint64_t pptr; + grub_uint32_t blockno, offset; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + blockno = grub_nilfs2_palloc_entry_offset (data, key, + sizeof (struct + grub_nilfs2_dat_entry)); + + grub_divmod64 (key * sizeof (struct grub_nilfs2_dat_entry), + NILFS2_BLOCK_SIZE (data), &offset); + + pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_dat, blockno, 0); + if (pptr == (grub_uint64_t) - 1) + { + grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + return -1; + } + + grub_disk_read (disk, pptr * nilfs2_block_count, offset, + sizeof (struct grub_nilfs2_dat_entry), &entry); + + return grub_le_to_cpu64 (entry.de_blocknr); +} + + +static grub_disk_addr_t +grub_nilfs2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + struct grub_nilfs2_data *data = node->data; + struct grub_nilfs2_inode *inode = &node->inode; + grub_uint64_t pptr = -1; + + pptr = grub_nilfs2_bmap_lookup (data, inode, fileblock, 1); + if (pptr == (grub_uint64_t) - 1) + { + grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + return -1; + } + + return pptr; +} + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_nilfs2_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t + sector, + unsigned offset, + unsigned length), + int pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_nilfs2_read_block, + grub_le_to_cpu64 (node->inode.i_size), + LOG2_NILFS2_BLOCK_SIZE (node->data)); + +} + +static grub_err_t +grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data, + grub_uint64_t cpno, + struct grub_nilfs2_checkpoint *cpp) +{ + grub_uint64_t blockno; + grub_uint32_t offset; + grub_uint64_t pptr; + grub_disk_t disk = data->disk; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + /* Assume sizeof(struct grub_nilfs2_cpfile_header) < + sizeof(struct grub_nilfs2_checkpoint). + */ + blockno = grub_divmod64 (cpno, NILFS2_BLOCK_SIZE (data) / + sizeof (struct grub_nilfs2_checkpoint), &offset); + + pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_cpfile, blockno, 1); + if (pptr == (grub_uint64_t) - 1) + { + return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + } + + return grub_disk_read (disk, pptr * nilfs2_block_count, + offset * sizeof (struct grub_nilfs2_checkpoint), + sizeof (struct grub_nilfs2_checkpoint), cpp); +} + +static inline grub_err_t +grub_nilfs2_read_last_checkpoint (struct grub_nilfs2_data *data, + struct grub_nilfs2_checkpoint *cpp) +{ + return grub_nilfs2_read_checkpoint (data, + grub_le_to_cpu64 (data-> + sblock.s_last_cno), + cpp); +} + +/* Read the inode INO for the file described by DATA into INODE. */ +static grub_err_t +grub_nilfs2_read_inode (struct grub_nilfs2_data *data, + grub_uint64_t ino, struct grub_nilfs2_inode *inodep) +{ + grub_uint64_t blockno; + unsigned int offset; + grub_uint64_t pptr; + grub_disk_t disk = data->disk; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + blockno = grub_nilfs2_palloc_entry_offset (data, ino, + sizeof (struct + grub_nilfs2_inode)); + + grub_divmod64 (sizeof (struct grub_nilfs2_inode) * ino, + NILFS2_BLOCK_SIZE (data), &offset); + pptr = grub_nilfs2_bmap_lookup (data, &data->ifile, blockno, 1); + if (pptr == (grub_uint64_t) - 1) + { + return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + } + + return grub_disk_read (disk, pptr * nilfs2_block_count, offset, + sizeof (struct grub_nilfs2_inode), inodep); +} + +static int +grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp) +{ + if (grub_le_to_cpu16 (sbp->s_magic) != NILFS2_SUPER_MAGIC) + return 0; + + if (grub_le_to_cpu32 (sbp->s_rev_level) != NILFS_SUPORT_REV) + return 0; + + return 1; +} + +static struct grub_nilfs2_data * +grub_nilfs2_mount (grub_disk_t disk) +{ + struct grub_nilfs2_data *data; + struct grub_nilfs2_segment_summary ss; + struct grub_nilfs2_checkpoint last_checkpoint; + grub_uint64_t last_pseg; + grub_uint32_t nblocks; + unsigned int nilfs2_block_count; + + data = grub_malloc (sizeof (struct grub_nilfs2_data)); + if (!data) + return 0; + + /* Read the superblock. */ + grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), + &data->sblock); + if (grub_errno) + goto fail; + + /* Make sure this is an nilfs2 filesystem. */ + if (!grub_nilfs2_valid_sb (&data->sblock)) + { + grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + goto fail; + } + + nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + /* Read the last segment summary. */ + last_pseg = grub_le_to_cpu64 (data->sblock.s_last_pseg); + grub_disk_read (disk, last_pseg * nilfs2_block_count, 0, + sizeof (struct grub_nilfs2_segment_summary), &ss); + + if (grub_errno) + goto fail; + + /* Read the super root block. */ + nblocks = grub_le_to_cpu32 (ss.ss_nblocks); + grub_disk_read (disk, (last_pseg + (nblocks - 1)) * nilfs2_block_count, 0, + sizeof (struct grub_nilfs2_super_root), &data->sroot); + + if (grub_errno) + goto fail; + + data->disk = disk; + + grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); + + if (grub_errno) + goto fail; + + grub_memcpy (&data->ifile, &last_checkpoint.cp_ifile_inode, + sizeof (struct grub_nilfs2_inode)); + + data->diropen.data = data; + data->diropen.ino = 2; + data->diropen.inode_read = 1; + data->inode = &data->diropen.inode; + + grub_nilfs2_read_inode (data, 2, data->inode); + + return data; + +fail: + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + + grub_free (data); + return 0; +} + +static char * +grub_nilfs2_read_symlink (grub_fshelp_node_t node) +{ + char *symlink; + struct grub_fshelp_node *diro = node; + + if (!diro->inode_read) + { + grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + symlink = grub_malloc (grub_le_to_cpu64 (diro->inode.i_size) + 1); + if (!symlink) + return 0; + + grub_nilfs2_read_file (diro, 0, 0, + grub_le_to_cpu64 (diro->inode.i_size), symlink); + if (grub_errno) + { + grub_free (symlink); + return 0; + } + + symlink[grub_le_to_cpu64 (diro->inode.i_size)] = '\0'; + return symlink; +} + +static int +grub_nilfs2_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + unsigned int fpos = 0; + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; + + if (!diro->inode_read) + { + grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + /* Iterate files. */ + while (fpos < grub_le_to_cpu64 (diro->inode.i_size)) + { + struct grub_nilfs2_dir_entry dirent; + + grub_nilfs2_read_file (diro, 0, fpos, + sizeof (struct grub_nilfs2_dir_entry), + (char *) &dirent); + if (grub_errno) + return 0; + + if (dirent.rec_len == 0) + return 0; + + if (dirent.name_len != 0) + { + char filename[dirent.name_len + 1]; + struct grub_fshelp_node *fdiro; + enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; + + grub_nilfs2_read_file (diro, 0, + fpos + sizeof (struct grub_nilfs2_dir_entry), + dirent.name_len, filename); + if (grub_errno) + return 0; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!fdiro) + return 0; + + fdiro->data = diro->data; + fdiro->ino = grub_le_to_cpu64 (dirent.inode); + + filename[dirent.name_len] = '\0'; + + if (dirent.file_type != NILFS_FT_UNKNOWN) + { + fdiro->inode_read = 0; + + if (dirent.file_type == NILFS_FT_DIR) + type = GRUB_FSHELP_DIR; + else if (dirent.file_type == NILFS_FT_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if (dirent.file_type == NILFS_FT_REG_FILE) + type = GRUB_FSHELP_REG; + } + else + { + /* The filetype can not be read from the dirent, read + the inode to get more information. */ + grub_nilfs2_read_inode (diro->data, + grub_le_to_cpu64 (dirent.inode), + &fdiro->inode); + if (grub_errno) + { + grub_free (fdiro); + return 0; + } + + fdiro->inode_read = 1; + + if ((grub_le_to_cpu16 (fdiro->inode.i_mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + type = GRUB_FSHELP_DIR; + else if ((grub_le_to_cpu16 (fdiro->inode.i_mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if ((grub_le_to_cpu16 (fdiro->inode.i_mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_REG) + type = GRUB_FSHELP_REG; + } + + if (hook (filename, type, fdiro)) + return 1; + } + + fpos += grub_le_to_cpu16 (dirent.rec_len); + } + + return 0; +} + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_nilfs2_open (struct grub_file *file, const char *name) +{ + struct grub_nilfs2_data *data = NULL; + struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, + grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink, + GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + if (!fdiro->inode_read) + { + grub_nilfs2_read_inode (data, fdiro->ino, &fdiro->inode); + if (grub_errno) + goto fail; + } + + grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_nilfs2_inode)); + grub_free (fdiro); + + file->size = grub_le_to_cpu64 (data->inode->i_size); + file->data = data; + file->offset = 0; + + return 0; + +fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_nilfs2_close (grub_file_t file) +{ + grub_free (file->data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +/* Read LEN bytes data from FILE into BUF. */ +static grub_ssize_t +grub_nilfs2_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_nilfs2_data *data = (struct grub_nilfs2_data *) file->data; + + return grub_nilfs2_read_file (&data->diropen, file->read_hook, + file->offset, len, buf); +} + +static grub_err_t +grub_nilfs2_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, + const struct grub_dirhook_info * info)) +{ + struct grub_nilfs2_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + if (!node->inode_read) + { + grub_nilfs2_read_inode (data, node->ino, &node->inode); + if (!grub_errno) + node->inode_read = 1; + grub_errno = GRUB_ERR_NONE; + } + if (node->inode_read) + { + info.mtimeset = 1; + info.mtime = grub_le_to_cpu64 (node->inode.i_mtime); + } + + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, &info); + } + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (path, &data->diropen, &fdiro, + grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink, + GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_nilfs2_iterate_dir (fdiro, iterate); + +fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_nilfs2_label (grub_device_t device, char **label) +{ + struct grub_nilfs2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (disk); + if (data) + *label = grub_strndup (data->sblock.s_volume_name, 14); + else + *label = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_nilfs2_uuid (grub_device_t device, char **uuid) +{ + struct grub_nilfs2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (disk); + if (data) + { + *uuid = + grub_xasprintf + ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%0x-%02x%02x%02x%02x%02x%02x", + data->sblock.s_uuid[0], data->sblock.s_uuid[1], + data->sblock.s_uuid[2], data->sblock.s_uuid[3], + data->sblock.s_uuid[4], data->sblock.s_uuid[5], + data->sblock.s_uuid[6], data->sblock.s_uuid[7], + data->sblock.s_uuid[8], data->sblock.s_uuid[9], + data->sblock.s_uuid[10], data->sblock.s_uuid[11], + data->sblock.s_uuid[12], data->sblock.s_uuid[13], + data->sblock.s_uuid[14], data->sblock.s_uuid[15]); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +/* Get mtime. */ +static grub_err_t +grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm) +{ + struct grub_nilfs2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (disk); + if (!data) + *tm = 0; + else + *tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_mtime); + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + + + +static struct grub_fs grub_nilfs2_fs = { + .name = "nilfs2", + .dir = grub_nilfs2_dir, + .open = grub_nilfs2_open, + .read = grub_nilfs2_read, + .close = grub_nilfs2_close, + .label = grub_nilfs2_label, + .uuid = grub_nilfs2_uuid, + .mtime = grub_nilfs2_mtime, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif + .next = 0 +}; + +GRUB_MOD_INIT (nilfs2) +{ + grub_fs_register (&grub_nilfs2_fs); + my_mod = mod; +} + +GRUB_MOD_FINI (nilfs2) +{ + grub_fs_unregister (&grub_nilfs2_fs); +} From 2aec1692d929f28b75242beafaf971d777b78655 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sat, 24 Apr 2010 22:41:52 +0200 Subject: [PATCH 23/38] * configure.ac: Do not CHECK_BSS_START_SYMBOL and CHECK_END_SYMBOL if grub-emu is built. Unset TARGET_OBJ2ELF if grub-emu is built without module support. --- ChangeLog | 7 +++++++ configure.ac | 16 +++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca82974e4..044b396b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-04-24 Christian Franke + + * configure.ac: Do not CHECK_BSS_START_SYMBOL + and CHECK_END_SYMBOL if grub-emu is built. + Unset TARGET_OBJ2ELF if grub-emu is built + without module support. + 2010-04-24 Jiro SEKIBA Nilfs2 support. diff --git a/configure.ac b/configure.ac index 28b3c1d95..4bfc5a2b0 100644 --- a/configure.ac +++ b/configure.ac @@ -511,11 +511,11 @@ grub_PROG_OBJCOPY_ABSOLUTE fi grub_PROG_LD_BUILD_ID_NONE if test "x$target_cpu" = xi386; then - if test ! -z "$TARGET_IMG_LDSCRIPT"; then - # Check symbols provided by linker script. - CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000,--defsym,___main=0x8100" - fi - if test "x$TARGET_APPLE_CC" != x1 ; then + if test "$platform" != emu && test "x$TARGET_APPLE_CC" != x1 ; then + if test ! -z "$TARGET_IMG_LDSCRIPT"; then + # Check symbols provided by linker script. + CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000 -Wl,--defsym,___main=0x8100" + fi grub_CHECK_BSS_START_SYMBOL grub_CHECK_END_SYMBOL fi @@ -635,6 +635,12 @@ else fi AC_SUBST(TARGET_NO_MODULES) +if test "$TARGET_NO_MODULES" = yes ; then + # Do not convert modules, otherwise linkage may fail (Cygwin only). + # FIXME: Should be checked above before TARGET_OBJ2ELF is set first. + TARGET_OBJ2ELF= +fi + if test x"$enable_grub_emu_usb" = xno ; then grub_emu_usb_excuse="explicitly disabled" fi From 553c01f95813ed7245b4bc3484940843a5e28e30 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sat, 24 Apr 2010 23:18:57 +0200 Subject: [PATCH 24/38] * Makefile.in (TARGET_LDFLAGS): Add -static-libgcc. (kernel_img_LDFLAGS): Remove -static-libgcc. --- ChangeLog | 5 +++++ Makefile.in | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 044b396b3..92c8dc53c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-24 Christian Franke + + * Makefile.in (TARGET_LDFLAGS): Add -static-libgcc. + (kernel_img_LDFLAGS): Remove -static-libgcc. + 2010-04-24 Christian Franke * configure.ac: Do not CHECK_BSS_START_SYMBOL diff --git a/Makefile.in b/Makefile.in index 29f997213..822a08797 100644 --- a/Makefile.in +++ b/Makefile.in @@ -99,12 +99,12 @@ TARGET_APPLE_CC = @TARGET_APPLE_CC@ OBJCONV = @OBJCONV@ TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \ -Wall -W -TARGET_LDFLAGS = -nostdlib @TARGET_LDFLAGS@ +TARGET_LDFLAGS = -nostdlib -static-libgcc @TARGET_LDFLAGS@ TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ TARGET_IMG_LDFLAGS = -nostdlib @TARGET_IMG_LDFLAGS@ TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@ TARGET_OBJ2ELF = @TARGET_OBJ2ELF@ -kernel_img_LDFLAGS = -static-libgcc -lgcc +kernel_img_LDFLAGS = -lgcc EXEEXT = @EXEEXT@ OBJCOPY = @OBJCOPY@ STRIP = @STRIP@ From d31bc9964cd301831055849a21aaa403b297c41b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 01:54:46 +0200 Subject: [PATCH 25/38] migrate kernel.img to elf --- conf/i386-pc.rmk | 5 +- conf/i386-qemu.rmk | 2 +- conf/mips-qemu-mips.rmk | 2 +- conf/mips-yeeloong.rmk | 2 +- conf/sparc64-ieee1275.rmk | 3 +- conf/x86-efi.rmk | 2 +- include/grub/x86_64/efi/boot.h | 0 util/grub-mkrawimage.c | 169 ++++++++++++++++++++++++++++++++- 8 files changed, 172 insertions(+), 13 deletions(-) create mode 100644 include/grub/x86_64/efi/boot.h diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index a5a1b08ea..f2490ba97 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -5,8 +5,7 @@ GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 COMMON_CFLAGS = -mrtd -mregparm=3 # Images. -pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \ - pxeboot.img +pkglib_IMAGES = boot.img cdboot.img diskboot.img lnxboot.img pxeboot.img # For boot.img. boot_img_SOURCES = boot/i386/pc/boot.S @@ -39,6 +38,7 @@ cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00 cdboot_img_FORMAT = binary # For kernel.img. +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/i386/pc/startup.S \ kern/i386/misc.S \ kern/main.c kern/device.c \ @@ -59,7 +59,6 @@ kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) -kernel_img_FORMAT = binary # Utilities. bin_UTILITIES = grub-mkimage diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 664bef12a..923231791 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -19,7 +19,7 @@ grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkrawimage.c_DEPENDENCIES = Makefile -pkglib_IMAGES += kernel.img +pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ kern/i386/coreboot/init.c \ diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index af5b26bec..2f80ab2e3 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -5,7 +5,7 @@ COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 include $(srcdir)/conf/mips.mk -pkglib_IMAGES = kernel.img +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/init.c \ kern/$(target_cpu)/$(target_machine)/init.c \ diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 6a96ddfaf..5ce8ede9d 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -8,7 +8,7 @@ kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h buf include $(srcdir)/conf/mips.mk -pkglib_IMAGES = kernel.img +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/init.c \ kern/$(target_cpu)/$(target_machine)/init.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index f0c9b0db7..8e96599aa 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -5,7 +5,8 @@ COMMON_CFLAGS = -mno-app-regs COMMON_LDFLAGS = -melf64_sparc -mno-relax # Images. -pkglib_IMAGES = boot.img diskboot.img kernel.img +pkglib_IMAGES = boot.img diskboot.img +pkglib_PROGRAMS = kernel.img # For boot.img. boot_img_SOURCES = boot/sparc64/ieee1275/boot.S diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 46957d933..bab561cc4 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -4,7 +4,7 @@ bin_UTILITIES = grub-mkimage # For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c \ util/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile diff --git a/include/grub/x86_64/efi/boot.h b/include/grub/x86_64/efi/boot.h new file mode 100644 index 000000000..e69de29bb diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 20a344d04..dace903a9 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -36,6 +36,7 @@ #include #include #include +#include #define _GNU_SOURCE 1 #include @@ -44,6 +45,8 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define SECTION_ALIGN 1 + #ifdef ENABLE_LZMA #include @@ -97,6 +100,162 @@ compress_kernel (char *kernel_img, size_t kernel_size, #endif /* No lzma compression */ +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +is_text_section (Elf_Shdr *s) +{ + if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == (SHF_EXECINSTR | SHF_ALLOC)); +} + +/* Determine if this section is a data section. This assumes that + BSS is also a data section, since the converter initializes BSS + when producing PE32 to avoid a bug in EFI implementations. */ +static int +is_data_section (Elf_Shdr *s) +{ + if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC); +} + +/* Locate section addresses by merging code sections and data sections + into .text and .data, respectively. Return the array of section + addresses. */ +static Elf_Addr * +locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, + Elf_Half num_sections, const char *strtab, + grub_size_t *exec_size, grub_size_t *kernel_sz) +{ + int i; + Elf_Addr current_address; + Elf_Addr *section_addresses; + Elf_Shdr *s; + + section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); + memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); + + current_address = 0; + + /* .text */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_text_section (s)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address, align); + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address, SECTION_ALIGN); + *exec_size = current_address; + + /* .data */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_data_section (s)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address, align); + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address, SECTION_ALIGN); + *kernel_sz = current_address; + return section_addresses; +} + +/* Return if the ELF header is valid. */ +static int +check_elf_header (Elf_Ehdr *e, size_t size) +{ + if (size < sizeof (*e) + || e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_version != grub_host_to_target32 (EV_CURRENT)) + return 0; + + return 1; +} + +static char * +load_image (const char *kernel_path, grub_size_t *exec_size, + grub_size_t *kernel_sz, grub_size_t total_module_size) +{ + char *kernel_img, *out_img; + const char *strtab; + Elf_Ehdr *e; + Elf_Shdr *sections; + Elf_Addr *section_addresses; + int i; + Elf_Shdr *s; + Elf_Half num_sections; + Elf_Off section_offset; + Elf_Half section_entsize; + grub_size_t kernel_size; + + kernel_size = grub_util_get_image_size (kernel_path); + kernel_img = xmalloc (kernel_size); + grub_util_load_image (kernel_path, kernel_img); + + e = (Elf_Ehdr *) kernel_img; + if (! check_elf_header (e, kernel_size)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_target_to_host32 (e->e_shoff); + section_entsize = grub_target_to_host16 (e->e_shentsize); + num_sections = grub_target_to_host16 (e->e_shnum); + + if (kernel_size < section_offset + section_entsize * num_sections) + grub_util_error ("invalid ELF format"); + + sections = (Elf_Shdr *) (kernel_img + section_offset); + + /* Relocate sections then symbols in the virtual address space. */ + s = (Elf_Shdr *) ((char *) sections + + grub_host_to_target16 (e->e_shstrndx) * section_entsize); + strtab = (char *) e + grub_host_to_target32 (s->sh_offset); + + section_addresses = locate_sections (sections, section_entsize, + num_sections, strtab, + exec_size, kernel_sz); + out_img = xmalloc (*kernel_sz + total_module_size); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_data_section (s) || is_text_section (s)) + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target32 (s->sh_offset), + grub_host_to_target32 (s->sh_size)); + free (kernel_img); + + return out_img; +} + static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, @@ -109,17 +268,15 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ) { char *kernel_img, *core_img; - size_t kernel_size, total_module_size, core_size; + size_t kernel_size, total_module_size, core_size, exec_size; size_t memdisk_size = 0, font_size = 0, config_size = 0, config_size_pure = 0; char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; struct grub_module_info *modinfo; - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); - kernel_size = grub_util_get_image_size (kernel_path); total_module_size = sizeof (struct grub_module_info); @@ -150,8 +307,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_info ("the total module size is 0x%x", total_module_size); - kernel_img = xmalloc (kernel_size + total_module_size); - grub_util_load_image (kernel_path, kernel_img); + kernel_img = load_image (kernel_path, &exec_size, &kernel_size, + total_module_size); if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error (_("prefix is too long")); @@ -237,8 +394,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) = grub_host_to_target32 (total_module_size); #endif +#ifdef GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) = grub_host_to_target32 (kernel_size); +#endif #ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); From e310b81f6cb8c0ad893e08282a49ef42f69d5c9f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 19:38:12 +0200 Subject: [PATCH 26/38] util/grub-mkrawimage.c working on EFI --- util/grub-mkrawimage.c | 690 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 680 insertions(+), 10 deletions(-) diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index dace903a9..30608a932 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,19 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#ifdef GRUB_MACHINE_EFI +#define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT +#define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) +#else #define SECTION_ALIGN 1 +#define VADDR_OFFSET 0 +#endif + +#if GRUB_TARGET_WORDSIZE == 32 +# define grub_target_to_host(val) grub_target_to_host32(val) +#elif GRUB_TARGET_WORDSIZE == 64 +# define grub_target_to_host(val) grub_target_to_host64(val) +#endif #ifdef ENABLE_LZMA #include @@ -100,13 +113,436 @@ compress_kernel (char *kernel_img, size_t kernel_size, #endif /* No lzma compression */ +#ifdef GRUB_MACHINE_EFI + +/* Relocate symbols; note that this function overwrites the symbol table. + Return the address of a start symbol. */ +static Elf_Addr +relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Shdr *symtab_section, Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Addr start_address = 0; + Elf_Sym *sym; + Elf_Word i; + Elf_Shdr *strtab_section; + const char *strtab; + + strtab_section + = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (symtab_section->sh_link) + * section_entsize)); + strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); + + symtab_size = grub_target_to_host32 (symtab_section->sh_size); + sym_size = grub_target_to_host32 (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host32 (symtab_section->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + { + Elf_Section index; + const char *name; + + name = strtab + grub_target_to_host32 (sym->st_name); + + index = grub_target_to_host16 (sym->st_shndx); + if (index == STN_ABS) + { + continue; + } + else if ((index == STN_UNDEF)) + { + if (sym->st_name) + grub_util_error ("undefined symbol %s", name); + else + continue; + } + else if (index >= num_sections) + grub_util_error ("section %d does not exist", index); + + sym->st_value = (grub_target_to_host32 (sym->st_value) + + section_addresses[index]); + grub_util_info ("locating %s at 0x%x", name, sym->st_value); + + if (! start_address) + if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) + start_address = sym->st_value; + } + + return start_address; +} + +/* Return the address of a symbol at the index I in the section S. */ +static Elf_Addr +get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) +{ + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host32 (s->sh_offset) + + i * grub_target_to_host32 (s->sh_entsize)); + return sym->st_value; +} + +/* Return the address of a modified value. */ +static Elf_Addr * +get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) +{ + return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); +} + +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static void +relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab) +{ + Elf_Half i; + Elf_Shdr *s; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Word target_section_index; + Elf_Addr target_section_addr; + Elf_Shdr *target_section; + Elf_Word j; + + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (s->sh_link) + * section_entsize)); + target_section_index = grub_target_to_host32 (s->sh_info); + target_section_addr = section_addresses[target_section_index]; + target_section = (Elf_Shdr *) ((char *) sections + + (target_section_index + * section_entsize)); + + grub_util_info ("dealing with the relocation section %s for %s", + strtab + grub_target_to_host32 (s->sh_name), + strtab + grub_target_to_host32 (target_section->sh_name)); + + rtab_size = grub_target_to_host32 (s->sh_size); + r_size = grub_target_to_host32 (s->sh_entsize); + rtab_offset = grub_target_to_host32 (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr sym_addr; + Elf_Addr *target; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + target = get_target_address (e, target_section, offset); + info = grub_target_to_host (r->r_info); + sym_addr = get_symbol_address (e, symtab_section, + ELF_R_SYM (info)); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + r->r_addend : 0; + + switch (ELF_R_TYPE (info)) + { +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + case R_386_NONE: + break; + + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - VADDR_OFFSET); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + +#else + + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", + *target, offset); + break; + + case R_X86_64_PC32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - VADDR_OFFSET); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + +#endif + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + } + } +} + +struct fixup_block_list +{ + struct fixup_block_list *next; + int state; + struct grub_pe32_fixup_block b; +}; + +/* Add a PE32's fixup entry for a relocation. Return the resulting address + after having written to the file OUT. */ +Elf_Addr +add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address) +{ + struct grub_pe32_fixup_block *b; + + b = &((*cblock)->b); + + /* First, check if it is necessary to write out the current block. */ + if ((*cblock)->state) + { + if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) + { + grub_uint32_t size; + + if (flush) + { + /* Add as much padding as necessary to align the address + with a section boundary. */ + Elf_Addr next_address; + unsigned padding_size; + size_t index; + + next_address = current_address + b->block_size; + padding_size = ((ALIGN_UP (next_address, SECTION_ALIGN) + - next_address) + >> 1); + index = ((b->block_size - sizeof (*b)) >> 1); + grub_util_info ("adding %d padding fixup entries", padding_size); + while (padding_size--) + { + b->entries[index++] = 0; + b->block_size += 2; + } + } + else if (b->block_size & (8 - 1)) + { + /* If not aligned with a 32-bit boundary, add + a padding entry. */ + size_t index; + + grub_util_info ("adding a padding fixup entry"); + index = ((b->block_size - sizeof (*b)) >> 1); + b->entries[index] = 0; + b->block_size += 2; + } + + /* Flush it. */ + grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", + b->block_size, b->page_rva); + size = b->block_size; + current_address += size; + b->page_rva = grub_host_to_target32 (b->page_rva); + b->block_size = grub_host_to_target32 (b->block_size); + (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); + memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); + *cblock = (*cblock)->next; + } + } + + b = &((*cblock)->b); + + if (! flush) + { + grub_uint16_t entry; + size_t index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! (*cblock)->state) + { + (*cblock)->state = 1; + + /* The spec does not mention the requirement of a Page RVA. + Here, align the address with a 4K boundary for safety. */ + b->page_rva = (addr & ~(0x1000 - 1)); + b->block_size = sizeof (*b); + } + + /* Sanity check. */ + if (b->block_size >= sizeof (*b) + 2 * 0x1000) + grub_util_error ("too many fixup entries"); + + /* Add a new entry. */ + index = ((b->block_size - sizeof (*b)) >> 1); + entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); + b->entries[index] = grub_host_to_target16 (entry); + b->block_size += 2; + } + + return current_address; +} + +/* Make a .reloc section. */ +static Elf_Addr +make_reloc_section (Elf_Ehdr *e, void **out, + Elf_Addr *section_addresses, Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab) +{ + Elf_Half i; + Elf_Shdr *s; + struct fixup_block_list *lst, *lst0; + Elf_Addr current_address = 0; + + lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); + memset (lst, 0, sizeof (*lst) + 2 * 0x1000); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || + (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) + { + Elf_Rel *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Addr section_address; + Elf_Word j; + + grub_util_info ("translating the relocation section %s", + strtab + grub_le_to_cpu32 (s->sh_name)); + + rtab_size = grub_le_to_cpu32 (s->sh_size); + r_size = grub_le_to_cpu32 (s->sh_entsize); + rtab_offset = grub_le_to_cpu32 (s->sh_offset); + num_rs = rtab_size / r_size; + + section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; + + for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rel *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + + offset = grub_le_to_cpu32 (r->r_offset); + info = grub_le_to_cpu32 (r->r_info); + + /* Necessary to relocate only absolute addresses. */ +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + if (ELF_R_TYPE (info) == R_386_32) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address); + } +#else + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address); + } +#endif + } + } + + current_address = add_fixup_entry (&lst, 0, 0, 1, current_address); + + { + grub_uint8_t *ptr; + ptr = *out = xmalloc (current_address); + for (lst = lst0; lst; lst = lst->next) + if (lst->state) + { + memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); + ptr += grub_target_to_host32 (lst->b.block_size); + } + if (current_address + *out != ptr) + { + grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, + current_address); + } + } + + return current_address; +} + +#endif + /* Determine if this section is a text section. Return false if this section is not allocated. */ static int is_text_section (Elf_Shdr *s) { +#ifndef GRUB_MACHINE_EFI if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; +#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -117,8 +553,10 @@ is_text_section (Elf_Shdr *s) static int is_data_section (Elf_Shdr *s) { +#ifndef GRUB_MACHINE_EFI if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; +#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -151,7 +589,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address, align); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -159,7 +598,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address, SECTION_ALIGN); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; *exec_size = current_address; /* .data */ @@ -172,7 +612,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address, align); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -180,7 +621,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address, SECTION_ALIGN); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; *kernel_sz = current_address; return section_addresses; } @@ -203,19 +645,25 @@ check_elf_header (Elf_Ehdr *e, size_t size) static char * load_image (const char *kernel_path, grub_size_t *exec_size, - grub_size_t *kernel_sz, grub_size_t total_module_size) + grub_size_t *kernel_sz, grub_size_t *bss_size, + grub_size_t total_module_size, Elf_Addr *start, + void **reloc_section, grub_size_t *reloc_size) { char *kernel_img, *out_img; const char *strtab; Elf_Ehdr *e; Elf_Shdr *sections; Elf_Addr *section_addresses; + Elf_Addr *section_vaddresses; int i; Elf_Shdr *s; Elf_Half num_sections; Elf_Off section_offset; Elf_Half section_entsize; grub_size_t kernel_size; + Elf_Shdr *symtab_section; + + *start = 0; kernel_size = grub_util_get_image_size (kernel_path); kernel_img = xmalloc (kernel_size); @@ -242,15 +690,93 @@ load_image (const char *kernel_path, grub_size_t *exec_size, section_addresses = locate_sections (sections, section_entsize, num_sections, strtab, exec_size, kernel_sz); + +#ifdef GRUB_MACHINE_EFI + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + VADDR_OFFSET; + +#if 0 + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) + { + symtab_section = s; + break; + } + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = relocate_symbols (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + relocate_addresses (e, sections, section_addresses, section_entsize, + num_sections, strtab); + + *reloc_size = make_reloc_section (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab); + + } +#else + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; +#endif + out_img = xmalloc (*kernel_sz + total_module_size); for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) if (is_data_section (s) || is_text_section (s)) - memcpy (out_img + section_addresses[i], - kernel_img + grub_host_to_target32 (s->sh_offset), - grub_host_to_target32 (s->sh_size)); + { + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + memset (out_img + section_addresses[i], 0, + grub_host_to_target32 (s->sh_size)); + else + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target32 (s->sh_offset), + grub_host_to_target32 (s->sh_size)); + } free (kernel_img); return out_img; @@ -274,6 +800,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t offset; struct grub_util_path_list *path_list, *p, *next; struct grub_module_info *modinfo; + grub_size_t bss_size; + Elf_Addr start_address; + void *rel_section; + grub_size_t reloc_size; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); @@ -307,8 +837,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_info ("the total module size is 0x%x", total_module_size); - kernel_img = load_image (kernel_path, &exec_size, &kernel_size, - total_module_size); + kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size); if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error (_("prefix is too long")); @@ -456,6 +987,145 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_img); free (boot_path); } +#elif defined(GRUB_MACHINE_EFI) + { + void *pe_img; + size_t pe_size; + struct grub_pe32_header *header; + struct grub_pe32_coff_header *c; + struct grub_pe32_optional_header *o; + struct grub_pe32_section_table *text_section, *data_section; + struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + SECTION_ALIGN); + int reloc_addr = ALIGN_UP (header_size + core_size, SECTION_ALIGN); + + pe_size = ALIGN_UP (reloc_addr + reloc_size, SECTION_ALIGN); + pe_img = xmalloc (reloc_addr + reloc_size); + memset (pe_img, 0, header_size); + memcpy (pe_img + header_size, core_img, core_size); + memcpy (pe_img + reloc_addr, rel_section, reloc_size); + header = pe_img; + + /* The magic. */ + memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); + memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + + /* The COFF file header. */ + c = &header->coff_header; +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); +#else + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); +#endif + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (time (0)); + c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + | GRUB_PE32_32BIT_MACHINE +#endif + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + o = &header->optional_header; + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + o->data_base = grub_host_to_target32 (header_size + exec_size); +#endif + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (SECTION_ALIGN); + o->file_alignment = grub_host_to_target32 (SECTION_ALIGN); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + + /* The sections. */ + text_section = (struct grub_pe32_section_table *) (header + 1); + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_ALIGN_64BYTES); + + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); + data_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); + +#if 0 + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); +#endif + + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); + mods_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); + + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } #elif defined(GRUB_MACHINE_QEMU) { char *rom_img; From 287c2f24265a5e1ca5c4fe5a6322e9f54b4bb996 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 19:39:22 +0200 Subject: [PATCH 27/38] Remove efi/grub-mkimage.c --- util/i386/efi/grub-mkimage.c | 1112 ---------------------------------- 1 file changed, 1112 deletions(-) delete mode 100644 util/i386/efi/grub-mkimage.c diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c deleted file mode 100644 index f8c0f152e..000000000 --- a/util/i386/efi/grub-mkimage.c +++ /dev/null @@ -1,1112 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2005,2006,2007,2008,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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "progname.h" - -#if GRUB_TARGET_WORDSIZE == 32 -# define grub_le_to_cpu(val) grub_le_to_cpu32(val) -#elif GRUB_TARGET_WORDSIZE == 64 -# define grub_le_to_cpu(val) grub_le_to_cpu64(val) -#endif - -static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - -static inline Elf_Addr -align_address (Elf_Addr addr, unsigned alignment) -{ - return (addr + alignment - 1) & ~(alignment - 1); -} - -static inline Elf_Addr -align_pe32_section (Elf_Addr addr) -{ - return align_address (addr, GRUB_PE32_SECTION_ALIGNMENT); -} - -/* Read the whole kernel image. Return the pointer to a read image, - and store the size in bytes in *SIZE. */ -static char * -read_kernel_image (const char *dir, size_t *size) -{ - char *kernel_image; - char *kernel_path; - - kernel_path = grub_util_get_path (dir, "kernel.img"); - *size = grub_util_get_image_size (kernel_path); - kernel_image = grub_util_read_image (kernel_path); - free (kernel_path); - - return kernel_image; -} - -/* Return if the ELF header is valid. */ -static int -check_elf_header (Elf_Ehdr *e, size_t size) -{ - if (size < sizeof (*e) - || e->e_ident[EI_MAG0] != ELFMAG0 - || e->e_ident[EI_MAG1] != ELFMAG1 - || e->e_ident[EI_MAG2] != ELFMAG2 - || e->e_ident[EI_MAG3] != ELFMAG3 - || e->e_ident[EI_VERSION] != EV_CURRENT - || e->e_version != grub_cpu_to_le32 (EV_CURRENT) - || ((e->e_ident[EI_CLASS] != ELFCLASS32) && - (e->e_ident[EI_CLASS] != ELFCLASS64)) - || e->e_ident[EI_DATA] != ELFDATA2LSB - || ((e->e_machine != grub_cpu_to_le16 (EM_386)) && - (e->e_machine != grub_cpu_to_le16 (EM_X86_64)))) - return 0; - - return 1; -} - -/* Return the starting address right after the header, - aligned by the section alignment. Allocate 4 section tables for - .text, .data, .reloc, and mods. */ -static Elf_Addr -get_starting_section_address (void) -{ - return align_pe32_section (sizeof (struct grub_pe32_header) - + 4 * sizeof (struct grub_pe32_section_table)); -} - -/* Determine if this section is a text section. Return false if this - section is not allocated. */ -static int -is_text_section (Elf_Shdr *s) -{ - return ((s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC)) - == grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC)); -} - -/* Determine if this section is a data section. This assumes that - BSS is also a data section, since the converter initializes BSS - when producing PE32 to avoid a bug in EFI implementations. */ -static int -is_data_section (Elf_Shdr *s) -{ - return (s->sh_flags & grub_cpu_to_le32 (SHF_ALLOC) - && ! (s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR))); -} - -/* Locate section addresses by merging code sections and data sections - into .text and .data, respectively. Return the array of section - addresses. */ -static Elf_Addr * -locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, - Elf_Half num_sections, const char *strtab) -{ - int i; - Elf_Addr current_address; - Elf_Addr *section_addresses; - Elf_Shdr *s; - - section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); - memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); - - current_address = get_starting_section_address (); - - /* .text */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - current_address = align_address (current_address, align); - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_le_to_cpu32 (s->sh_size); - } - - current_address = align_pe32_section (current_address); - - /* .data */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - current_address = align_address (current_address, align); - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_le_to_cpu32 (s->sh_size); - } - - return section_addresses; -} - -/* Return the symbol table section, if any. */ -static Elf_Shdr * -find_symtab_section (Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections) -{ - int i; - Elf_Shdr *s; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_cpu_to_le32 (SHT_SYMTAB)) - return s; - - return 0; -} - -/* Return the address of the string table. */ -static const char * -find_strtab (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Half section_entsize) -{ - Elf_Shdr *s; - char *strtab; - - s = (Elf_Shdr *) ((char *) sections - + grub_le_to_cpu16 (e->e_shstrndx) * section_entsize); - strtab = (char *) e + grub_le_to_cpu32 (s->sh_offset); - return strtab; -} - -/* Relocate symbols; note that this function overwrites the symbol table. - Return the address of a start symbol. */ -static Elf_Addr -relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Shdr *symtab_section, Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections) -{ - Elf_Word symtab_size, sym_size, num_syms; - Elf_Off symtab_offset; - Elf_Addr start_address = 0; - Elf_Sym *sym; - Elf_Word i; - Elf_Shdr *strtab_section; - const char *strtab; - - strtab_section - = (Elf_Shdr *) ((char *) sections - + (grub_le_to_cpu32 (symtab_section->sh_link) - * section_entsize)); - strtab = (char *) e + grub_le_to_cpu32 (strtab_section->sh_offset); - - symtab_size = grub_le_to_cpu32 (symtab_section->sh_size); - sym_size = grub_le_to_cpu32 (symtab_section->sh_entsize); - symtab_offset = grub_le_to_cpu32 (symtab_section->sh_offset); - num_syms = symtab_size / sym_size; - - for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); - i < num_syms; - i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) - { - Elf_Section index; - const char *name; - - name = strtab + grub_le_to_cpu32 (sym->st_name); - - index = grub_le_to_cpu16 (sym->st_shndx); - if (index == STN_ABS) - { - continue; - } - else if ((index == STN_UNDEF)) - { - if (sym->st_name) - grub_util_error ("undefined symbol %s", name); - else - continue; - } - else if (index >= num_sections) - grub_util_error ("section %d does not exist", index); - - sym->st_value = (grub_le_to_cpu32 (sym->st_value) - + section_addresses[index]); - grub_util_info ("locating %s at 0x%x", name, sym->st_value); - - if (! start_address) - if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) - start_address = sym->st_value; - } - - return start_address; -} - -/* Return the address of a symbol at the index I in the section S. */ -static Elf_Addr -get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) -{ - Elf_Sym *sym; - - sym = (Elf_Sym *) ((char *) e - + grub_le_to_cpu32 (s->sh_offset) - + i * grub_le_to_cpu32 (s->sh_entsize)); - return sym->st_value; -} - -/* Return the address of a modified value. */ -static Elf_Addr * -get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) -{ - return (Elf_Addr *) ((char *) e + grub_le_to_cpu32 (s->sh_offset) + offset); -} - -/* Deal with relocation information. This function relocates addresses - within the virtual address space starting from 0. So only relative - addresses can be fully resolved. Absolute addresses must be relocated - again by a PE32 relocator when loaded. */ -static void -relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || - (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) - { - Elf_Rela *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Shdr *symtab_section; - Elf_Word target_section_index; - Elf_Addr target_section_addr; - Elf_Shdr *target_section; - Elf_Word j; - - symtab_section = (Elf_Shdr *) ((char *) sections - + (grub_le_to_cpu32 (s->sh_link) - * section_entsize)); - target_section_index = grub_le_to_cpu32 (s->sh_info); - target_section_addr = section_addresses[target_section_index]; - target_section = (Elf_Shdr *) ((char *) sections - + (target_section_index - * section_entsize)); - - grub_util_info ("dealing with the relocation section %s for %s", - strtab + grub_le_to_cpu32 (s->sh_name), - strtab + grub_le_to_cpu32 (target_section->sh_name)); - - rtab_size = grub_le_to_cpu32 (s->sh_size); - r_size = grub_le_to_cpu32 (s->sh_entsize); - rtab_offset = grub_le_to_cpu32 (s->sh_offset); - num_rs = rtab_size / r_size; - - for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rela *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - Elf_Addr sym_addr; - Elf_Addr *target; - Elf_Addr addend; - - offset = grub_le_to_cpu (r->r_offset); - target = get_target_address (e, target_section, offset); - info = grub_le_to_cpu (r->r_info); - sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info)); - - addend = (s->sh_type == grub_cpu_to_le32 (SHT_RELA)) ? - r->r_addend : 0; - - switch (ELF_R_TYPE (info)) - { -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - case R_386_NONE: - break; - - case R_386_32: - /* This is absolute. */ - *target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - - case R_386_PC32: - /* This is relative. */ - *target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target) - + addend + sym_addr - - target_section_addr - offset); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - -#else - - case R_X86_64_NONE: - break; - - case R_X86_64_64: - *target = grub_cpu_to_le64 (grub_le_to_cpu64 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", - *target, offset); - break; - - case R_X86_64_PC32: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_cpu_to_le64 (grub_le_to_cpu32 (*t32) - + addend + sym_addr - - target_section_addr - offset); - grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - - case R_X86_64_32: - case R_X86_64_32S: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_cpu_to_le64 (grub_le_to_cpu32 (*t32) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - -#endif - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } - } - } -} - -void -write_padding (FILE *out, size_t size) -{ - size_t i; - - for (i = 0; i < size; i++) - if (fputc (0, out) == EOF) - grub_util_error ("padding failed"); -} - -/* Add a PE32's fixup entry for a relocation. Return the resulting address - after having written to the file OUT. */ -Elf_Addr -add_fixup_entry (struct grub_pe32_fixup_block **block, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address, - FILE *out) -{ - struct grub_pe32_fixup_block *b = *block; - - /* First, check if it is necessary to write out the current block. */ - if (b) - { - if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) - { - grub_uint32_t size; - - if (flush) - { - /* Add as much padding as necessary to align the address - with a section boundary. */ - Elf_Addr next_address; - unsigned padding_size; - size_t index; - - next_address = current_address + b->block_size; - padding_size = ((align_pe32_section (next_address) - - next_address) - >> 1); - index = ((b->block_size - sizeof (*b)) >> 1); - grub_util_info ("adding %d padding fixup entries", padding_size); - while (padding_size--) - { - b->entries[index++] = 0; - b->block_size += 2; - } - } - else if (b->block_size & (8 - 1)) - { - /* If not aligned with a 32-bit boundary, add - a padding entry. */ - size_t index; - - grub_util_info ("adding a padding fixup entry"); - index = ((b->block_size - sizeof (*b)) >> 1); - b->entries[index] = 0; - b->block_size += 2; - } - - /* Flush it. */ - grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", - b->block_size, b->page_rva); - size = b->block_size; - current_address += size; - b->page_rva = grub_cpu_to_le32 (b->page_rva); - b->block_size = grub_cpu_to_le32 (b->block_size); - if (fwrite (b, size, 1, out) != 1) - grub_util_error ("write failed"); - free (b); - *block = b = 0; - } - } - - if (! flush) - { - grub_uint16_t entry; - size_t index; - - /* If not allocated yet, allocate a block with enough entries. */ - if (! b) - { - *block = b = xmalloc (sizeof (*b) + 2 * 0x1000); - - /* The spec does not mention the requirement of a Page RVA. - Here, align the address with a 4K boundary for safety. */ - b->page_rva = (addr & ~(0x1000 - 1)); - b->block_size = sizeof (*b); - } - - /* Sanity check. */ - if (b->block_size >= sizeof (*b) + 2 * 0x1000) - grub_util_error ("too many fixup entries"); - - /* Add a new entry. */ - index = ((b->block_size - sizeof (*b)) >> 1); - entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); - b->entries[index] = grub_cpu_to_le16 (entry); - b->block_size += 2; - } - - return current_address; -} - -/* Write out zeros to make space for the header. */ -static Elf_Addr -make_header_space (FILE *out) -{ - Elf_Addr addr; - - addr = get_starting_section_address (); - write_padding (out, addr); - - return addr; -} - -/* Write text sections. */ -static Elf_Addr -write_text_sections (FILE *out, Elf_Addr current_address, - Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - Elf_Addr addr; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - Elf_Word size = grub_le_to_cpu32 (s->sh_size); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - { - addr = align_address (current_address, align); - if (current_address != addr) - { - grub_util_info ("padding %d bytes for the ELF section alignment", - addr - current_address); - write_padding (out, addr - current_address); - current_address = addr; - } - } - - grub_util_info ("writing the text section %s at 0x%x", - name, current_address); - - if (fwrite ((char *) e + offset, size, 1, out) != 1) - grub_util_error ("write failed"); - - current_address += size; - } - - addr = align_pe32_section (current_address); - if (addr != current_address) - { - grub_util_info ("padding %d bytes for the PE32 section alignment", - addr - current_address); - write_padding (out, addr - current_address); - } - - return addr; -} - -/* Write data sections. */ -static Elf_Addr -write_data_sections (FILE *out, Elf_Addr current_address, - Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - Elf_Addr addr; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - Elf_Word size = grub_le_to_cpu32 (s->sh_size); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - { - addr = align_address (current_address, align); - if (current_address != addr) - { - grub_util_info ("padding %d bytes for the ELF section alignment", - addr - current_address); - write_padding (out, addr - current_address); - current_address = addr; - } - } - - grub_util_info ("writing the data section %s at 0x%x", - name, current_address); - - if (s->sh_type == grub_cpu_to_le32 (SHT_NOBITS)) - write_padding (out, size); - else - if (fwrite ((char *) e + offset, size, 1, out) != 1) - grub_util_error ("write failed"); - - current_address += size; - } - - addr = align_pe32_section (current_address); - if (addr != current_address) - { - grub_util_info ("padding %d bytes for the PE32 section alignment", - addr - current_address); - write_padding (out, addr - current_address); - } - - return addr; -} - -/* Write modules. */ -static Elf_Addr -make_mods_section (FILE *out, Elf_Addr current_address, - const char *dir, char *mods[]) -{ - struct grub_util_path_list *path_list; - grub_size_t total_module_size; - struct grub_util_path_list *p; - struct grub_module_info modinfo; - Elf_Addr addr; - - memset (&modinfo, 0, sizeof (modinfo)); - - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); - - total_module_size = sizeof (struct grub_module_info); - for (p = path_list; p; p = p->next) - { - total_module_size += (grub_util_get_image_size (p->name) - + sizeof (struct grub_module_header)); - } - - grub_util_info ("the total module size is 0x%x", total_module_size); - - modinfo.magic = grub_cpu_to_le32 (GRUB_MODULE_MAGIC); - modinfo.offset = grub_cpu_to_le32 (sizeof (modinfo)); - modinfo.size = grub_cpu_to_le32 (total_module_size); - - if (fwrite (&modinfo, sizeof (modinfo), 1, out) != 1) - grub_util_error ("write failed"); - - for (p = path_list; p; p = p->next) - { - struct grub_module_header header; - size_t mod_size; - char *mod_image; - - memset (&header, 0, sizeof (header)); - - grub_util_info ("adding module %s", p->name); - - mod_size = grub_util_get_image_size (p->name); - header.type = OBJ_TYPE_ELF; - header.size = grub_host_to_target32 (mod_size + sizeof (header)); - - mod_image = grub_util_read_image (p->name); - - if (fwrite (&header, sizeof (header), 1, out) != 1 - || fwrite (mod_image, mod_size, 1, out) != 1) - grub_util_error ("write failed"); - - free (mod_image); - } - - for (p = path_list; p; ) - { - struct grub_util_path_list *q; - - q = p->next; - free (p); - p = q; - } - - current_address += total_module_size; - - addr = align_pe32_section (current_address); - if (addr != current_address) - { - grub_util_info ("padding %d bytes for the PE32 section alignment", - addr - current_address); - write_padding (out, addr - current_address); - } - - return addr; -} - -/* Make a .reloc section. */ -static Elf_Addr -make_reloc_section (FILE *out, Elf_Addr current_address, Elf_Ehdr *e, - Elf_Addr *section_addresses, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - struct grub_pe32_fixup_block *fixup_block = 0; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || - (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) - { - Elf_Rel *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Addr section_address; - Elf_Word j; - - grub_util_info ("translating the relocation section %s", - strtab + grub_le_to_cpu32 (s->sh_name)); - - rtab_size = grub_le_to_cpu32 (s->sh_size); - r_size = grub_le_to_cpu32 (s->sh_entsize); - rtab_offset = grub_le_to_cpu32 (s->sh_offset); - num_rs = rtab_size / r_size; - - section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; - - for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rel *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - - offset = grub_le_to_cpu32 (r->r_offset); - info = grub_le_to_cpu32 (r->r_info); - - /* Necessary to relocate only absolute addresses. */ -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - if (ELF_R_TYPE (info) == R_386_32) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%x", addr); - current_address = add_fixup_entry (&fixup_block, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address, - out); - } -#else - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) - { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&fixup_block, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address, - out); - } -#endif - } - } - - current_address = add_fixup_entry (&fixup_block, 0, 0, 1, - current_address, out); - - return current_address; -} - -/* Create the header. */ -static void -make_header (FILE *out, Elf_Addr text_address, Elf_Addr data_address, - Elf_Addr mods_address, Elf_Addr reloc_address, - Elf_Addr end_address, Elf_Addr start_address) -{ - struct grub_pe32_header header; - struct grub_pe32_coff_header *c; - struct grub_pe32_optional_header *o; - struct grub_pe32_section_table text_section, data_section; - struct grub_pe32_section_table mods_section, reloc_section; - - /* The magic. */ - memset (&header, 0, sizeof (header)); - memcpy (header.msdos_stub, stub, sizeof (header.msdos_stub)); - memcpy (header.signature, "PE\0\0", sizeof (header.signature)); - - /* The COFF file header. */ - c = &header.coff_header; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_I386); -#else - c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_X86_64); -#endif - - c->num_sections = grub_cpu_to_le16 (4); - c->time = grub_cpu_to_le32 (time (0)); - c->optional_header_size = grub_cpu_to_le16 (sizeof (header.optional_header)); - c->characteristics = grub_cpu_to_le16 (GRUB_PE32_EXECUTABLE_IMAGE - | GRUB_PE32_LINE_NUMS_STRIPPED -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - | GRUB_PE32_32BIT_MACHINE -#endif - | GRUB_PE32_LOCAL_SYMS_STRIPPED - | GRUB_PE32_DEBUG_STRIPPED); - - /* The PE Optional header. */ - o = &header.optional_header; - o->magic = grub_cpu_to_le16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_cpu_to_le32 (data_address - text_address); - o->data_size = grub_cpu_to_le32 (reloc_address - data_address); - o->bss_size = 0; - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (text_address); -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - o->data_base = grub_cpu_to_le32 (data_address); -#endif - o->image_base = 0; - o->section_alignment = grub_cpu_to_le32 (GRUB_PE32_SECTION_ALIGNMENT); - o->file_alignment = grub_cpu_to_le32 (GRUB_PE32_FILE_ALIGNMENT); - o->image_size = grub_cpu_to_le32 (end_address); - o->header_size = grub_cpu_to_le32 (text_address); - o->subsystem = grub_cpu_to_le16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); - - /* Do these really matter? */ - o->stack_reserve_size = grub_cpu_to_le32 (0x10000); - o->stack_commit_size = grub_cpu_to_le32 (0x10000); - o->heap_reserve_size = grub_cpu_to_le32 (0x10000); - o->heap_commit_size = grub_cpu_to_le32 (0x10000); - - o->num_data_directories = grub_cpu_to_le32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - - o->base_relocation_table.rva = grub_cpu_to_le32 (reloc_address); - o->base_relocation_table.size = grub_cpu_to_le32 (end_address - - reloc_address); - - /* The sections. */ - memset (&text_section, 0, sizeof (text_section)); - strcpy (text_section.name, ".text"); - text_section.virtual_size = grub_cpu_to_le32 (data_address - text_address); - text_section.virtual_address = grub_cpu_to_le32 (text_address); - text_section.raw_data_size = grub_cpu_to_le32 (data_address - text_address); - text_section.raw_data_offset = grub_cpu_to_le32 (text_address); - text_section.characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ); - - memset (&data_section, 0, sizeof (data_section)); - strcpy (data_section.name, ".data"); - data_section.virtual_size = grub_cpu_to_le32 (mods_address - data_address); - data_section.virtual_address = grub_cpu_to_le32 (data_address); - data_section.raw_data_size = grub_cpu_to_le32 (mods_address - data_address); - data_section.raw_data_offset = grub_cpu_to_le32 (data_address); - data_section.characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - - memset (&mods_section, 0, sizeof (mods_section)); - strcpy (mods_section.name, "mods"); - mods_section.virtual_size = grub_cpu_to_le32 (reloc_address - mods_address); - mods_section.virtual_address = grub_cpu_to_le32 (mods_address); - mods_section.raw_data_size = grub_cpu_to_le32 (reloc_address - mods_address); - mods_section.raw_data_offset = grub_cpu_to_le32 (mods_address); - mods_section.characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - - memset (&reloc_section, 0, sizeof (reloc_section)); - strcpy (reloc_section.name, ".reloc"); - reloc_section.virtual_size = grub_cpu_to_le32 (end_address - reloc_address); - reloc_section.virtual_address = grub_cpu_to_le32 (reloc_address); - reloc_section.raw_data_size = grub_cpu_to_le32 (end_address - reloc_address); - reloc_section.raw_data_offset = grub_cpu_to_le32 (reloc_address); - reloc_section.characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_DISCARDABLE - | GRUB_PE32_SCN_MEM_READ); - - /* Write them out. */ - if (fseeko (out, 0, SEEK_SET) < 0) - grub_util_error ("seek failed"); - - if (fwrite (&header, sizeof (header), 1, out) != 1 - || fwrite (&text_section, sizeof (text_section), 1, out) != 1 - || fwrite (&data_section, sizeof (data_section), 1, out) != 1 - || fwrite (&mods_section, sizeof (mods_section), 1, out) != 1 - || fwrite (&reloc_section, sizeof (reloc_section), 1, out) != 1) - grub_util_error ("write failed"); -} - -/* Convert an ELF relocatable object into an EFI Application (PE32). */ -void -convert_elf (const char *dir, char *prefix, FILE *out, char *mods[]) -{ - char *kernel_image; - size_t kernel_size; - const char *strtab; - Elf_Ehdr *e; - Elf_Shdr *sections; - Elf_Off section_offset; - Elf_Half section_entsize; - Elf_Half num_sections; - Elf_Addr *section_addresses; - Elf_Shdr *symtab_section; - Elf_Addr start_address; - Elf_Addr text_address, data_address, reloc_address, mods_address; - Elf_Addr end_address; - Elf_Shdr *s; - int i; - - /* Get the kernel image and check the format. */ - kernel_image = read_kernel_image (dir, &kernel_size); - e = (Elf_Ehdr *) kernel_image; - if (! check_elf_header (e, kernel_size)) - grub_util_error ("invalid ELF header"); - - section_offset = grub_cpu_to_le32 (e->e_shoff); - section_entsize = grub_cpu_to_le16 (e->e_shentsize); - num_sections = grub_cpu_to_le16 (e->e_shnum); - - if (kernel_size < section_offset + section_entsize * num_sections) - grub_util_error ("invalid ELF format"); - - sections = (Elf_Shdr *) (kernel_image + section_offset); - strtab = find_strtab (e, sections, section_entsize); - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error ("prefix too long"); - - strcpy (kernel_image + offset + GRUB_KERNEL_MACHINE_PREFIX, prefix); - break; - } - - /* Relocate sections then symbols in the virtual address space. */ - section_addresses = locate_sections (sections, section_entsize, - num_sections, strtab); - - symtab_section = find_symtab_section (sections, - section_entsize, num_sections); - if (! symtab_section) - grub_util_error ("no symbol table"); - - start_address = relocate_symbols (e, sections, symtab_section, - section_addresses, section_entsize, - num_sections); - if (start_address == 0) - grub_util_error ("start symbol is not defined"); - - /* Resolve addresses in the virtual address space. */ - relocate_addresses (e, sections, section_addresses, section_entsize, - num_sections, strtab); - - /* Generate a PE32 image file. The strategy is to dump binary data first, - then fill up the header. */ - text_address = make_header_space (out); - data_address = write_text_sections (out, text_address, e, sections, - section_entsize, num_sections, - strtab); - mods_address = write_data_sections (out, data_address, e, sections, - section_entsize, num_sections, - strtab); - reloc_address = make_mods_section (out, mods_address, dir, mods); - end_address = make_reloc_section (out, reloc_address, e, section_addresses, - sections, section_entsize, num_sections, - strtab); - make_header (out, text_address, data_address, mods_address, - reloc_address, end_address, start_address); - - /* Clean up. */ - free (section_addresses); - free (kernel_image); -} - -static struct option options[] = - { - {"directory", required_argument, 0, 'd'}, - {"prefix", required_argument, 0, 'p'}, - {"output", required_argument, 0, 'o'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - { 0, 0, 0, 0 } - }; - -static void -usage (int status) -{ - if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s -o FILE [OPTION]... [MODULES]\n\ -\n\ -Make a bootable image of GRUB.\n\ -\n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ - -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ - -o, --output=FILE output a generated image to FILE\n\ - -h, --help display this message and exit\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n\ -", program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); - - exit (status); -} - -int -main (int argc, char *argv[]) -{ - FILE *fp; - char *output = NULL; - char *dir = NULL; - char *prefix = NULL; - - program_name = "grub-mkimage"; - - while (1) - { - int c = getopt_long (argc, argv, "d:p:o:hVv", options, 0); - if (c == -1) - break; - - switch (c) - { - case 'd': - if (dir) - free (dir); - dir = xstrdup (optarg); - break; - case 'h': - usage (0); - break; - case 'o': - if (output) - free (output); - output = xstrdup (optarg); - break; - case 'p': - if (prefix) - free (prefix); - prefix = xstrdup (optarg); - break; - case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); - return 0; - case 'v': - verbosity++; - break; - default: - usage (1); - break; - } - } - - if (! output) - usage (1); - - fp = fopen (output, "wb"); - if (! fp) - grub_util_error ("cannot open %s", output); - - convert_elf (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind); - - fclose (fp); - - return 0; -} From 2fa6a5dd4431588f98790e052858f3b851e34bac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 19:41:51 +0200 Subject: [PATCH 28/38] rename grub-mkrawimage to grub-mkimage --- conf/i386-pc.rmk | 4 ++-- conf/i386-qemu.rmk | 4 ++-- conf/mips.rmk | 4 ++-- conf/sparc64-ieee1275.rmk | 2 +- conf/x86-efi.rmk | 2 +- util/{grub-mkrawimage.c => grub-mkimage.c} | 0 6 files changed, 8 insertions(+), 8 deletions(-) rename util/{grub-mkrawimage.c => grub-mkimage.c} (100%) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index f2490ba97..2dd874e13 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -65,10 +65,10 @@ bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup # For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile +util/grub-mkimage.c_DEPENDENCIES = Makefile # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 923231791..003f86c33 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -14,10 +14,10 @@ boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LI boot_img_FORMAT = binary bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ util/resolve.c gnulib/progname.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile +util/grub-mkimage.c_DEPENDENCIES = Makefile pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ diff --git a/conf/mips.rmk b/conf/mips.rmk index 4603c219e..c748d3945 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -12,10 +12,10 @@ bin_SCRIPTS = # For grub-mkimage. bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile +util/grub-mkimage.c_DEPENDENCIES = Makefile # For serial.mod. pkglib_MODULES += serial.mod diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 8e96599aa..dd1524df1 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -45,7 +45,7 @@ bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname # For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ util/resolve.c gnulib/progname.c # For grub-setup. diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index bab561cc4..8bf0a08d9 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -4,7 +4,7 @@ bin_UTILITIES = grub-mkimage # For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c \ util/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile diff --git a/util/grub-mkrawimage.c b/util/grub-mkimage.c similarity index 100% rename from util/grub-mkrawimage.c rename to util/grub-mkimage.c From 2296410ffbef1c180f3c001dff7abcc39fc6a242 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 22:26:29 +0200 Subject: [PATCH 29/38] initial support for ppc in grub-mkimage (bugs for now) --- conf/common.rmk | 7 ++ conf/i386-pc.rmk | 7 -- conf/i386-qemu.rmk | 6 -- conf/mips.rmk | 7 -- conf/sparc64-ieee1275.rmk | 5 -- conf/x86-efi.rmk | 8 -- include/grub/mips/kernel.h | 2 + include/grub/powerpc/ieee1275/kernel.h | 19 ++++ include/grub/powerpc/kernel.h | 3 - kern/powerpc/ieee1275/startup.S | 6 +- util/elf/grub-mkimage.c | 5 +- util/grub-mkimage.c | 115 +++++++++++++++++++++---- 12 files changed, 133 insertions(+), 57 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 4b39e9b71..011bb2773 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -21,6 +21,13 @@ grub_mkelfimage_SOURCES = gnulib/progname.c \ util/resolve.c util/elf/grub-mkimage.c_DEPENDENCIES = Makefile +# For grub-mkimage. +bin_UTILITIES += grub-mkimage +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ + util/resolve.c lib/LzmaEnc.c lib/LzFind.c +grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) +util/grub-mkimage.c_DEPENDENCIES = Makefile + # For grub-probe. sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 2dd874e13..1e0a3ff58 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -61,15 +61,8 @@ kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkimage.c_DEPENDENCIES = Makefile - # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = gnulib/progname.c \ diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 003f86c33..ff263245d 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -13,12 +13,6 @@ boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_M boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR) boot_img_FORMAT = binary -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ - util/resolve.c gnulib/progname.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkimage.c_DEPENDENCIES = Makefile - pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ diff --git a/conf/mips.rmk b/conf/mips.rmk index c748d3945..7d30f55f1 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -10,13 +10,6 @@ kernel_img_HEADERS += cpu/cache.h sbin_SCRIPTS = bin_SCRIPTS = -# For grub-mkimage. -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) -util/grub-mkimage.c_DEPENDENCIES = Makefile - # For serial.mod. pkglib_MODULES += serial.mod serial_mod_SOURCES = term/serial.c diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index dd1524df1..5b71d4cb2 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -41,13 +41,8 @@ kernel_img_LDFLAGS += -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc kernel_img_FORMAT = binary # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname -# For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ - util/resolve.c gnulib/progname.c - # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 8bf0a08d9..99a9938ef 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -1,13 +1,5 @@ # -*- makefile -*- -# Utilities. -bin_UTILITIES = grub-mkimage - -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c \ - util/misc.c util/resolve.c -util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile - # Scripts. sbin_SCRIPTS = grub-install diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 8b68f7b6b..172c1dbe2 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -46,6 +46,8 @@ #define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW +#define EM_TARGET EM_MIPS + #ifndef ASM_FILE typedef enum { diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h index a76c2a4df..229416243 100644 --- a/include/grub/powerpc/ieee1275/kernel.h +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -21,8 +21,27 @@ #include +#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" +#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" + +#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW +#define GRUB_KERNEL_MACHINE_PREFIX 0x4 +#define GRUB_KERNEL_MACHINE_DATA_END 0x44 +#define GRUB_KERNEL_MACHINE_LINK_ALIGN 4 + +#define EM_TARGET EM_PPC +#define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 + #ifndef ASM_FILE +typedef enum { + GRUB_PLATFORM_IMAGE_RAW, + GRUB_PLATFORM_IMAGE_ELF +} + grub_platform_image_format_t; +#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW +#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF + /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h index b4687337f..e4ff65174 100644 --- a/include/grub/powerpc/kernel.h +++ b/include/grub/powerpc/kernel.h @@ -26,7 +26,4 @@ rewrite grub-mkimage to generate valid ELF files. */ #define GRUB_MOD_GAP 0x8000 -#define GRUB_KERNEL_CPU_PREFIX 0x4 -#define GRUB_KERNEL_CPU_DATA_END 0x44 - #endif diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S index 75e1ed852..979f260f8 100644 --- a/kern/powerpc/ieee1275/startup.S +++ b/kern/powerpc/ieee1275/startup.S @@ -18,7 +18,7 @@ */ #include -#include +#include .extern __bss_start .extern _end @@ -30,7 +30,7 @@ start: _start: b codestart - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkelfimage */ @@ -39,7 +39,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END codestart: li 2, 0 diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c index 04a19bc4e..f37837c19 100644 --- a/util/elf/grub-mkimage.c +++ b/util/elf/grub-mkimage.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "progname.h" @@ -323,9 +324,9 @@ add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char * if (prefix) { - if (GRUB_KERNEL_CPU_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_CPU_DATA_END) + if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error ("prefix too long"); - grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_CPU_PREFIX, out); + grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_MACHINE_PREFIX, out); } free (phdrs); diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 30608a932..71376eaee 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -46,6 +46,36 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define GRUB_IEEE1275_NOTE_NAME "PowerPC" +#define GRUB_IEEE1275_NOTE_TYPE 0x1275 + +/* These structures are defined according to the CHRP binding to IEEE1275, + "Client Program Format" section. */ + +struct grub_ieee1275_note_hdr +{ + grub_uint32_t namesz; + grub_uint32_t descsz; + grub_uint32_t type; + char name[sizeof (GRUB_IEEE1275_NOTE_NAME)]; +}; + +struct grub_ieee1275_note_desc +{ + grub_uint32_t real_mode; + grub_uint32_t real_base; + grub_uint32_t real_size; + grub_uint32_t virt_base; + grub_uint32_t virt_size; + grub_uint32_t load_base; +}; + +struct grub_ieee1275_note +{ + struct grub_ieee1275_note_hdr header; + struct grub_ieee1275_note_desc descriptor; +}; + #ifdef GRUB_MACHINE_EFI #define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT #define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) @@ -786,11 +816,11 @@ static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format + grub_platform_image_format_t format, #else - int dummy __attribute__ ((unused)) + int dummy __attribute__ ((unused)), #endif - + int note ) { char *kernel_img, *core_img; @@ -1205,7 +1235,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_img); free (boot_path); } -#elif defined(GRUB_MACHINE_MIPS) +#elif defined(GRUB_MACHINE_MIPS) || defined (GRUB_MACHINE_IEEE1275) if (format == GRUB_PLATFORM_IMAGE_ELF) { char *elf_img; @@ -1213,12 +1243,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; grub_uint32_t target_addr; + int header_size, footer_size = 0; + int phnum = 1; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); program_size = ALIGN_ADDR (core_size); - elf_img = xmalloc (program_size + sizeof (*ehdr) + sizeof (*phdr)); - memset (elf_img, 0, program_size + sizeof (*ehdr) + sizeof (*phdr)); - memcpy (elf_img + sizeof (*ehdr) + sizeof (*phdr), core_img, core_size); + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size); + memcpy (elf_img + header_size, core_img, core_size); ehdr = (void *) elf_img; phdr = (void *) (elf_img + sizeof (*ehdr)); memcpy (ehdr->e_ident, ELFMAG, SELFMAG); @@ -1231,12 +1270,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_ident[EI_VERSION] = EV_CURRENT; ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; ehdr->e_type = grub_host_to_target16 (ET_EXEC); - ehdr->e_machine = grub_host_to_target16 (EM_MIPS); + ehdr->e_machine = grub_host_to_target16 (EM_TARGET); ehdr->e_version = grub_host_to_target32 (EV_CURRENT); ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); - ehdr->e_phnum = grub_host_to_target16 (1); + ehdr->e_phnum = grub_host_to_target16 (phnum); /* No section headers. */ ehdr->e_shoff = grub_host_to_target32 (0); @@ -1247,23 +1286,60 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_offset = grub_host_to_target32 (sizeof (*ehdr) + sizeof (*phdr)); + phdr->p_offset = grub_host_to_target32 (header_size); phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR +#if defined(GRUB_MACHINE_MIPS) + target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR + kernel_size + total_module_size, 32); +#else + target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; +#endif ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN); +#if defined(GRUB_MACHINE_MIPS) ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER | EF_MIPS_PIC | EF_MIPS_CPIC); +#else + ehdr->e_flags = 0; +#endif phdr->p_filesz = grub_host_to_target32 (core_size); phdr->p_memsz = grub_host_to_target32 (core_size); + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + grub_util_info ("adding CHRP NOTE segment"); + + note->header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); + note->header.descsz = grub_host_to_target32 (note_size); + note->header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); + strcpy (note->header.name, GRUB_IEEE1275_NOTE_NAME); + note->descriptor.real_mode = grub_host_to_target32 (0xffffffff); + note->descriptor.real_base = grub_host_to_target32 (0x00c00000); + note->descriptor.real_size = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_base = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); + note->descriptor.load_base = grub_host_to_target32 (0x00004000); + + phdr[1].p_type = grub_host_to_target32 (PT_NOTE); + phdr[1].p_flags = grub_host_to_target32 (PF_R); + phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_vaddr = 0; + phdr[1].p_paddr = 0; + phdr[1].p_filesz = grub_host_to_target32 (note_size); + phdr[1].p_memsz = 0; + phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + } + free (core_img); core_img = elf_img; - core_size = program_size + sizeof (*ehdr) + sizeof (*phdr); + core_size = program_size + header_size + footer_size; } #endif @@ -1291,6 +1367,7 @@ static struct option options[] = {"font", required_argument, 0, 'f'}, {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, + {"note", no_argument, 0, 'n'}, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT {"format", required_argument, 0, 'O'}, #endif @@ -1316,6 +1393,7 @@ Make a bootable image of GRUB.\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ + -n, --note add NOTE segment for CHRP Open Firmware\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n" #ifdef GRUB_PLATFORM_IMAGE_DEFAULT "\ @@ -1348,6 +1426,7 @@ main (int argc, char *argv[]) char *font = NULL; char *config = NULL; FILE *fp = stdout; + int note = 0; #ifdef GRUB_PLATFORM_IMAGE_DEFAULT grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; #endif @@ -1358,7 +1437,7 @@ main (int argc, char *argv[]) while (1) { - int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVvn", options, 0); if (c == -1) break; @@ -1400,6 +1479,10 @@ main (int argc, char *argv[]) dir = xstrdup (optarg); break; + case 'n': + note = 1; + break; + case 'm': if (memdisk) free (memdisk); @@ -1462,11 +1545,11 @@ main (int argc, char *argv[]) generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - format + format, #else - 0 + 0, #endif - ); + note); fclose (fp); From 7576adef7cc18df53688e248fcdabb73aa9cb4da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 23:04:29 +0200 Subject: [PATCH 30/38] Remove grub-mkelfimage --- conf/common.rmk | 7 ------- 1 file changed, 7 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 011bb2773..bab7effb9 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -14,13 +14,6 @@ else grub_mkdevicemap_SOURCES += util/devicemap.c endif -# For grub-mkelfimage. -bin_UTILITIES += grub-mkelfimage -grub_mkelfimage_SOURCES = gnulib/progname.c \ - util/elf/grub-mkimage.c util/misc.c \ - util/resolve.c -util/elf/grub-mkimage.c_DEPENDENCIES = Makefile - # For grub-mkimage. bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ From 614be3f11949a6a2e7033e2f2dc4caa3e5a772a3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 00:45:21 +0200 Subject: [PATCH 31/38] #if-less grub-mkimage --- include/grub/i386/pc/boot.h | 17 +- include/grub/i386/pc/kernel.h | 24 +- include/grub/i386/pc/memory.h | 6 +- include/grub/i386/qemu/boot.h | 3 - include/grub/i386/qemu/kernel.h | 3 - include/grub/sparc64/ieee1275/boot.h | 4 - include/grub/sparc64/ieee1275/kernel.h | 13 - util/grub-mkimage.c | 1378 +++++++++++++----------- util/grub-mkrescue.in | 2 +- 9 files changed, 765 insertions(+), 685 deletions(-) diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index e88c62b71..09d01caee 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -19,6 +19,9 @@ #ifndef GRUB_BOOT_MACHINE_HEADER #define GRUB_BOOT_MACHINE_HEADER 1 +#define MACHINE I386_PC +#include + /* The signature for bootloader. */ #define GRUB_BOOT_MACHINE_SIGNATURE 0xaa55 @@ -57,9 +60,6 @@ floppy. */ #define GRUB_BOOT_MACHINE_BIOS_HD_FLAG 0x80 -/* The segment where the kernel is loaded. */ -#define GRUB_BOOT_MACHINE_KERNEL_SEG 0x800 - /* The address where the kernel is loaded. */ #define GRUB_BOOT_MACHINE_KERNEL_ADDR (GRUB_BOOT_MACHINE_KERNEL_SEG << 4) @@ -68,16 +68,7 @@ #define GRUB_BOOT_MACHINE_PXE_DL 0x7f -#ifndef ASM_FILE - /* This is the blocklist used in the diskboot image. */ -struct grub_boot_blocklist -{ - grub_uint64_t start; - grub_uint16_t len; - grub_uint16_t segment; -} __attribute__ ((packed)); - -#endif /* ! ASM_FILE */ +#define grub_boot_blocklist grub_pc_bios_boot_blocklist #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index e830afae2..77d5c6e5a 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -19,29 +19,9 @@ #ifndef KERNEL_MACHINE_HEADER #define KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 +#define MACHINE I386_PC -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE 0x10 - -/* The offset of GRUB_INSTALL_DOS_PART. */ -#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART 0x14 - -/* The offset of GRUB_INSTALL_BSD_PART. */ -#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART 0x18 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x1c - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x5c - -/* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x5F0) +#include /* Enable LZMA compression */ #define ENABLE_LZMA 1 diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 841b06164..0b4191734 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -29,6 +29,9 @@ #include +#define MACHINE I386_PC +#include + /* The scratch buffer used in real mode code. */ #define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 #define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) @@ -40,9 +43,6 @@ /* The size of the protect mode stack. */ #define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE 0x8000 -/* The upper memory area (starting at 640 kiB). */ -#define GRUB_MEMORY_MACHINE_UPPER 0xa0000 - /* The protected mode stack. */ #define GRUB_MEMORY_MACHINE_PROT_STACK \ (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \ diff --git a/include/grub/i386/qemu/boot.h b/include/grub/i386/qemu/boot.h index 6fbb57750..5f53eabfb 100644 --- a/include/grub/i386/qemu/boot.h +++ b/include/grub/i386/qemu/boot.h @@ -22,7 +22,4 @@ /* The size of boot.img. */ #define GRUB_BOOT_MACHINE_SIZE (0x100000 - GRUB_BOOT_MACHINE_LINK_ADDR) -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR 0x4 - #endif diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index bc0b93d4f..3d22c9d9f 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -19,9 +19,6 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR 0x8 - /* The offset of GRUB_KERNEL_IMAGE_SIZE. */ #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 9671c6900..bd0a7bf3c 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -50,10 +50,6 @@ #define GRUB_BOOT_MACHINE_CODE_END \ (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) -#define GRUB_BOOT_MACHINE_LIST_SIZE 12 - -#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS 0x4400 - #define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200 #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index a16fb88e7..2948a8d2f 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -42,21 +42,8 @@ #define GRUB_KERNEL_MACHINE_RAW_SIZE 0 #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, aout" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_AOUT -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_AOUT GRUB_PLATFORM_IMAGE_AOUT - #include #include diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 71376eaee..af2988a3f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -19,9 +19,6 @@ #include #include -#include -#include -#include #include #include #include @@ -30,6 +27,7 @@ #include #include #include +#include #include #include @@ -44,7 +42,144 @@ #include "progname.h" -#define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +#define TARGET_NO_FIELD 0xffffffff +struct image_target_desc +{ + const char *name; + grub_size_t voidp_sizeof; + int bigendian; + enum { + IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, + IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, + IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC + } id; + enum {FORMAT_RAW, FORMAT_AOUT, FORMAT_ELF, FORMAT_PE} format; + enum + { + PLATFORM_FLAGS_NONE = 0, + PLATFORM_FLAGS_LZMA = 1 + } flags; + unsigned prefix; + unsigned data_end; + unsigned raw_size; + unsigned total_module_size; + unsigned kernel_image_size; + unsigned compressed_size; + unsigned link_align; + grub_uint16_t elf_target; + unsigned section_align; + signed vaddr_offset; + unsigned install_dos_part, install_bsd_part; +}; + +struct image_target_desc image_targets[] = + { + {"i386-coreboot", 4, 0, IMAGE_COREBOOT, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + {"i386-pc", 4, 0, IMAGE_I386_PC, FORMAT_RAW, PLATFORM_FLAGS_LZMA, + GRUB_KERNEL_I386_PC_PREFIX, GRUB_KERNEL_I386_PC_DATA_END, + GRUB_KERNEL_I386_PC_RAW_SIZE, GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, + GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, GRUB_KERNEL_I386_PC_INSTALL_BSD_PART + }, + {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"i386-qemu", 4, 0, IMAGE_QEMU, FORMAT_RAW, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"powerpc-ieee1275", 4, 1, IMAGE_PPC, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"sparc64-ieee1275-raw", 8, 1, IMAGE_SPARC64_RAW, + FORMAT_RAW, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"sparc64-ieee1275-aout", 8, 1, IMAGE_SPARC64_AOUT, + FORMAT_AOUT, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + }; + +#define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) +#define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x))) +#define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x))) +#define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x))) + +static inline grub_uint32_t +grub_target_to_host32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu32 (in); + else + return grub_le_to_cpu32 (in); +} + +static inline grub_uint64_t +grub_target_to_host64_real (struct image_target_desc *image_target, grub_uint64_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu64 (in); + else + return grub_le_to_cpu64 (in); +} + +static inline grub_uint32_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_target_to_host64_real (image_target, in); + else + return grub_target_to_host32_real (image_target, in); +} + +static inline grub_uint32_t +grub_host_to_target32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be32 (in); + else + return grub_cpu_to_le32 (in); +} + +static inline grub_uint16_t +grub_target_to_host16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu16 (in); + else + return grub_le_to_cpu16 (in); +} + +static inline grub_uint16_t +grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be16 (in); + else + return grub_cpu_to_le16 (in); +} #define GRUB_IEEE1275_NOTE_NAME "PowerPC" #define GRUB_IEEE1275_NOTE_TYPE 0x1275 @@ -76,21 +211,8 @@ struct grub_ieee1275_note struct grub_ieee1275_note_desc descriptor; }; -#ifdef GRUB_MACHINE_EFI -#define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT -#define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) -#else -#define SECTION_ALIGN 1 -#define VADDR_OFFSET 0 -#endif +#define grub_target_to_host(val) grub_target_to_host_real(image_target, (val)) -#if GRUB_TARGET_WORDSIZE == 32 -# define grub_target_to_host(val) grub_target_to_host32(val) -#elif GRUB_TARGET_WORDSIZE == 64 -# define grub_target_to_host(val) grub_target_to_host64(val) -#endif - -#ifdef ENABLE_LZMA #include static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); } @@ -98,8 +220,8 @@ static void SzFree(void *p, void *address) { p = p; free(address); } static ISzAlloc g_Alloc = { SzAlloc, SzFree }; static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) +compress_kernel_lzma (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size, size_t raw_size) { CLzmaEncProps props; unsigned char out_props[5]; @@ -112,45 +234,47 @@ compress_kernel (char *kernel_img, size_t kernel_size, props.pb = 2; props.numThreads = 1; - if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE) + if (kernel_size < raw_size) grub_util_error (_("the core image is too small")); *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE); + memcpy (*core_img, kernel_img, raw_size); - *core_size = kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE; - if (LzmaEncode((unsigned char *) *core_img + GRUB_KERNEL_MACHINE_RAW_SIZE, - core_size, - (unsigned char *) kernel_img + GRUB_KERNEL_MACHINE_RAW_SIZE, - kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE, - &props, out_props, &out_props_size, - 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) + *core_size = kernel_size - raw_size; + if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size, + (unsigned char *) kernel_img + raw_size, + kernel_size - raw_size, + &props, out_props, &out_props_size, + 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) grub_util_error (_("cannot compress the kernel image")); - *core_size += GRUB_KERNEL_MACHINE_RAW_SIZE; + *core_size += raw_size; } -#else /* No lzma compression */ - static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) +compress_kernel (struct image_target_desc *image_target, char *kernel_img, + size_t kernel_size, char **core_img, size_t *core_size) { + if (image_target->flags & PLATFORM_FLAGS_LZMA) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size, image_target->raw_size); + return; + } + *core_img = xmalloc (kernel_size); memcpy (*core_img, kernel_img, kernel_size); *core_size = kernel_size; } -#endif /* No lzma compression */ - -#ifdef GRUB_MACHINE_EFI /* Relocate symbols; note that this function overwrites the symbol table. Return the address of a start symbol. */ static Elf_Addr relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Shdr *symtab_section, Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections) + Elf_Half section_entsize, Elf_Half num_sections, + struct image_target_desc *image_target) { Elf_Word symtab_size, sym_size, num_syms; Elf_Off symtab_offset; @@ -209,7 +333,8 @@ relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, /* Return the address of a symbol at the index I in the section S. */ static Elf_Addr -get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) +get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + struct image_target_desc *image_target) { Elf_Sym *sym; @@ -221,7 +346,8 @@ get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) /* Return the address of a modified value. */ static Elf_Addr * -get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) +get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + struct image_target_desc *image_target) { return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); } @@ -234,7 +360,7 @@ static void relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Addr *section_addresses, Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) + const char *strtab, struct image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; @@ -283,79 +409,84 @@ relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Addr addend; offset = grub_target_to_host (r->r_offset); - target = get_target_address (e, target_section, offset); + target = get_target_address (e, target_section, offset, image_target); info = grub_target_to_host (r->r_info); sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info)); + ELF_R_SYM (info), image_target); addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? r->r_addend : 0; - switch (ELF_R_TYPE (info)) - { -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - case R_386_NONE: - break; + if (image_target->voidp_sizeof == 4) + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; - case R_386_32: - /* This is absolute. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; - case R_386_PC32: - /* This is relative. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr - - target_section_addr - offset - - VADDR_OFFSET); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + else + switch (ELF_R_TYPE (info)) + { -#else + case R_X86_64_NONE: + break; - case R_X86_64_NONE: - break; + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", + *target, offset); + break; - case R_X86_64_64: - *target = grub_host_to_target64 (grub_target_to_host64 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", - *target, offset); - break; + case R_X86_64_PC32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } - case R_X86_64_PC32: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr - - target_section_addr - offset - - VADDR_OFFSET); - grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } - case R_X86_64_32: - case R_X86_64_32S: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - -#endif - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } } } } @@ -371,7 +502,8 @@ struct fixup_block_list after having written to the file OUT. */ Elf_Addr add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address) + Elf_Addr addr, int flush, Elf_Addr current_address, + struct image_target_desc *image_target) { struct grub_pe32_fixup_block *b; @@ -393,7 +525,7 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, size_t index; next_address = current_address + b->block_size; - padding_size = ((ALIGN_UP (next_address, SECTION_ALIGN) + padding_size = ((ALIGN_UP (next_address, image_target->section_align) - next_address) >> 1); index = ((b->block_size - sizeof (*b)) >> 1); @@ -466,7 +598,7 @@ static Elf_Addr make_reloc_section (Elf_Ehdr *e, void **out, Elf_Addr *section_addresses, Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) + const char *strtab, struct image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; @@ -509,39 +641,44 @@ make_reloc_section (Elf_Ehdr *e, void **out, info = grub_le_to_cpu32 (r->r_info); /* Necessary to relocate only absolute addresses. */ -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - if (ELF_R_TYPE (info) == R_386_32) + if (image_target->voidp_sizeof == 4) { - Elf_Addr addr; + if (ELF_R_TYPE (info) == R_386_32) + { + Elf_Addr addr; - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%x", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address); + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + image_target); + } } -#else - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) + else { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address); + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address, + image_target); + } } -#endif } } - current_address = add_fixup_entry (&lst, 0, 0, 1, current_address); + current_address = add_fixup_entry (&lst, 0, 0, 1, current_address, image_target); { grub_uint8_t *ptr; @@ -562,17 +699,14 @@ make_reloc_section (Elf_Ehdr *e, void **out, return current_address; } -#endif - /* Determine if this section is a text section. Return false if this section is not allocated. */ static int -is_text_section (Elf_Shdr *s) +is_text_section (Elf_Shdr *s, struct image_target_desc *image_target) { -#ifndef GRUB_MACHINE_EFI - if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; -#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -581,12 +715,11 @@ is_text_section (Elf_Shdr *s) BSS is also a data section, since the converter initializes BSS when producing PE32 to avoid a bug in EFI implementations. */ static int -is_data_section (Elf_Shdr *s) +is_data_section (Elf_Shdr *s, struct image_target_desc *image_target) { -#ifndef GRUB_MACHINE_EFI - if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; -#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -597,7 +730,8 @@ is_data_section (Elf_Shdr *s) static Elf_Addr * locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, const char *strtab, - grub_size_t *exec_size, grub_size_t *kernel_sz) + grub_size_t *exec_size, grub_size_t *kernel_sz, + struct image_target_desc *image_target) { int i; Elf_Addr current_address; @@ -613,14 +747,14 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) + if (is_text_section (s, image_target)) { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) - image_target->vaddr_offset; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -628,22 +762,24 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; *exec_size = current_address; /* .data */ for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) + if (is_data_section (s, image_target)) { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -651,15 +787,15 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; *kernel_sz = current_address; return section_addresses; } /* Return if the ELF header is valid. */ static int -check_elf_header (Elf_Ehdr *e, size_t size) +check_elf_header (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) { if (size < sizeof (*e) || e->e_ident[EI_MAG0] != ELFMAG0 @@ -677,7 +813,8 @@ static char * load_image (const char *kernel_path, grub_size_t *exec_size, grub_size_t *kernel_sz, grub_size_t *bss_size, grub_size_t total_module_size, Elf_Addr *start, - void **reloc_section, grub_size_t *reloc_size) + void **reloc_section, grub_size_t *reloc_size, + struct image_target_desc *image_target) { char *kernel_img, *out_img; const char *strtab; @@ -700,7 +837,7 @@ load_image (const char *kernel_path, grub_size_t *exec_size, grub_util_load_image (kernel_path, kernel_img); e = (Elf_Ehdr *) kernel_img; - if (! check_elf_header (e, kernel_size)) + if (! check_elf_header (e, kernel_size, image_target)) grub_util_error ("invalid ELF header"); section_offset = grub_target_to_host32 (e->e_shoff); @@ -719,85 +856,86 @@ load_image (const char *kernel_path, grub_size_t *exec_size, section_addresses = locate_sections (sections, section_entsize, num_sections, strtab, - exec_size, kernel_sz); + exec_size, kernel_sz, image_target); -#ifdef GRUB_MACHINE_EFI - { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + if (image_target->id == IMAGE_EFI) + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + VADDR_OFFSET; + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; #if 0 - { - Elf_Addr current_address = *kernel_sz; + { + Elf_Addr current_address = *kernel_sz; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); + symtab_section = s; + break; } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = relocate_symbols (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections, image_target); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + relocate_addresses (e, sections, section_addresses, section_entsize, + num_sections, strtab, image_target); + + *reloc_size = make_reloc_section (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab, image_target); + + } + else + { + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; } -#else - *bss_size = 0; -#endif - - symtab_section = NULL; - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) - { - symtab_section = s; - break; - } - - if (! symtab_section) - grub_util_error ("no symbol table"); - - *start = relocate_symbols (e, sections, symtab_section, - section_vaddresses, section_entsize, - num_sections); - if (*start == 0) - grub_util_error ("start symbol is not defined"); - - /* Resolve addresses in the virtual address space. */ - relocate_addresses (e, sections, section_addresses, section_entsize, - num_sections, strtab); - - *reloc_size = make_reloc_section (e, reloc_section, - section_vaddresses, sections, - section_entsize, num_sections, - strtab); - - } -#else - *bss_size = 0; - *reloc_size = 0; - *reloc_section = NULL; -#endif out_img = xmalloc (*kernel_sz + total_module_size); for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s) || is_text_section (s)) + if (is_data_section (s, image_target) || is_text_section (s, image_target)) { if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) memset (out_img + section_addresses[i], 0, @@ -815,13 +953,7 @@ load_image (const char *kernel_path, grub_size_t *exec_size, static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format, -#else - int dummy __attribute__ ((unused)), -#endif - int note -) + struct image_target_desc *image_target, int note) { char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size, exec_size; @@ -869,11 +1001,11 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size); + &reloc_size, image_target); - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); - strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); + strcpy (kernel_img + image_target->prefix, prefix); /* Fill in the grub_module_info structure. */ modinfo = (struct grub_module_info *) (kernel_img + kernel_size); @@ -946,402 +1078,401 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], } grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); - compress_kernel (kernel_img, kernel_size + total_module_size, + compress_kernel (image_target, kernel_img, kernel_size + total_module_size, &core_img, &core_size); grub_util_info ("the core size is 0x%x", core_size); -#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) - = grub_host_to_target32 (total_module_size); -#endif -#ifdef GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) - = grub_host_to_target32 (kernel_size); -#endif -#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) - = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); -#endif + if (image_target->total_module_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + if (image_target->kernel_image_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->kernel_image_size)) + = grub_host_to_target32 (kernel_size); + if (image_target->compressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->compressed_size)) + = grub_host_to_target32 (core_size - image_target->raw_size); -#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) /* If we included a drive in our prefix, let GRUB know it doesn't have to prepend the drive told by BIOS. */ - if (prefix[0] == '(') + if (image_target->install_dos_part != TARGET_NO_FIELD + && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') { - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) + *((grub_int32_t *) (core_img + image_target->install_dos_part)) = grub_host_to_target32 (-2); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) + *((grub_int32_t *) (core_img + image_target->install_bsd_part)) = grub_host_to_target32 (-2); } -#endif - -#ifdef GRUB_MACHINE_PCBIOS - if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) - grub_util_error (_("core image is too big (%p > %p)"), - GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, - GRUB_MEMORY_MACHINE_UPPER); -#endif - -#if defined(GRUB_MACHINE_PCBIOS) - { - unsigned num; - char *boot_path, *boot_img; - size_t boot_size; - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - if (num > 0xffff) - grub_util_error (_("the core image is too big")); - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error (_("diskboot.img size must be %u bytes"), - GRUB_DISK_SECTOR_SIZE); - - boot_img = grub_util_read_image (boot_path); + switch (image_target->id) { - struct grub_boot_blocklist *block; - block = (struct grub_boot_blocklist *) (boot_img - + GRUB_DISK_SECTOR_SIZE - - sizeof (*block)); - block->len = grub_host_to_target16 (num); + case IMAGE_I386_PC: + { + unsigned num; + char *boot_path, *boot_img; + size_t boot_size; - /* This is filled elsewhere. Verify it just in case. */ - assert (block->segment - == grub_host_to_target16 (GRUB_BOOT_MACHINE_KERNEL_SEG - + (GRUB_DISK_SECTOR_SIZE >> 4))); - } + if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) + grub_util_error (_("core image is too big (%p > %p)"), + GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, + GRUB_MEMORY_I386_PC_UPPER); - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_EFI) - { - void *pe_img; - size_t pe_size; - struct grub_pe32_header *header; - struct grub_pe32_coff_header *c; - struct grub_pe32_optional_header *o; - struct grub_pe32_section_table *text_section, *data_section; - struct grub_pe32_section_table *mods_section, *reloc_section; - static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), - SECTION_ALIGN); - int reloc_addr = ALIGN_UP (header_size + core_size, SECTION_ALIGN); + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + if (num > 0xffff) + grub_util_error (_("the core image is too big")); - pe_size = ALIGN_UP (reloc_addr + reloc_size, SECTION_ALIGN); - pe_img = xmalloc (reloc_addr + reloc_size); - memset (pe_img, 0, header_size); - memcpy (pe_img + header_size, core_img, core_size); - memcpy (pe_img + reloc_addr, rel_section, reloc_size); - header = pe_img; + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); - /* The magic. */ - memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); - memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + boot_img = grub_util_read_image (boot_path); - /* The COFF file header. */ - c = &header->coff_header; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); -#else - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); -#endif + { + struct grub_pc_bios_boot_blocklist *block; + block = (struct grub_pc_bios_boot_blocklist *) (boot_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + block->len = grub_host_to_target16 (num); - c->num_sections = grub_host_to_target16 (4); - c->time = grub_host_to_target32 (time (0)); - c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); - c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE - | GRUB_PE32_LINE_NUMS_STRIPPED -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - | GRUB_PE32_32BIT_MACHINE -#endif - | GRUB_PE32_LOCAL_SYMS_STRIPPED - | GRUB_PE32_DEBUG_STRIPPED); + /* This is filled elsewhere. Verify it just in case. */ + assert (block->segment + == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG + + (GRUB_DISK_SECTOR_SIZE >> 4))); + } - /* The PE Optional header. */ - o = &header->optional_header; - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); - o->bss_size = grub_cpu_to_le32 (bss_size); - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (header_size); -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - o->data_base = grub_host_to_target32 (header_size + exec_size); -#endif - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (SECTION_ALIGN); - o->file_alignment = grub_host_to_target32 (SECTION_ALIGN); - o->image_size = grub_host_to_target32 (pe_size); - o->header_size = grub_host_to_target32 (header_size); - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_EFI: + { + void *pe_img; + size_t pe_size; + struct grub_pe32_header *header; + struct grub_pe32_coff_header *c; + struct grub_pe32_optional_header *o; + struct grub_pe32_section_table *text_section, *data_section; + struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + image_target->section_align); + int reloc_addr = ALIGN_UP (header_size + core_size, image_target->section_align); - /* Do these really matter? */ - o->stack_reserve_size = grub_host_to_target32 (0x10000); - o->stack_commit_size = grub_host_to_target32 (0x10000); - o->heap_reserve_size = grub_host_to_target32 (0x10000); - o->heap_commit_size = grub_host_to_target32 (0x10000); + pe_size = ALIGN_UP (reloc_addr + reloc_size, image_target->section_align); + pe_img = xmalloc (reloc_addr + reloc_size); + memset (pe_img, 0, header_size); + memcpy (pe_img + header_size, core_img, core_size); + memcpy (pe_img + reloc_addr, rel_section, reloc_size); + header = pe_img; + + /* The magic. */ + memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); + memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + + /* The COFF file header. */ + c = &header->coff_header; + if (image_target->voidp_sizeof == 4) + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); + else + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (time (0)); + c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED + | ((image_target->voidp_sizeof == 4) + ? GRUB_PE32_32BIT_MACHINE + : 0) + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + o = &header->optional_header; + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + if (image_target->voidp_sizeof == 4) + o->data_base = grub_host_to_target32 (header_size + exec_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); - o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); - o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); - /* The sections. */ - text_section = (struct grub_pe32_section_table *) (header + 1); - strcpy (text_section->name, ".text"); - text_section->virtual_size = grub_cpu_to_le32 (exec_size); - text_section->virtual_address = grub_cpu_to_le32 (header_size); - text_section->raw_data_size = grub_cpu_to_le32 (exec_size); - text_section->raw_data_offset = grub_cpu_to_le32 (header_size); - text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_ALIGN_64BYTES); + /* The sections. */ + text_section = (struct grub_pe32_section_table *) (header + 1); + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_ALIGN_64BYTES); - data_section = text_section + 1; - strcpy (data_section->name, ".data"); - data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); - data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); - data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); - data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); - data_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); + data_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); #if 0 - bss_section = data_section + 1; - strcpy (bss_section->name, ".bss"); - bss_section->virtual_size = grub_cpu_to_le32 (bss_size); - bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); - bss_section->raw_data_size = 0; - bss_section->raw_data_offset = 0; - bss_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES - | GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | 0x80); + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); #endif - mods_section = data_section + 1; - strcpy (mods_section->name, "mods"); - mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); - mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); - mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); - mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); - mods_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); + mods_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); - reloc_section = mods_section + 1; - strcpy (reloc_section->name, ".reloc"); - reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); - reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); - reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); - reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); - reloc_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_DISCARDABLE - | GRUB_PE32_SCN_MEM_READ); - free (core_img); - core_img = pe_img; - core_size = pe_size; - } -#elif defined(GRUB_MACHINE_QEMU) - { - char *rom_img; - size_t rom_size; - char *boot_path, *boot_img; - size_t boot_size; + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } + break; + case IMAGE_QEMU: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; - boot_path = grub_util_get_path (dir, "boot.img"); - boot_size = grub_util_get_image_size (boot_path); - boot_img = grub_util_read_image (boot_path); + boot_path = grub_util_get_path (dir, "boot.img"); + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); - /* Rom sizes must be 64k-aligned. */ - rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); + /* Rom sizes must be 64k-aligned. */ + rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); - rom_img = xmalloc (rom_size); - memset (rom_img, 0, rom_size); + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); - memcpy (rom_img, core_img, core_size); + memcpy (rom_img, core_img, core_size); - *((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); + *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); - memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); + memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); - free (core_img); - core_img = rom_img; - core_size = rom_size; + free (core_img); + core_img = rom_img; + core_size = rom_size; - free (boot_img); - free (boot_path); - } -#elif defined (GRUB_MACHINE_SPARC64) - if (format == GRUB_PLATFORM_IMAGE_AOUT) - { - void *aout_img; - size_t aout_size; - struct grub_aout32_header *aout_head; + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_AOUT: + { + void *aout_img; + size_t aout_size; + struct grub_aout32_header *aout_head; - aout_size = core_size + sizeof (*aout_head); - aout_img = xmalloc (aout_size); - aout_head = aout_img; - aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) - | AOUT32_OMAGIC); - aout_head->a_text = grub_host_to_target32 (core_size); - aout_head->a_entry - = grub_host_to_target32 (GRUB_BOOT_MACHINE_IMAGE_ADDRESS); - memcpy (aout_img + sizeof (*aout_head), core_img, core_size); + aout_size = core_size + sizeof (*aout_head); + aout_img = xmalloc (aout_size); + aout_head = aout_img; + aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) + | AOUT32_OMAGIC); + aout_head->a_text = grub_host_to_target32 (core_size); + aout_head->a_entry + = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS); + memcpy (aout_img + sizeof (*aout_head), core_img, core_size); - free (core_img); - core_img = aout_img; - core_size = aout_size; + free (core_img); + core_img = aout_img; + core_size = aout_size; + } + break; + case IMAGE_SPARC64_RAW: + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + num <<= GRUB_DISK_SECTOR_BITS; + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("diskboot.img is not one sector size"); + + boot_img = grub_util_read_image (boot_path); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8)) + = grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_YEELOONG_ELF: + case IMAGE_PPC: + case IMAGE_COREBOOT: + case IMAGE_I386_IEEE1275: + { + char *elf_img; + size_t program_size; + Elf32_Ehdr *ehdr; + Elf32_Phdr *phdr; + grub_uint32_t target_addr; + int header_size, footer_size = 0; + int phnum = 1; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); + + program_size = ALIGN_ADDR (core_size); + + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size); + memcpy (elf_img + header_size, core_img, core_size); + ehdr = (void *) elf_img; + phdr = (void *) (elf_img + sizeof (*ehdr)); + memcpy (ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASS32; + if (!image_target->bigendian) + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; + else + ehdr->e_ident[EI_DATA] = ELFDATA2MSB; + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr->e_type = grub_host_to_target16 (ET_EXEC); + ehdr->e_machine = grub_host_to_target16 (image_target->elf_target); + ehdr->e_version = grub_host_to_target32 (EV_CURRENT); + + ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); + ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); + ehdr->e_phnum = grub_host_to_target16 (phnum); + + /* No section headers. */ + ehdr->e_shoff = grub_host_to_target32 (0); + ehdr->e_shentsize = grub_host_to_target16 (0); + ehdr->e_shnum = grub_host_to_target16 (0); + ehdr->e_shstrndx = grub_host_to_target16 (0); + + ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); + + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + + if (image_target->id == IMAGE_YEELOONG_ELF) + target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR + + kernel_size + total_module_size, 32); + else + target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; + ehdr->e_entry = grub_host_to_target32 (target_addr); + phdr->p_vaddr = grub_host_to_target32 (target_addr); + phdr->p_paddr = grub_host_to_target32 (target_addr); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + if (image_target->id == IMAGE_YEELOONG_ELF) + ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER + | EF_MIPS_PIC | EF_MIPS_CPIC); + else + ehdr->e_flags = 0; + phdr->p_filesz = grub_host_to_target32 (core_size); + phdr->p_memsz = grub_host_to_target32 (core_size); + + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + grub_util_info ("adding CHRP NOTE segment"); + + note->header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); + note->header.descsz = grub_host_to_target32 (note_size); + note->header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); + strcpy (note->header.name, GRUB_IEEE1275_NOTE_NAME); + note->descriptor.real_mode = grub_host_to_target32 (0xffffffff); + note->descriptor.real_base = grub_host_to_target32 (0x00c00000); + note->descriptor.real_size = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_base = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); + note->descriptor.load_base = grub_host_to_target32 (0x00004000); + + phdr[1].p_type = grub_host_to_target32 (PT_NOTE); + phdr[1].p_flags = grub_host_to_target32 (PF_R); + phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_vaddr = 0; + phdr[1].p_paddr = 0; + phdr[1].p_filesz = grub_host_to_target32 (note_size); + phdr[1].p_memsz = 0; + phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + } + + free (core_img); + core_img = elf_img; + core_size = program_size + header_size + footer_size; + } + break; } - else - { - unsigned int num; - char *boot_path, *boot_img; - size_t boot_size; - - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - num <<= GRUB_DISK_SECTOR_BITS; - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error ("diskboot.img is not one sector size"); - - boot_img = grub_util_read_image (boot_path); - - *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) - = grub_host_to_target32 (num); - - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_MIPS) || defined (GRUB_MACHINE_IEEE1275) - if (format == GRUB_PLATFORM_IMAGE_ELF) - { - char *elf_img; - size_t program_size; - Elf32_Ehdr *ehdr; - Elf32_Phdr *phdr; - grub_uint32_t target_addr; - int header_size, footer_size = 0; - int phnum = 1; - - if (note) - { - phnum++; - footer_size += sizeof (struct grub_ieee1275_note); - } - header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); - - program_size = ALIGN_ADDR (core_size); - - elf_img = xmalloc (program_size + header_size + footer_size); - memset (elf_img, 0, program_size + header_size); - memcpy (elf_img + header_size, core_img, core_size); - ehdr = (void *) elf_img; - phdr = (void *) (elf_img + sizeof (*ehdr)); - memcpy (ehdr->e_ident, ELFMAG, SELFMAG); - ehdr->e_ident[EI_CLASS] = ELFCLASS32; -#ifdef GRUB_CPU_MIPSEL - ehdr->e_ident[EI_DATA] = ELFDATA2LSB; -#else - ehdr->e_ident[EI_DATA] = ELFDATA2MSB; -#endif - ehdr->e_ident[EI_VERSION] = EV_CURRENT; - ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; - ehdr->e_type = grub_host_to_target16 (ET_EXEC); - ehdr->e_machine = grub_host_to_target16 (EM_TARGET); - ehdr->e_version = grub_host_to_target32 (EV_CURRENT); - - ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); - ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); - ehdr->e_phnum = grub_host_to_target16 (phnum); - - /* No section headers. */ - ehdr->e_shoff = grub_host_to_target32 (0); - ehdr->e_shentsize = grub_host_to_target16 (0); - ehdr->e_shnum = grub_host_to_target16 (0); - ehdr->e_shstrndx = grub_host_to_target16 (0); - - ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); - - phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_offset = grub_host_to_target32 (header_size); - phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - -#if defined(GRUB_MACHINE_MIPS) - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); -#else - target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; -#endif - ehdr->e_entry = grub_host_to_target32 (target_addr); - phdr->p_vaddr = grub_host_to_target32 (target_addr); - phdr->p_paddr = grub_host_to_target32 (target_addr); - phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN); -#if defined(GRUB_MACHINE_MIPS) - ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER - | EF_MIPS_PIC | EF_MIPS_CPIC); -#else - ehdr->e_flags = 0; -#endif - phdr->p_filesz = grub_host_to_target32 (core_size); - phdr->p_memsz = grub_host_to_target32 (core_size); - - if (note) - { - int note_size = sizeof (struct grub_ieee1275_note); - struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) - (elf_img + program_size + header_size); - - grub_util_info ("adding CHRP NOTE segment"); - - note->header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); - note->header.descsz = grub_host_to_target32 (note_size); - note->header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); - strcpy (note->header.name, GRUB_IEEE1275_NOTE_NAME); - note->descriptor.real_mode = grub_host_to_target32 (0xffffffff); - note->descriptor.real_base = grub_host_to_target32 (0x00c00000); - note->descriptor.real_size = grub_host_to_target32 (0xffffffff); - note->descriptor.virt_base = grub_host_to_target32 (0xffffffff); - note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); - note->descriptor.load_base = grub_host_to_target32 (0x00004000); - - phdr[1].p_type = grub_host_to_target32 (PT_NOTE); - phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr[1].p_vaddr = 0; - phdr[1].p_paddr = 0; - phdr[1].p_filesz = grub_host_to_target32 (note_size); - phdr[1].p_memsz = 0; - phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); - } - - free (core_img); - core_img = elf_img; - core_size = program_size + header_size + footer_size; - } -#endif grub_util_write_image (core_img, core_size, out); free (kernel_img); @@ -1368,9 +1499,7 @@ static struct option options[] = {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, {"note", no_argument, 0, 'n'}, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT {"format", required_argument, 0, 'O'}, -#endif {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, @@ -1383,7 +1512,24 @@ usage (int status) if (status) fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); else - printf (_("\ + { + int format_len = 0; + char *formats; + char *ptr; + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + format_len += strlen (image_targets[i].name) + 2; + ptr = formats = xmalloc (format_len); + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + { + strcpy (ptr, image_targets[i].name); + ptr += strlen (image_targets[i].name); + *ptr++ = ','; + *ptr++ = ' '; + } + ptr[-2] = 0; + + printf (_("\ Usage: %s [OPTION]... [MODULES]\n\ \n\ Make a bootable image of GRUB.\n\ @@ -1394,25 +1540,20 @@ Make a bootable image of GRUB.\n\ -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ -n, --note add NOTE segment for CHRP Open Firmware\n\ - -o, --output=FILE output a generated image to FILE [default=stdout]\n" -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - "\ - -O, --format=FORMAT generate an image in format [default=%s]\n\ - available formats: %s\n" -#endif - "\ + -o, --output=FILE output a generated image to FILE [default=stdout]\n\ + -O, --format=FORMAT generate an image in format\n\ + available formats: %s\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ "), -program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT, GRUB_PLATFORM_IMAGE_FORMATS, -#endif -PACKAGE_BUGREPORT); - + program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, + formats, + PACKAGE_BUGREPORT); + free (formats); + } exit (status); } @@ -1427,9 +1568,7 @@ main (int argc, char *argv[]) char *config = NULL; FILE *fp = stdout; int note = 0; -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; -#endif + struct image_target_desc *image_target = NULL; set_program_name (argv[0]); @@ -1451,27 +1590,19 @@ main (int argc, char *argv[]) output = xstrdup (optarg); break; -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT case 'O': -#ifdef GRUB_PLATFORM_IMAGE_RAW - if (strcmp (optarg, "raw") == 0) - format = GRUB_PLATFORM_IMAGE_RAW; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_ELF - if (strcmp (optarg, "elf") == 0) - format = GRUB_PLATFORM_IMAGE_ELF; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_AOUT - if (strcmp (optarg, "aout") == 0) - format = GRUB_PLATFORM_IMAGE_AOUT; - else -#endif - usage (1); - break; -#endif - + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + if (strcmp (optarg, image_targets[i].name) == 0) + image_target = &image_targets[i]; + if (!image_target) + { + printf ("unknown target %s\n", optarg); + usage (1); + } + break; + } case 'd': if (dir) free (dir); @@ -1534,6 +1665,12 @@ main (int argc, char *argv[]) } } + if (!image_target) + { + printf ("Target not specified.\n"); + usage (1); + } + if (output) { fp = fopen (output, "wb"); @@ -1544,12 +1681,7 @@ main (int argc, char *argv[]) generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - format, -#else - 0, -#endif - note); + image_target, note); fclose (fp); diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index aafdfb059..7d553a767 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -171,7 +171,7 @@ fi if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ + grub-mkimage -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img From 94ac7906451fc65323122507c595b790fb2b4644 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 10:56:12 +0200 Subject: [PATCH 32/38] Fix various issues created by previous commits --- Makefile.in | 4 +- boot/i386/qemu/boot.S | 2 +- boot/sparc64/ieee1275/diskboot.S | 11 +- configure.ac | 1 + include/grub/efi/pe32.h | 60 +++++++-- include/grub/i386/pc/boot.h | 1 - include/grub/i386/pc/kernel.h | 2 - include/grub/i386/pc/memory.h | 1 - include/grub/i386/qemu/kernel.h | 9 +- include/grub/offsets.h | 101 ++++++++++++++++ include/grub/powerpc/ieee1275/kernel.h | 18 +-- kern/i386/qemu/startup.S | 2 +- util/grub-mkimage.c | 161 ++++++++++++++++++------- 13 files changed, 285 insertions(+), 88 deletions(-) create mode 100644 include/grub/offsets.h diff --git a/Makefile.in b/Makefile.in index 822a08797..3df8b1b72 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS) ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ - -DGRUB_LIBDIR=\"$(pkglibdir)\" -DLOCALEDIR=\"$(localedir)\" + -DGRUB_LIBDIR=\"$(libdir)\" -DLOCALEDIR=\"$(localedir)\" TARGET_CC = @TARGET_CC@ TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@ TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@ @@ -287,7 +287,7 @@ build_env.mk: Makefile echo "TARGET_CC=$(TARGET_CC)" ; \ echo "TARGET_CFLAGS=$(TARGET_CFLAGS)" ; \ echo "TARGET_ASFLAGS=$(TARGET_ASFLAGS)" ; \ - echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(pkglibdir) -I$(includedir)" ; \ + echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(libdir) -I$(includedir)" ; \ echo "STRIP=$(STRIP)" ; \ echo "OBJCONV=$(OBJCONV)" ; \ echo "TARGET_MODULE_FORMAT=$(TARGET_MODULE_FORMAT)" ; \ diff --git a/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S index a93fe3943..51039dd69 100644 --- a/boot/i386/qemu/boot.S +++ b/boot/i386/qemu/boot.S @@ -31,7 +31,7 @@ _start: jmp 1f - . = _start + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR + . = _start + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 1: diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S index a4d4b5bf9..a8fd50d87 100644 --- a/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -19,6 +19,7 @@ #include #include +#include .text .align 4 @@ -87,8 +88,8 @@ after_info_block: call console_write mov NOTIFICATION_STRING_LEN, %o3 - GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2) - set GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3 + GET_ABS(firstlist - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2) + set GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS, %l3 bootloop: lduw [%l2 + 0x08], %o0 brz %o0, bootit @@ -115,7 +116,7 @@ bootloop: mov NOTIFICATION_STEP_LEN, %o3 ba bootloop - sub %l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2 + sub %l2, GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2 bootit: GET_ABS(prom_close_name, %o0) @@ -127,8 +128,8 @@ bootit: GET_ABS(notification_done, %o2) call console_write mov NOTIFICATION_DONE_LEN, %o3 - sethi %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2 - jmpl %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7 + sethi %hi(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o2 + jmpl %o2 + %lo(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o7 mov CIF_REG, %o4 1: ba,a 1b diff --git a/configure.ac b/configure.ac index 4bfc5a2b0..e3453b636 100644 --- a/configure.ac +++ b/configure.ac @@ -148,6 +148,7 @@ case "$target_cpu" in mips) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_MIPS=1" ;; sparc64) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_SPARC64=1" ;; esac +machine_CFLAGS="$machine_CFLAGS -DMACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" CFLAGS="$CFLAGS $machine_CFLAGS" TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS" diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 21b56ae27..9d9edc220 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -99,12 +99,8 @@ struct grub_pe32_optional_header grub_uint32_t entry_addr; grub_uint32_t code_base; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 grub_uint32_t data_base; grub_uint32_t image_base; -#else - grub_uint64_t image_base; -#endif grub_uint32_t section_alignment; grub_uint32_t file_alignment; @@ -121,22 +117,66 @@ struct grub_pe32_optional_header grub_uint16_t subsystem; grub_uint16_t dll_characteristics; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - grub_uint32_t stack_reserve_size; grub_uint32_t stack_commit_size; grub_uint32_t heap_reserve_size; grub_uint32_t heap_commit_size; -#else + grub_uint32_t loader_flags; + grub_uint32_t num_data_directories; + + /* Data directories. */ + struct grub_pe32_data_directory export_table; + struct grub_pe32_data_directory import_table; + struct grub_pe32_data_directory resource_table; + struct grub_pe32_data_directory exception_table; + struct grub_pe32_data_directory certificate_table; + struct grub_pe32_data_directory base_relocation_table; + struct grub_pe32_data_directory debug; + struct grub_pe32_data_directory architecture; + struct grub_pe32_data_directory global_ptr; + struct grub_pe32_data_directory tls_table; + struct grub_pe32_data_directory load_config_table; + struct grub_pe32_data_directory bound_import; + struct grub_pe32_data_directory iat; + struct grub_pe32_data_directory delay_import_descriptor; + struct grub_pe32_data_directory com_runtime_header; + struct grub_pe32_data_directory reserved_entry; +}; + +struct grub_pe64_optional_header +{ + grub_uint16_t magic; + grub_uint8_t major_linker_version; + grub_uint8_t minor_linker_version; + grub_uint32_t code_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t entry_addr; + grub_uint32_t code_base; + + grub_uint64_t image_base; + + grub_uint32_t section_alignment; + grub_uint32_t file_alignment; + grub_uint16_t major_os_version; + grub_uint16_t minor_os_version; + grub_uint16_t major_image_version; + grub_uint16_t minor_image_version; + grub_uint16_t major_subsystem_version; + grub_uint16_t minor_subsystem_version; + grub_uint32_t reserved; + grub_uint32_t image_size; + grub_uint32_t header_size; + grub_uint32_t checksum; + grub_uint16_t subsystem; + grub_uint16_t dll_characteristics; grub_uint64_t stack_reserve_size; grub_uint64_t stack_commit_size; grub_uint64_t heap_reserve_size; grub_uint64_t heap_commit_size; -#endif - grub_uint32_t loader_flags; grub_uint32_t num_data_directories; @@ -221,6 +261,8 @@ struct grub_pe32_header struct grub_pe32_optional_header optional_header; }; +#define GRUB_PE32_SIGNATURE_SIZE 4 + struct grub_pe32_fixup_block { grub_uint32_t page_rva; diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index 09d01caee..a4d42ff3c 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -19,7 +19,6 @@ #ifndef GRUB_BOOT_MACHINE_HEADER #define GRUB_BOOT_MACHINE_HEADER 1 -#define MACHINE I386_PC #include /* The signature for bootloader. */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 77d5c6e5a..f0a9d4fc2 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -19,8 +19,6 @@ #ifndef KERNEL_MACHINE_HEADER #define KERNEL_MACHINE_HEADER 1 -#define MACHINE I386_PC - #include /* Enable LZMA compression */ diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 0b4191734..68f5e8bc9 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -29,7 +29,6 @@ #include -#define MACHINE I386_PC #include /* The scratch buffer used in real mode code. */ diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index 3d22c9d9f..e29f0aeb2 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -19,14 +19,7 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x10 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 +#include #ifndef ASM_FILE diff --git a/include/grub/offsets.h b/include/grub/offsets.h new file mode 100644 index 000000000..a0c2f61f9 --- /dev/null +++ b/include/grub/offsets.h @@ -0,0 +1,101 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2007,2008 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 OFFSETS_HEADER +#define OFFSETS_HEADER 1 + +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x10 + +/* The offset of GRUB_INSTALL_DOS_PART. */ +#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x14 + +/* The offset of GRUB_INSTALL_BSD_PART. */ +#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x18 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_PC_PREFIX 0x1c + +/* End of the data section. */ +#define GRUB_KERNEL_I386_PC_DATA_END 0x5c + +/* The size of the first region which won't be compressed. */ +#define GRUB_KERNEL_I386_PC_RAW_SIZE (GRUB_KERNEL_I386_PC_DATA_END + 0x5F0) + +/* The segment where the kernel is loaded. */ +#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 + +/* The upper memory area (starting at 640 kiB). */ +#define GRUB_MEMORY_I386_PC_UPPER 0xa0000 +#define GRUB_MEMORY_I386_QEMU_UPPER GRUB_MEMORY_I386_PC_UPPER + +/* The offset of GRUB_CORE_ENTRY_ADDR. */ +#define GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR 0x4 + +/* The offset of GRUB_CORE_ENTRY_ADDR. */ +#define GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_QEMU_PREFIX 0x10 + +/* End of the data section. */ +#define GRUB_KERNEL_I386_QEMU_DATA_END 0x50 + +#define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 + +#define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 + +#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 +#define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 +#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 + +#ifdef MACHINE +#define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c +#define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) +#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE) +#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE) +#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) + +#define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX) +#define GRUB_KERNEL_MACHINE_DATA_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _DATA_END) +#define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, MACHINE, _KERNEL_SEG) +#define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, MACHINE, _UPPER) +#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _RAW_SIZE) +#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_BSD_PART) +#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_DOS_PART) +#endif + +#ifndef ASM_FILE +struct grub_pc_bios_boot_blocklist +{ + grub_uint64_t start; + grub_uint16_t len; + grub_uint16_t segment; +} __attribute__ ((packed)); +#endif + +#endif diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h index 229416243..75d6c62a6 100644 --- a/include/grub/powerpc/ieee1275/kernel.h +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -20,28 +20,12 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include +#include -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW -#define GRUB_KERNEL_MACHINE_PREFIX 0x4 -#define GRUB_KERNEL_MACHINE_DATA_END 0x44 -#define GRUB_KERNEL_MACHINE_LINK_ALIGN 4 - -#define EM_TARGET EM_PPC #define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_ELF -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF - /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/kern/i386/qemu/startup.S b/kern/i386/qemu/startup.S index 7484650b2..dc40cc4a2 100644 --- a/kern/i386/qemu/startup.S +++ b/kern/i386/qemu/startup.S @@ -27,7 +27,7 @@ _start: jmp codestart - . = _start + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR + . = _start + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 VARIABLE(grub_kernel_image_size) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index af2988a3f..08003a07f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -72,6 +72,7 @@ struct image_target_desc unsigned section_align; signed vaddr_offset; unsigned install_dos_part, install_bsd_part; + grub_uint64_t link_addr; }; struct image_target_desc image_targets[] = @@ -90,8 +91,11 @@ struct image_target_desc image_targets[] = }, {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), GRUB_PE32_SECTION_ALIGNMENT) }, {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, @@ -102,8 +106,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0}, {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), GRUB_PE32_SECTION_ALIGNMENT) }, {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, @@ -1150,19 +1157,35 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], case IMAGE_EFI: { void *pe_img; + grub_uint8_t *header; size_t pe_size; - struct grub_pe32_header *header; struct grub_pe32_coff_header *c; - struct grub_pe32_optional_header *o; struct grub_pe32_section_table *text_section, *data_section; struct grub_pe32_section_table *mods_section, *reloc_section; static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), - image_target->section_align); - int reloc_addr = ALIGN_UP (header_size + core_size, image_target->section_align); + int header_size; + int reloc_addr; - pe_size = ALIGN_UP (reloc_addr + reloc_size, image_target->section_align); + if (image_target->voidp_sizeof == 4) + header_size = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT); + else + header_size = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT); + + reloc_addr = ALIGN_UP (header_size + core_size, + image_target->section_align); + + pe_size = ALIGN_UP (reloc_addr + reloc_size, + image_target->section_align); pe_img = xmalloc (reloc_addr + reloc_size); memset (pe_img, 0, header_size); memcpy (pe_img + header_size, core_img, core_size); @@ -1170,11 +1193,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], header = pe_img; /* The magic. */ - memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); - memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE); + memcpy (header + GRUB_PE32_MSDOS_STUB_SIZE, "PE\0\0", + GRUB_PE32_SIGNATURE_SIZE); /* The COFF file header. */ - c = &header->coff_header; + c = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE; if (image_target->voidp_sizeof == 4) c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); else @@ -1182,7 +1206,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], c->num_sections = grub_host_to_target16 (4); c->time = grub_host_to_target32 (time (0)); - c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE | GRUB_PE32_LINE_NUMS_STRIPPED | ((image_target->voidp_sizeof == 4) @@ -1192,33 +1215,74 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], | GRUB_PE32_DEBUG_STRIPPED); /* The PE Optional header. */ - o = &header->optional_header; - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); - o->bss_size = grub_cpu_to_le32 (bss_size); - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (header_size); if (image_target->voidp_sizeof == 4) - o->data_base = grub_host_to_target32 (header_size + exec_size); - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (image_target->section_align); - o->file_alignment = grub_host_to_target32 (image_target->section_align); - o->image_size = grub_host_to_target32 (pe_size); - o->header_size = grub_host_to_target32 (header_size); - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + { + struct grub_pe32_optional_header *o; - /* Do these really matter? */ - o->stack_reserve_size = grub_host_to_target32 (0x10000); - o->stack_commit_size = grub_host_to_target32 (0x10000); - o->heap_reserve_size = grub_host_to_target32 (0x10000); - o->heap_commit_size = grub_host_to_target32 (0x10000); + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + + o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + + o->data_base = grub_host_to_target32 (header_size + exec_size); + + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); - o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); - o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + } + else + { + struct grub_pe64_optional_header *o; + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + + o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories + = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + } /* The sections. */ text_section = (struct grub_pe32_section_table *) (header + 1); strcpy (text_section->name, ".text"); @@ -1422,10 +1486,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); if (image_target->id == IMAGE_YEELOONG_ELF) - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); + target_addr = ALIGN_UP (image_target->link_addr + + kernel_size + total_module_size, 32); else - target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; + target_addr = image_target->link_addr; ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); @@ -1534,7 +1598,7 @@ Usage: %s [OPTION]... [MODULES]\n\ \n\ Make a bootable image of GRUB.\n\ \n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ + -d, --directory=DIR use images and modules under DIR [default=%s/@platform@]\n\ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ -f, --font=FILE embed FILE as a boot font\n\ @@ -1679,6 +1743,21 @@ main (int argc, char *argv[]) free (output); } + if (!dir) + { + const char *last; + last = strchr (image_target->name, '-'); + if (last) + last = strchr (last + 1, '-'); + if (!last) + last = image_target->name + strlen (image_target->name); + dir = xmalloc (sizeof (GRUB_LIBDIR) + (last - image_target->name)); + memcpy (dir, GRUB_LIBDIR, sizeof (GRUB_LIBDIR) - 1); + memcpy (dir + sizeof (GRUB_LIBDIR) - 1, image_target->name, + last - image_target->name); + *(dir + sizeof (GRUB_LIBDIR) - 1 + (last - image_target->name)) = 0; + } + generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, image_target, note); From 0253aeb7a1ae7c4bc03f4fa4f4c34ff73f4d9ff4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 13:11:43 +0200 Subject: [PATCH 33/38] Unified grub-mkimage achieved --- conf/common.rmk | 1 - conf/i386-pc.rmk | 4 +- include/grub/efi/pe32.h | 9 +- include/grub/kernel.h | 26 +- include/grub/offsets.h | 2 + util/grub-mkimage.c | 767 ++++------------------------------------ util/grub-mkimagexx.c | 741 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 836 insertions(+), 714 deletions(-) create mode 100644 util/grub-mkimagexx.c diff --git a/conf/common.rmk b/conf/common.rmk index bab7effb9..98dca34f9 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -18,7 +18,6 @@ endif bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkimage.c_DEPENDENCIES = Makefile # For grub-probe. diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 1e0a3ff58..f0da94b42 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -1,7 +1,5 @@ # -*- makefile -*- -GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 - COMMON_CFLAGS = -mrtd -mregparm=3 # Images. @@ -58,7 +56,7 @@ kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ machine/pxe.h i386/pit.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8200 $(COMMON_CFLAGS) # Utilities. sbin_UTILITIES = grub-setup diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 9d9edc220..90f9c9f5c 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -199,15 +199,8 @@ struct grub_pe64_optional_header struct grub_pe32_data_directory reserved_entry; }; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - #define GRUB_PE32_PE32_MAGIC 0x10b - -#else - -#define GRUB_PE32_PE32_MAGIC 0x20b - -#endif +#define GRUB_PE32_PE64_MAGIC 0x20b #define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10 diff --git a/include/grub/kernel.h b/include/grub/kernel.h index bf52ffcb4..f7740b2e3 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -42,19 +42,33 @@ struct grub_module_header /* "gmim" (GRUB Module Info Magic). */ #define GRUB_MODULE_MAGIC 0x676d696d -struct grub_module_info +struct grub_module_info32 { /* Magic number so we know we have modules present. */ grub_uint32_t magic; -#if GRUB_TARGET_SIZEOF_VOID_P == 8 - grub_uint32_t padding; -#endif /* The offset of the modules. */ - grub_target_off_t offset; + grub_uint32_t offset; /* The size of all modules plus this header. */ - grub_target_size_t size; + grub_uint32_t size; }; +struct grub_module_info64 +{ + /* Magic number so we know we have modules present. */ + grub_uint32_t magic; + grub_uint32_t padding; + /* The offset of the modules. */ + grub_uint64_t offset; + /* The size of all modules plus this header. */ + grub_uint64_t size; +}; + +#if GRUB_TARGET_SIZEOF_VOID_P == 8 +#define grub_module_info grub_module_info64 +#else +#define grub_module_info grub_module_info32 +#endif + extern grub_addr_t grub_arch_modules_addr (void); extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *)); diff --git a/include/grub/offsets.h b/include/grub/offsets.h index a0c2f61f9..2ba6351ca 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -46,6 +46,8 @@ /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 +#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x8200 + /* The upper memory area (starting at 640 kiB). */ #define GRUB_MEMORY_I386_PC_UPPER 0xa0000 #define GRUB_MEMORY_I386_QEMU_UPPER GRUB_MEMORY_I386_PC_UPPER diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 08003a07f..c9bafdd8b 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -131,6 +131,9 @@ struct image_target_desc image_targets[] = #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) #define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x))) +#define grub_target_to_host64(x) (grub_target_to_host64_real (image_target, (x))) +#define grub_host_to_target64(x) (grub_host_to_target64_real (image_target, (x))) +#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (image_target, (x))) #define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x))) #define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x))) @@ -152,13 +155,13 @@ grub_target_to_host64_real (struct image_target_desc *image_target, grub_uint64_ return grub_le_to_cpu64 (in); } -static inline grub_uint32_t -grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +static inline grub_uint64_t +grub_host_to_target64_real (struct image_target_desc *image_target, grub_uint64_t in) { - if (image_target->voidp_sizeof == 8) - return grub_target_to_host64_real (image_target, in); + if (image_target->bigendian) + return grub_cpu_to_be64 (in); else - return grub_target_to_host32_real (image_target, in); + return grub_cpu_to_le64 (in); } static inline grub_uint32_t @@ -188,6 +191,24 @@ grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_ return grub_cpu_to_le16 (in); } +static inline grub_uint32_t +grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_host_to_target64_real (image_target, in); + else + return grub_host_to_target32_real (image_target, in); +} + +static inline grub_uint32_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_target_to_host64_real (image_target, in); + else + return grub_target_to_host32_real (image_target, in); +} + #define GRUB_IEEE1275_NOTE_NAME "PowerPC" #define GRUB_IEEE1275_NOTE_TYPE 0x1275 @@ -274,230 +295,6 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, *core_size = kernel_size; } - -/* Relocate symbols; note that this function overwrites the symbol table. - Return the address of a start symbol. */ -static Elf_Addr -relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Shdr *symtab_section, Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections, - struct image_target_desc *image_target) -{ - Elf_Word symtab_size, sym_size, num_syms; - Elf_Off symtab_offset; - Elf_Addr start_address = 0; - Elf_Sym *sym; - Elf_Word i; - Elf_Shdr *strtab_section; - const char *strtab; - - strtab_section - = (Elf_Shdr *) ((char *) sections - + (grub_target_to_host32 (symtab_section->sh_link) - * section_entsize)); - strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); - - symtab_size = grub_target_to_host32 (symtab_section->sh_size); - sym_size = grub_target_to_host32 (symtab_section->sh_entsize); - symtab_offset = grub_target_to_host32 (symtab_section->sh_offset); - num_syms = symtab_size / sym_size; - - for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); - i < num_syms; - i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) - { - Elf_Section index; - const char *name; - - name = strtab + grub_target_to_host32 (sym->st_name); - - index = grub_target_to_host16 (sym->st_shndx); - if (index == STN_ABS) - { - continue; - } - else if ((index == STN_UNDEF)) - { - if (sym->st_name) - grub_util_error ("undefined symbol %s", name); - else - continue; - } - else if (index >= num_sections) - grub_util_error ("section %d does not exist", index); - - sym->st_value = (grub_target_to_host32 (sym->st_value) - + section_addresses[index]); - grub_util_info ("locating %s at 0x%x", name, sym->st_value); - - if (! start_address) - if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) - start_address = sym->st_value; - } - - return start_address; -} - -/* Return the address of a symbol at the index I in the section S. */ -static Elf_Addr -get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, - struct image_target_desc *image_target) -{ - Elf_Sym *sym; - - sym = (Elf_Sym *) ((char *) e - + grub_target_to_host32 (s->sh_offset) - + i * grub_target_to_host32 (s->sh_entsize)); - return sym->st_value; -} - -/* Return the address of a modified value. */ -static Elf_Addr * -get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, - struct image_target_desc *image_target) -{ - return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); -} - -/* Deal with relocation information. This function relocates addresses - within the virtual address space starting from 0. So only relative - addresses can be fully resolved. Absolute addresses must be relocated - again by a PE32 relocator when loaded. */ -static void -relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab, struct image_target_desc *image_target) -{ - Elf_Half i; - Elf_Shdr *s; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || - (s->sh_type == grub_host_to_target32 (SHT_RELA))) - { - Elf_Rela *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Shdr *symtab_section; - Elf_Word target_section_index; - Elf_Addr target_section_addr; - Elf_Shdr *target_section; - Elf_Word j; - - symtab_section = (Elf_Shdr *) ((char *) sections - + (grub_target_to_host32 (s->sh_link) - * section_entsize)); - target_section_index = grub_target_to_host32 (s->sh_info); - target_section_addr = section_addresses[target_section_index]; - target_section = (Elf_Shdr *) ((char *) sections - + (target_section_index - * section_entsize)); - - grub_util_info ("dealing with the relocation section %s for %s", - strtab + grub_target_to_host32 (s->sh_name), - strtab + grub_target_to_host32 (target_section->sh_name)); - - rtab_size = grub_target_to_host32 (s->sh_size); - r_size = grub_target_to_host32 (s->sh_entsize); - rtab_offset = grub_target_to_host32 (s->sh_offset); - num_rs = rtab_size / r_size; - - for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rela *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - Elf_Addr sym_addr; - Elf_Addr *target; - Elf_Addr addend; - - offset = grub_target_to_host (r->r_offset); - target = get_target_address (e, target_section, offset, image_target); - info = grub_target_to_host (r->r_info); - sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info), image_target); - - addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? - r->r_addend : 0; - - if (image_target->voidp_sizeof == 4) - switch (ELF_R_TYPE (info)) - { - case R_386_NONE: - break; - - case R_386_32: - /* This is absolute. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - - case R_386_PC32: - /* This is relative. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr - - target_section_addr - offset - - image_target->vaddr_offset); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } - else - switch (ELF_R_TYPE (info)) - { - - case R_X86_64_NONE: - break; - - case R_X86_64_64: - *target = grub_host_to_target64 (grub_target_to_host64 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", - *target, offset); - break; - - case R_X86_64_PC32: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr - - target_section_addr - offset - - image_target->vaddr_offset); - grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - - case R_X86_64_32: - case R_X86_64_32S: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } - } - } -} - struct fixup_block_list { struct fixup_block_list *next; @@ -505,457 +302,13 @@ struct fixup_block_list struct grub_pe32_fixup_block b; }; -/* Add a PE32's fixup entry for a relocation. Return the resulting address - after having written to the file OUT. */ -Elf_Addr -add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address, - struct image_target_desc *image_target) -{ - struct grub_pe32_fixup_block *b; +#define MKIMAGE_ELF32 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF32 - b = &((*cblock)->b); - - /* First, check if it is necessary to write out the current block. */ - if ((*cblock)->state) - { - if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) - { - grub_uint32_t size; - - if (flush) - { - /* Add as much padding as necessary to align the address - with a section boundary. */ - Elf_Addr next_address; - unsigned padding_size; - size_t index; - - next_address = current_address + b->block_size; - padding_size = ((ALIGN_UP (next_address, image_target->section_align) - - next_address) - >> 1); - index = ((b->block_size - sizeof (*b)) >> 1); - grub_util_info ("adding %d padding fixup entries", padding_size); - while (padding_size--) - { - b->entries[index++] = 0; - b->block_size += 2; - } - } - else if (b->block_size & (8 - 1)) - { - /* If not aligned with a 32-bit boundary, add - a padding entry. */ - size_t index; - - grub_util_info ("adding a padding fixup entry"); - index = ((b->block_size - sizeof (*b)) >> 1); - b->entries[index] = 0; - b->block_size += 2; - } - - /* Flush it. */ - grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", - b->block_size, b->page_rva); - size = b->block_size; - current_address += size; - b->page_rva = grub_host_to_target32 (b->page_rva); - b->block_size = grub_host_to_target32 (b->block_size); - (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); - memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); - *cblock = (*cblock)->next; - } - } - - b = &((*cblock)->b); - - if (! flush) - { - grub_uint16_t entry; - size_t index; - - /* If not allocated yet, allocate a block with enough entries. */ - if (! (*cblock)->state) - { - (*cblock)->state = 1; - - /* The spec does not mention the requirement of a Page RVA. - Here, align the address with a 4K boundary for safety. */ - b->page_rva = (addr & ~(0x1000 - 1)); - b->block_size = sizeof (*b); - } - - /* Sanity check. */ - if (b->block_size >= sizeof (*b) + 2 * 0x1000) - grub_util_error ("too many fixup entries"); - - /* Add a new entry. */ - index = ((b->block_size - sizeof (*b)) >> 1); - entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); - b->entries[index] = grub_host_to_target16 (entry); - b->block_size += 2; - } - - return current_address; -} - -/* Make a .reloc section. */ -static Elf_Addr -make_reloc_section (Elf_Ehdr *e, void **out, - Elf_Addr *section_addresses, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab, struct image_target_desc *image_target) -{ - Elf_Half i; - Elf_Shdr *s; - struct fixup_block_list *lst, *lst0; - Elf_Addr current_address = 0; - - lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); - memset (lst, 0, sizeof (*lst) + 2 * 0x1000); - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || - (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) - { - Elf_Rel *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Addr section_address; - Elf_Word j; - - grub_util_info ("translating the relocation section %s", - strtab + grub_le_to_cpu32 (s->sh_name)); - - rtab_size = grub_le_to_cpu32 (s->sh_size); - r_size = grub_le_to_cpu32 (s->sh_entsize); - rtab_offset = grub_le_to_cpu32 (s->sh_offset); - num_rs = rtab_size / r_size; - - section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; - - for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rel *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - - offset = grub_le_to_cpu32 (r->r_offset); - info = grub_le_to_cpu32 (r->r_info); - - /* Necessary to relocate only absolute addresses. */ - if (image_target->voidp_sizeof == 4) - { - if (ELF_R_TYPE (info) == R_386_32) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%x", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address, - image_target); - } - } - else - { - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) - { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address, - image_target); - } - } - } - } - - current_address = add_fixup_entry (&lst, 0, 0, 1, current_address, image_target); - - { - grub_uint8_t *ptr; - ptr = *out = xmalloc (current_address); - for (lst = lst0; lst; lst = lst->next) - if (lst->state) - { - memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); - ptr += grub_target_to_host32 (lst->b.block_size); - } - if (current_address + *out != ptr) - { - grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, - current_address); - } - } - - return current_address; -} - -/* Determine if this section is a text section. Return false if this - section is not allocated. */ -static int -is_text_section (Elf_Shdr *s, struct image_target_desc *image_target) -{ - if (image_target->id != IMAGE_EFI - && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) - return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) - == (SHF_EXECINSTR | SHF_ALLOC)); -} - -/* Determine if this section is a data section. This assumes that - BSS is also a data section, since the converter initializes BSS - when producing PE32 to avoid a bug in EFI implementations. */ -static int -is_data_section (Elf_Shdr *s, struct image_target_desc *image_target) -{ - if (image_target->id != IMAGE_EFI - && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) - return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) - == SHF_ALLOC); -} - -/* Locate section addresses by merging code sections and data sections - into .text and .data, respectively. Return the array of section - addresses. */ -static Elf_Addr * -locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, - Elf_Half num_sections, const char *strtab, - grub_size_t *exec_size, grub_size_t *kernel_sz, - struct image_target_desc *image_target) -{ - int i; - Elf_Addr current_address; - Elf_Addr *section_addresses; - Elf_Shdr *s; - - section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); - memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); - - current_address = 0; - - /* .text */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s, image_target)) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - align) - image_target->vaddr_offset; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); - } - - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - image_target->section_align) - - image_target->vaddr_offset; - *exec_size = current_address; - - /* .data */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s, image_target)) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - align) - - image_target->vaddr_offset; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); - } - - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - image_target->section_align) - image_target->vaddr_offset; - *kernel_sz = current_address; - return section_addresses; -} - -/* Return if the ELF header is valid. */ -static int -check_elf_header (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) -{ - if (size < sizeof (*e) - || e->e_ident[EI_MAG0] != ELFMAG0 - || e->e_ident[EI_MAG1] != ELFMAG1 - || e->e_ident[EI_MAG2] != ELFMAG2 - || e->e_ident[EI_MAG3] != ELFMAG3 - || e->e_ident[EI_VERSION] != EV_CURRENT - || e->e_version != grub_host_to_target32 (EV_CURRENT)) - return 0; - - return 1; -} - -static char * -load_image (const char *kernel_path, grub_size_t *exec_size, - grub_size_t *kernel_sz, grub_size_t *bss_size, - grub_size_t total_module_size, Elf_Addr *start, - void **reloc_section, grub_size_t *reloc_size, - struct image_target_desc *image_target) -{ - char *kernel_img, *out_img; - const char *strtab; - Elf_Ehdr *e; - Elf_Shdr *sections; - Elf_Addr *section_addresses; - Elf_Addr *section_vaddresses; - int i; - Elf_Shdr *s; - Elf_Half num_sections; - Elf_Off section_offset; - Elf_Half section_entsize; - grub_size_t kernel_size; - Elf_Shdr *symtab_section; - - *start = 0; - - kernel_size = grub_util_get_image_size (kernel_path); - kernel_img = xmalloc (kernel_size); - grub_util_load_image (kernel_path, kernel_img); - - e = (Elf_Ehdr *) kernel_img; - if (! check_elf_header (e, kernel_size, image_target)) - grub_util_error ("invalid ELF header"); - - section_offset = grub_target_to_host32 (e->e_shoff); - section_entsize = grub_target_to_host16 (e->e_shentsize); - num_sections = grub_target_to_host16 (e->e_shnum); - - if (kernel_size < section_offset + section_entsize * num_sections) - grub_util_error ("invalid ELF format"); - - sections = (Elf_Shdr *) (kernel_img + section_offset); - - /* Relocate sections then symbols in the virtual address space. */ - s = (Elf_Shdr *) ((char *) sections - + grub_host_to_target16 (e->e_shstrndx) * section_entsize); - strtab = (char *) e + grub_host_to_target32 (s->sh_offset); - - section_addresses = locate_sections (sections, section_entsize, - num_sections, strtab, - exec_size, kernel_sz, image_target); - - if (image_target->id == IMAGE_EFI) - { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; - -#if 0 - { - Elf_Addr current_address = *kernel_sz; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); - } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; - } -#else - *bss_size = 0; -#endif - - symtab_section = NULL; - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) - { - symtab_section = s; - break; - } - - if (! symtab_section) - grub_util_error ("no symbol table"); - - *start = relocate_symbols (e, sections, symtab_section, - section_vaddresses, section_entsize, - num_sections, image_target); - if (*start == 0) - grub_util_error ("start symbol is not defined"); - - /* Resolve addresses in the virtual address space. */ - relocate_addresses (e, sections, section_addresses, section_entsize, - num_sections, strtab, image_target); - - *reloc_size = make_reloc_section (e, reloc_section, - section_vaddresses, sections, - section_entsize, num_sections, - strtab, image_target); - - } - else - { - *bss_size = 0; - *reloc_size = 0; - *reloc_section = NULL; - } - - out_img = xmalloc (*kernel_sz + total_module_size); - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s, image_target) || is_text_section (s, image_target)) - { - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - memset (out_img + section_addresses[i], 0, - grub_host_to_target32 (s->sh_size)); - else - memcpy (out_img + section_addresses[i], - kernel_img + grub_host_to_target32 (s->sh_offset), - grub_host_to_target32 (s->sh_size)); - } - free (kernel_img); - - return out_img; -} +#define MKIMAGE_ELF64 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF64 static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], @@ -968,16 +321,18 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; - struct grub_module_info *modinfo; grub_size_t bss_size; - Elf_Addr start_address; + grub_uint64_t start_address; void *rel_section; grub_size_t reloc_size; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); - total_module_size = sizeof (struct grub_module_info); + if (image_target->voidp_sizeof == 8) + total_module_size = sizeof (struct grub_module_info64); + else + total_module_size = sizeof (struct grub_module_info32); if (memdisk_path) { @@ -1006,22 +361,42 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_info ("the total module size is 0x%x", total_module_size); - kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, - total_module_size, &start_address, &rel_section, - &reloc_size, image_target); + if (image_target->voidp_sizeof == 4) + kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, image_target); + else + kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, image_target); if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); strcpy (kernel_img + image_target->prefix, prefix); - /* Fill in the grub_module_info structure. */ - modinfo = (struct grub_module_info *) (kernel_img + kernel_size); - memset (modinfo, 0, sizeof (struct grub_module_info)); - modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); - modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info)); - modinfo->size = grub_host_to_target_addr (total_module_size); + if (image_target->voidp_sizeof == 8) + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info64 *modinfo; + modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info64)); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64)); + modinfo->size = grub_host_to_target_addr (total_module_size); + offset = kernel_size + sizeof (struct grub_module_info64); + } + else + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info32 *modinfo; + modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info32)); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32)); + modinfo->size = grub_host_to_target_addr (total_module_size); + offset = kernel_size + sizeof (struct grub_module_info32); + } - offset = kernel_size + sizeof (struct grub_module_info); for (p = path_list; p; p = p->next) { struct grub_module_header *header; @@ -1119,9 +494,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *boot_path, *boot_img; size_t boot_size; - if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) + if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) grub_util_error (_("core image is too big (%p > %p)"), - GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, + GRUB_KERNEL_I386_PC_LINK_ADDR + core_size, GRUB_MEMORY_I386_PC_UPPER); num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); @@ -1258,7 +633,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + sizeof (struct grub_pe32_coff_header); - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); o->code_size = grub_host_to_target32 (exec_size); o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); o->bss_size = grub_cpu_to_le32 (bss_size); @@ -1523,7 +898,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr[1].p_type = grub_host_to_target32 (PT_NOTE); phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_align = grub_host_to_target32 (image_target->voidp_sizeof); phdr[1].p_vaddr = 0; phdr[1].p_paddr = 0; phdr[1].p_filesz = grub_host_to_target32 (note_size); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c new file mode 100644 index 000000000..eb0c7a514 --- /dev/null +++ b/util/grub-mkimagexx.c @@ -0,0 +1,741 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,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 . + */ + +#if defined(MKIMAGE_ELF32) +# define SUFFIX(x) x ## 32 +# define ELFCLASSXX ELFCLASS32 +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Phdr Elf32_Phdr +# define Elf_Addr Elf32_Addr +# define Elf_Sym Elf32_Sym +# define Elf_Off Elf32_Off +# define Elf_Shdr Elf32_Shdr +# define Elf_Rela Elf32_Rela +# define Elf_Rel Elf32_Rel +# define ELF_R_SYM(val) ELF32_R_SYM(val) +# define ELF_R_TYPE(val) ELF32_R_TYPE(val) +#elif defined(MKIMAGE_ELF64) +# define SUFFIX(x) x ## 64 +# define ELFCLASSXX ELFCLASS64 +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Phdr Elf64_Phdr +# define Elf_Addr Elf64_Addr +# define Elf_Sym Elf64_Sym +# define Elf_Off Elf64_Off +# define Elf_Shdr Elf64_Shdr +# define Elf_Rela Elf64_Rela +# define Elf_Rel Elf64_Rel +# define ELF_R_SYM(val) ELF64_R_SYM(val) +# define ELF_R_TYPE(val) ELF64_R_TYPE(val) +#else +#error "I'm confused" +#endif + +/* Relocate symbols; note that this function overwrites the symbol table. + Return the address of a start symbol. */ +static Elf_Addr +SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Shdr *symtab_section, Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + struct image_target_desc *image_target) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Addr start_address = 0; + Elf_Sym *sym; + Elf_Word i; + Elf_Shdr *strtab_section; + const char *strtab; + + strtab_section + = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (symtab_section->sh_link) + * section_entsize)); + strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); + + symtab_size = grub_target_to_host32 (symtab_section->sh_size); + sym_size = grub_target_to_host32 (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host32 (symtab_section->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + { + Elf_Section index; + const char *name; + + name = strtab + grub_target_to_host32 (sym->st_name); + + index = grub_target_to_host16 (sym->st_shndx); + if (index == STN_ABS) + { + continue; + } + else if ((index == STN_UNDEF)) + { + if (sym->st_name) + grub_util_error ("undefined symbol %s", name); + else + continue; + } + else if (index >= num_sections) + grub_util_error ("section %d does not exist", index); + + sym->st_value = (grub_target_to_host32 (sym->st_value) + + section_addresses[index]); + grub_util_info ("locating %s at 0x%x", name, sym->st_value); + + if (! start_address) + if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) + start_address = sym->st_value; + } + + return start_address; +} + +/* Return the address of a symbol at the index I in the section S. */ +static Elf_Addr +SUFFIX (get_symbol_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + struct image_target_desc *image_target) +{ + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host32 (s->sh_offset) + + i * grub_target_to_host32 (s->sh_entsize)); + return sym->st_value; +} + +/* Return the address of a modified value. */ +static Elf_Addr * +SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + struct image_target_desc *image_target) +{ + return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); +} + +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static void +SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab, struct image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Word target_section_index; + Elf_Addr target_section_addr; + Elf_Shdr *target_section; + Elf_Word j; + + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (s->sh_link) + * section_entsize)); + target_section_index = grub_target_to_host32 (s->sh_info); + target_section_addr = section_addresses[target_section_index]; + target_section = (Elf_Shdr *) ((char *) sections + + (target_section_index + * section_entsize)); + + grub_util_info ("dealing with the relocation section %s for %s", + strtab + grub_target_to_host32 (s->sh_name), + strtab + grub_target_to_host32 (target_section->sh_name)); + + rtab_size = grub_target_to_host32 (s->sh_size); + r_size = grub_target_to_host32 (s->sh_entsize); + rtab_offset = grub_target_to_host32 (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr sym_addr; + Elf_Addr *target; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + target = SUFFIX (get_target_address) (e, target_section, + offset, image_target); + info = grub_target_to_host (r->r_info); + sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + ELF_R_SYM (info), image_target); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + r->r_addend : 0; + + if (image_target->voidp_sizeof == 4) + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; + + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + else + switch (ELF_R_TYPE (info)) + { + + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", + *target, offset); + break; + + case R_X86_64_PC32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + } + } +} + +/* Add a PE32's fixup entry for a relocation. Return the resulting address + after having written to the file OUT. */ +static Elf_Addr +SUFFIX (add_fixup_entry) (struct fixup_block_list **cblock, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address, + struct image_target_desc *image_target) +{ + struct grub_pe32_fixup_block *b; + + b = &((*cblock)->b); + + /* First, check if it is necessary to write out the current block. */ + if ((*cblock)->state) + { + if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) + { + grub_uint32_t size; + + if (flush) + { + /* Add as much padding as necessary to align the address + with a section boundary. */ + Elf_Addr next_address; + unsigned padding_size; + size_t index; + + next_address = current_address + b->block_size; + padding_size = ((ALIGN_UP (next_address, image_target->section_align) + - next_address) + >> 1); + index = ((b->block_size - sizeof (*b)) >> 1); + grub_util_info ("adding %d padding fixup entries", padding_size); + while (padding_size--) + { + b->entries[index++] = 0; + b->block_size += 2; + } + } + else if (b->block_size & (8 - 1)) + { + /* If not aligned with a 32-bit boundary, add + a padding entry. */ + size_t index; + + grub_util_info ("adding a padding fixup entry"); + index = ((b->block_size - sizeof (*b)) >> 1); + b->entries[index] = 0; + b->block_size += 2; + } + + /* Flush it. */ + grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", + b->block_size, b->page_rva); + size = b->block_size; + current_address += size; + b->page_rva = grub_host_to_target32 (b->page_rva); + b->block_size = grub_host_to_target32 (b->block_size); + (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); + memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); + *cblock = (*cblock)->next; + } + } + + b = &((*cblock)->b); + + if (! flush) + { + grub_uint16_t entry; + size_t index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! (*cblock)->state) + { + (*cblock)->state = 1; + + /* The spec does not mention the requirement of a Page RVA. + Here, align the address with a 4K boundary for safety. */ + b->page_rva = (addr & ~(0x1000 - 1)); + b->block_size = sizeof (*b); + } + + /* Sanity check. */ + if (b->block_size >= sizeof (*b) + 2 * 0x1000) + grub_util_error ("too many fixup entries"); + + /* Add a new entry. */ + index = ((b->block_size - sizeof (*b)) >> 1); + entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); + b->entries[index] = grub_host_to_target16 (entry); + b->block_size += 2; + } + + return current_address; +} + +/* Make a .reloc section. */ +static Elf_Addr +SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, + Elf_Addr *section_addresses, Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab, struct image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + struct fixup_block_list *lst, *lst0; + Elf_Addr current_address = 0; + + lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); + memset (lst, 0, sizeof (*lst) + 2 * 0x1000); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || + (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) + { + Elf_Rel *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Addr section_address; + Elf_Word j; + + grub_util_info ("translating the relocation section %s", + strtab + grub_le_to_cpu32 (s->sh_name)); + + rtab_size = grub_le_to_cpu32 (s->sh_size); + r_size = grub_le_to_cpu32 (s->sh_entsize); + rtab_offset = grub_le_to_cpu32 (s->sh_offset); + num_rs = rtab_size / r_size; + + section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; + + for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rel *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + + offset = grub_le_to_cpu32 (r->r_offset); + info = grub_le_to_cpu32 (r->r_info); + + /* Necessary to relocate only absolute addresses. */ + if (image_target->voidp_sizeof == 4) + { + if (ELF_R_TYPE (info) == R_386_32) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address + = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + image_target); + } + } + else + { + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address + = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address, + image_target); + } + } + } + } + + current_address = SUFFIX (add_fixup_entry) (&lst, 0, 0, 1, current_address, image_target); + + { + grub_uint8_t *ptr; + ptr = *out = xmalloc (current_address); + for (lst = lst0; lst; lst = lst->next) + if (lst->state) + { + memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); + ptr += grub_target_to_host32 (lst->b.block_size); + } + if (current_address + *out != ptr) + { + grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, + current_address); + } + } + + return current_address; +} + +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +SUFFIX (is_text_section) (Elf_Shdr *s, struct image_target_desc *image_target) +{ + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == (SHF_EXECINSTR | SHF_ALLOC)); +} + +/* Determine if this section is a data section. This assumes that + BSS is also a data section, since the converter initializes BSS + when producing PE32 to avoid a bug in EFI implementations. */ +static int +SUFFIX (is_data_section) (Elf_Shdr *s, struct image_target_desc *image_target) +{ + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC); +} + +/* Return if the ELF header is valid. */ +static int +SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) +{ + if (size < sizeof (*e) + || e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_ident[EI_CLASS] != ELFCLASSXX + || e->e_version != grub_host_to_target32 (EV_CURRENT)) + return 0; + + return 1; +} + +/* Locate section addresses by merging code sections and data sections + into .text and .data, respectively. Return the array of section + addresses. */ +static Elf_Addr * +SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, + Elf_Half num_sections, const char *strtab, + grub_size_t *exec_size, grub_size_t *kernel_sz, + struct image_target_desc *image_target) +{ + int i; + Elf_Addr current_address; + Elf_Addr *section_addresses; + Elf_Shdr *s; + + section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); + memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); + + current_address = 0; + + /* .text */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_text_section) (s, image_target)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + *exec_size = current_address; + + /* .data */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_data_section) (s, image_target)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; + *kernel_sz = current_address; + return section_addresses; +} + +static char * +SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, + grub_size_t *kernel_sz, grub_size_t *bss_size, + grub_size_t total_module_size, grub_uint64_t *start, + void **reloc_section, grub_size_t *reloc_size, + struct image_target_desc *image_target) +{ + char *kernel_img, *out_img; + const char *strtab; + Elf_Ehdr *e; + Elf_Shdr *sections; + Elf_Addr *section_addresses; + Elf_Addr *section_vaddresses; + int i; + Elf_Shdr *s; + Elf_Half num_sections; + Elf_Off section_offset; + Elf_Half section_entsize; + grub_size_t kernel_size; + Elf_Shdr *symtab_section; + + *start = 0; + + kernel_size = grub_util_get_image_size (kernel_path); + kernel_img = xmalloc (kernel_size); + grub_util_load_image (kernel_path, kernel_img); + + e = (Elf_Ehdr *) kernel_img; + if (! SUFFIX (check_elf_header) (e, kernel_size, image_target)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_target_to_host32 (e->e_shoff); + section_entsize = grub_target_to_host16 (e->e_shentsize); + num_sections = grub_target_to_host16 (e->e_shnum); + + if (kernel_size < section_offset + section_entsize * num_sections) + grub_util_error ("invalid ELF format"); + + sections = (Elf_Shdr *) (kernel_img + section_offset); + + /* Relocate sections then symbols in the virtual address space. */ + s = (Elf_Shdr *) ((char *) sections + + grub_host_to_target16 (e->e_shstrndx) * section_entsize); + strtab = (char *) e + grub_host_to_target32 (s->sh_offset); + + section_addresses = SUFFIX (locate_sections) (sections, section_entsize, + num_sections, strtab, + exec_size, kernel_sz, image_target); + + if (image_target->id == IMAGE_EFI) + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; + +#if 0 + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) + { + symtab_section = s; + break; + } + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = SUFFIX (relocate_symbols) (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections, image_target); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + SUFFIX (relocate_addresses) (e, sections, section_addresses, section_entsize, + num_sections, strtab, image_target); + + *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab, image_target); + } + else + { + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; + } + + out_img = xmalloc (*kernel_sz + total_module_size); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_data_section) (s, image_target) + || SUFFIX (is_text_section) (s, image_target)) + { + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + memset (out_img + section_addresses[i], 0, + grub_host_to_target32 (s->sh_size)); + else + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target32 (s->sh_offset), + grub_host_to_target32 (s->sh_size)); + } + free (kernel_img); + + return out_img; +} + + +#undef SUFFIX +#undef ELFCLASSXX +#undef Elf_Ehdr +#undef Elf_Phdr +#undef Elf_Shdr +#undef Elf_Addr +#undef Elf_Sym +#undef Elf_Off +#undef Elf_Rela +#undef Elf_Rel +#undef ELF_R_TYPE +#undef ELF_R_SYM From 962b15b4c19ba248a7e66ebd9f504c901f917361 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 14:42:40 +0200 Subject: [PATCH 34/38] Fill info tables for qemu, sparc and mips --- boot/sparc64/ieee1275/diskboot.S | 2 +- include/grub/mips/kernel.h | 33 ----- include/grub/offsets.h | 31 ++++ include/grub/sparc64/ieee1275/kernel.h | 16 -- kern/mips/startup.S | 23 +-- kern/sparc64/ieee1275/crt0.S | 1 + util/grub-mkimage.c | 198 ++++++++++++++++++------- util/grub-mkimagexx.c | 27 ++-- 8 files changed, 205 insertions(+), 126 deletions(-) diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S index a8fd50d87..83dfee098 100644 --- a/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -137,7 +137,7 @@ lastlist: .word 0 .word 0 - . = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE) + . = _start + (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE) blocklist_default_start: .word 0 .word 2 diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 172c1dbe2..bc4d43b2b 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -23,41 +23,8 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_MOD_GAP 0x0 -#define GRUB_KERNEL_MACHINE_LINK_ALIGN 32 - -#define GRUB_KERNEL_CPU_RAW_SIZE 0x200 -#define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc -#define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10 - -#define GRUB_KERNEL_CPU_PREFIX GRUB_KERNEL_CPU_RAW_SIZE -#define GRUB_KERNEL_CPU_DATA_END GRUB_KERNEL_CPU_RAW_SIZE + 0x48 - -#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_KERNEL_CPU_RAW_SIZE - -#define GRUB_KERNEL_MACHINE_PREFIX GRUB_KERNEL_CPU_PREFIX -#define GRUB_KERNEL_MACHINE_DATA_END GRUB_KERNEL_CPU_DATA_END -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE - -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - -#define EM_TARGET EM_MIPS - #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_ELF -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF - /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 2ba6351ca..fc4cd0a46 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -67,14 +67,45 @@ /* End of the data section. */ #define GRUB_KERNEL_I386_QEMU_DATA_END 0x50 +#define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 + +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE 0x10 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX 0x14 + +/* End of the data section. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_DATA_END 0x114 + #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 #define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 +#define GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE 0 +#define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 #define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 #define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 +#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR 0x80200000 + +#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN 32 + +#define GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE 0x200 +#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE 0xc +#define GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE 0x10 + +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE +#define GRUB_KERNEL_MIPS_YEELOONG_DATA_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 + #ifdef MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 2948a8d2f..012b5570c 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -24,22 +24,6 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_MOD_GAP 0x0 -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 - -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE 0x10 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x14 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x114 - -#define GRUB_KERNEL_MACHINE_RAW_SIZE 0 #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 #ifndef ASM_FILE diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 5e3fb7ad5..876b2df71 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -18,8 +18,9 @@ */ #include -#include +#include #include +#include #define BASE_ADDR 8 @@ -32,13 +33,13 @@ _start: start: bal codestart base: - . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE + . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE compressed_size: .long 0 - . = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE + . = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE total_module_size: .long 0 - . = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE + . = _start + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE kernel_image_size: .long 0 codestart: @@ -105,10 +106,10 @@ argdone: #endif /* Decompress the payload. */ - addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR + addiu $a0, $s0, GRUB_KERNEL_MACHINE_RAW_SIZE - BASE_ADDR lui $a1, %hi(compressed) addiu $a1, %lo(compressed) - lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0) + lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) move $s1, $a1 /* $a0 contains source compressed address, $a1 is destination, @@ -134,9 +135,9 @@ reloccont: addiu $t1, %lo(cont) jr $t1 - . = _start + GRUB_KERNEL_CPU_RAW_SIZE + . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE compressed: - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) @@ -146,7 +147,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END #ifdef GRUB_MACHINE_MIPS_YEELOONG VARIABLE (grub_arch_busclock) .long 0 @@ -171,7 +172,7 @@ cont: /* Move the modules out of BSS. */ lui $t1, %hi(_start) addiu $t1, %lo(_start) - lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) + lw $t2, (GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) addu $t2, $t1, $t2 lui $t1, %hi(_end) @@ -181,7 +182,7 @@ cont: nor $t3, $t3, $0 and $t1, $t1, $t3 - lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) + lw $t3, (GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) /* Backward copy. */ add $t1, $t1, $t3 diff --git a/kern/sparc64/ieee1275/crt0.S b/kern/sparc64/ieee1275/crt0.S index d5a172296..f0f47416d 100644 --- a/kern/sparc64/ieee1275/crt0.S +++ b/kern/sparc64/ieee1275/crt0.S @@ -18,6 +18,7 @@ */ #include #include +#include .text .align 4 diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index c9bafdd8b..7ba9e595e 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -55,7 +55,6 @@ struct image_target_desc IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC } id; - enum {FORMAT_RAW, FORMAT_AOUT, FORMAT_ELF, FORMAT_PE} format; enum { PLATFORM_FLAGS_NONE = 0, @@ -77,56 +76,153 @@ struct image_target_desc struct image_target_desc image_targets[] = { - {"i386-coreboot", 4, 0, IMAGE_COREBOOT, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0 + { + .name = "i386-coreboot", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 }, - {"i386-pc", 4, 0, IMAGE_I386_PC, FORMAT_RAW, PLATFORM_FLAGS_LZMA, - GRUB_KERNEL_I386_PC_PREFIX, GRUB_KERNEL_I386_PC_DATA_END, - GRUB_KERNEL_I386_PC_RAW_SIZE, GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, - .section_align = 1, - .vaddr_offset = 0, - GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, GRUB_KERNEL_I386_PC_INSTALL_BSD_PART + { + .name = "i386-pc", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC, + .flags = PLATFORM_FLAGS_LZMA, + .prefix = GRUB_KERNEL_I386_PC_PREFIX, + .data_end = GRUB_KERNEL_I386_PC_DATA_END, + .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, + .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, + .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, - {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, - .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe32_optional_header) - + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + { + .name = "i386-efi", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) }, - {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"i386-qemu", 4, 0, IMAGE_QEMU, FORMAT_RAW, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, - .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe64_optional_header) - + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + { + .name = "i386-ieee1275", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_IEEE1275, + .flags = PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + { + .name = "i386-qemu", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_QEMU, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_QEMU_PREFIX, + .data_end = GRUB_KERNEL_I386_QEMU_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .kernel_image_size = GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR + }, + { + .name = "x86_64-efi", + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + { + .name = "mipsel-yeeloong-elf", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_YEELOONG_ELF, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, + .data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END, + .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, + .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, + .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, + .kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN + }, + { + .name = "powerpc-ieee1275", + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_PPC, + .flags = PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + { + .name = "sparc64-ieee1275-raw", + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_RAW, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + }, + { + .name = "sparc64-ieee1275-aout", + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_AOUT, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR }, - {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"powerpc-ieee1275", 4, 1, IMAGE_PPC, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"sparc64-ieee1275-raw", 8, 1, IMAGE_SPARC64_RAW, - FORMAT_RAW, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"sparc64-ieee1275-aout", 8, 1, IMAGE_SPARC64_AOUT, - FORMAT_AOUT, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, }; #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) @@ -191,8 +287,8 @@ grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_ return grub_cpu_to_le16 (in); } -static inline grub_uint32_t -grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint32_t in) +static inline grub_uint64_t +grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint64_t in) { if (image_target->voidp_sizeof == 8) return grub_host_to_target64_real (image_target, in); @@ -200,8 +296,8 @@ grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint return grub_host_to_target32_real (image_target, in); } -static inline grub_uint32_t -grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +static inline grub_uint64_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint64_t in) { if (image_target->voidp_sizeof == 8) return grub_target_to_host64_real (image_target, in); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index eb0c7a514..abfe56d42 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -67,11 +67,11 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, = (Elf_Shdr *) ((char *) sections + (grub_target_to_host32 (symtab_section->sh_link) * section_entsize)); - strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); + strtab = (char *) e + grub_target_to_host (strtab_section->sh_offset); - symtab_size = grub_target_to_host32 (symtab_section->sh_size); - sym_size = grub_target_to_host32 (symtab_section->sh_entsize); - symtab_offset = grub_target_to_host32 (symtab_section->sh_offset); + symtab_size = grub_target_to_host (symtab_section->sh_size); + sym_size = grub_target_to_host (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host (symtab_section->sh_offset); num_syms = symtab_size / sym_size; for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); @@ -482,7 +482,7 @@ SUFFIX (is_text_section) (Elf_Shdr *s, struct image_target_desc *image_target) if (image_target->id != IMAGE_EFI && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -495,7 +495,7 @@ SUFFIX (is_data_section) (Elf_Shdr *s, struct image_target_desc *image_target) if (image_target->id != IMAGE_EFI && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -543,7 +543,6 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); - if (align) current_address = ALIGN_UP (current_address + image_target->vaddr_offset, align) - image_target->vaddr_offset; @@ -551,7 +550,7 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, grub_util_info ("locating the section %s at 0x%x", name, current_address); section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); + current_address += grub_host_to_target_addr (s->sh_size); } current_address = ALIGN_UP (current_address + image_target->vaddr_offset, @@ -576,7 +575,7 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, grub_util_info ("locating the section %s at 0x%x", name, current_address); section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); + current_address += grub_host_to_target_addr (s->sh_size); } current_address = ALIGN_UP (current_address + image_target->vaddr_offset, @@ -616,7 +615,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, if (! SUFFIX (check_elf_header) (e, kernel_size, image_target)) grub_util_error ("invalid ELF header"); - section_offset = grub_target_to_host32 (e->e_shoff); + section_offset = grub_target_to_host (e->e_shoff); section_entsize = grub_target_to_host16 (e->e_shentsize); num_sections = grub_target_to_host16 (e->e_shnum); @@ -660,7 +659,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, grub_util_info ("locating the section %s at 0x%x", name, current_address); section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); + current_address += grub_host_to_target_addr (s->sh_size); } current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - VADDR_OFFSET; @@ -715,11 +714,11 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, { if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) memset (out_img + section_addresses[i], 0, - grub_host_to_target32 (s->sh_size)); + grub_host_to_target_addr (s->sh_size)); else memcpy (out_img + section_addresses[i], - kernel_img + grub_host_to_target32 (s->sh_offset), - grub_host_to_target32 (s->sh_size)); + kernel_img + grub_host_to_target_addr (s->sh_offset), + grub_host_to_target_addr (s->sh_size)); } free (kernel_img); From bb3208158ab37c8a8f28b946b1e804a1442d0c9a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 17:19:15 +0200 Subject: [PATCH 35/38] Fill info for remaining platforms. Make efi image identical to image of previous grub-mkimage --- conf/i386-coreboot.rmk | 4 +- include/grub/efi/pe32.h | 10 ++-- include/grub/i386/efi/kernel.h | 6 --- include/grub/i386/kernel.h | 3 -- include/grub/offsets.h | 21 ++++++++ include/grub/x86_64/efi/kernel.h | 6 --- kern/i386/coreboot/startup.S | 4 +- kern/i386/ieee1275/startup.S | 4 +- util/grub-mkimage.c | 88 ++++++++++++++++++++++++-------- 9 files changed, 101 insertions(+), 45 deletions(-) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 69b8e9a48..11c3abd2a 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -4,8 +4,6 @@ COMMON_CFLAGS = -mrtd -mregparm=3 # Images. -GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 - pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/misc.S \ @@ -26,7 +24,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 90f9c9f5c..81a1a5797 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -238,6 +238,7 @@ struct grub_pe32_section_table #define GRUB_PE32_SCN_ALIGN_SHIFT 20 #define GRUB_PE32_SCN_ALIGN_MASK 7 +#define GRUB_PE32_SIGNATURE_SIZE 4 struct grub_pe32_header { @@ -245,17 +246,20 @@ struct grub_pe32_header grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE]; /* This is always PE\0\0. */ - char signature[4]; + char signature[GRUB_PE32_SIGNATURE_SIZE]; /* The COFF file header. */ struct grub_pe32_coff_header coff_header; +#if GRUB_TARGET_SIZEOF_VOID_P == 8 + /* The Optional header. */ + struct grub_pe64_optional_header optional_header; +#else /* The Optional header. */ struct grub_pe32_optional_header optional_header; +#endif }; -#define GRUB_PE32_SIGNATURE_SIZE 4 - struct grub_pe32_fixup_block { grub_uint32_t page_rva; diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h index c0549f41a..0cb39a215 100644 --- a/include/grub/i386/efi/kernel.h +++ b/include/grub/i386/efi/kernel.h @@ -23,11 +23,5 @@ configuration file are located. */ extern char grub_prefix[]; -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 - #endif /* ! GRUB_MACHINE_KERNEL_HEADER */ diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h index 5514c8ccf..a0d806929 100644 --- a/include/grub/i386/kernel.h +++ b/include/grub/i386/kernel.h @@ -29,7 +29,4 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_MOD_GAP 0x0 -#define GRUB_KERNEL_CPU_PREFIX 0x2 -#define GRUB_KERNEL_CPU_DATA_END 0x42 - #endif diff --git a/include/grub/offsets.h b/include/grub/offsets.h index fc4cd0a46..768e4726a 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -93,6 +93,7 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 #define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 +#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 #define GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR 0x80200000 @@ -106,6 +107,26 @@ #define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE #define GRUB_KERNEL_MIPS_YEELOONG_DATA_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_EFI_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_I386_EFI_DATA_END 0x50 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_X86_64_EFI_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_X86_64_EFI_DATA_END 0x50 + +#define GRUB_KERNEL_I386_COREBOOT_PREFIX 0x2 +#define GRUB_KERNEL_I386_COREBOOT_DATA_END 0x42 +#define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 + +#define GRUB_KERNEL_I386_IEEE1275_PREFIX 0x2 +#define GRUB_KERNEL_I386_IEEE1275_DATA_END 0x42 +#define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 + #ifdef MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h index c0549f41a..0cb39a215 100644 --- a/include/grub/x86_64/efi/kernel.h +++ b/include/grub/x86_64/efi/kernel.h @@ -23,11 +23,5 @@ configuration file are located. */ extern char grub_prefix[]; -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 - #endif /* ! GRUB_MACHINE_KERNEL_HEADER */ diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index e94950aae..ecdc0b61c 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -42,7 +42,7 @@ _start: * This is a special data area at a fixed offset from the beginning. */ - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkimage */ @@ -51,7 +51,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S index 35258adb6..ad2ef329b 100644 --- a/kern/i386/ieee1275/startup.S +++ b/kern/i386/ieee1275/startup.S @@ -43,7 +43,7 @@ _start: * This is a special data area at a fixed offset from the beginning. */ - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkimage */ @@ -52,7 +52,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END codestart: movl %eax, EXT_C(grub_ieee1275_entry_fn) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 7ba9e595e..25ab5afe4 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -82,8 +82,17 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, + .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, - .vaddr_offset = 0 + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR }, { .name = "i386-pc", @@ -109,13 +118,21 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_EFI_PREFIX, + .data_end = GRUB_KERNEL_I386_EFI_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + sizeof (struct grub_pe32_coff_header) + sizeof (struct grub_pe32_optional_header) + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + GRUB_PE32_SECTION_ALIGNMENT), + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, }, { .name = "i386-ieee1275", @@ -123,8 +140,17 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_IEEE1275, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_I386_IEEE1275_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, - .vaddr_offset = 0 + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR }, { .name = "i386-qemu", @@ -150,13 +176,21 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_X86_64_EFI_PREFIX, + .data_end = GRUB_KERNEL_X86_64_EFI_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + sizeof (struct grub_pe32_coff_header) + sizeof (struct grub_pe64_optional_header) + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + GRUB_PE32_SECTION_ALIGNMENT), + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, }, { .name = "mipsel-yeeloong-elf", @@ -184,8 +218,17 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_PPC, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_POWERPC_IEEE1275_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, - .vaddr_offset = 0 + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR }, { .name = "sparc64-ieee1275-raw", @@ -629,6 +672,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], { void *pe_img; grub_uint8_t *header; + void *sections; size_t pe_size; struct grub_pe32_coff_header *c; struct grub_pe32_section_table *text_section, *data_section; @@ -669,7 +713,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], GRUB_PE32_SIGNATURE_SIZE); /* The COFF file header. */ - c = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE; + c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE); if (image_target->voidp_sizeof == 4) c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); else @@ -692,11 +737,13 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); - o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header); + o = (struct grub_pe32_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); o->bss_size = grub_cpu_to_le32 (bss_size); o->entry_addr = grub_cpu_to_le32 (start_address); o->code_base = grub_cpu_to_le32 (header_size); @@ -720,18 +767,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + sections = o + 1; } else { struct grub_pe64_optional_header *o; - c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); - o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header); + o = (struct grub_pe64_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); o->bss_size = grub_cpu_to_le32 (bss_size); o->entry_addr = grub_cpu_to_le32 (start_address); o->code_base = grub_cpu_to_le32 (header_size); @@ -753,9 +803,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + sections = o + 1; } /* The sections. */ - text_section = (struct grub_pe32_section_table *) (header + 1); + text_section = sections; strcpy (text_section->name, ".text"); text_section->virtual_size = grub_cpu_to_le32 (exec_size); text_section->virtual_address = grub_cpu_to_le32 (header_size); @@ -763,8 +814,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], text_section->raw_data_offset = grub_cpu_to_le32 (header_size); text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_ALIGN_64BYTES); + | GRUB_PE32_SCN_MEM_READ); data_section = text_section + 1; strcpy (data_section->name, ".data"); @@ -775,8 +825,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], data_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + | GRUB_PE32_SCN_MEM_WRITE); #if 0 bss_section = data_section + 1; @@ -802,8 +851,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], mods_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + | GRUB_PE32_SCN_MEM_WRITE); reloc_section = mods_section + 1; strcpy (reloc_section->name, ".reloc"); From debaf23f7c1ee4cc70a43a7bebc37667e5a4d6e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 19:11:38 +0200 Subject: [PATCH 36/38] all images binary identical to the ones from trunk --- include/grub/elf.h | 1 + include/grub/i386/kernel.h | 10 ---- include/grub/offsets.h | 16 +++++++ include/grub/powerpc/kernel.h | 7 --- kern/i386/coreboot/init.c | 2 +- kern/ieee1275/init.c | 2 +- util/grub-mkimage.c | 86 ++++++++++++++++++++++++++-------- util/grub-mkimagexx.c | 87 ++++++++++++++++++++--------------- 8 files changed, 137 insertions(+), 74 deletions(-) diff --git a/include/grub/elf.h b/include/grub/elf.h index e54989cde..b9401f241 100644 --- a/include/grub/elf.h +++ b/include/grub/elf.h @@ -555,6 +555,7 @@ typedef struct #define PT_NUM 8 /* Number of defined types */ #define PT_LOOS 0x60000000 /* Start of OS-specific */ #define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* GCC stack segment */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h index a0d806929..45c7abd72 100644 --- a/include/grub/i386/kernel.h +++ b/include/grub/i386/kernel.h @@ -19,14 +19,4 @@ #ifndef GRUB_KERNEL_CPU_HEADER #define GRUB_KERNEL_CPU_HEADER 1 - -#ifdef GRUB_MACHINE_IEEE1275 -#define GRUB_MOD_ALIGN 0x1000 -#else -#define GRUB_MOD_ALIGN 0x1 -#endif - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - #endif diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 768e4726a..a7f252e85 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -127,9 +127,25 @@ #define GRUB_KERNEL_I386_IEEE1275_DATA_END 0x42 #define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 +#define GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN 0x1000 +#define GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN 0x1 + +/* Non-zero value is only needed for PowerMacs. */ +#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0 +#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 + +#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 + +/* Minimal gap between _end and the start of the modules. It's a hack + for PowerMac to prevent "CLAIM failed" error. The real fix is to + rewrite grub-mkimage to generate valid ELF files. */ +#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x8000 + #ifdef MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) +#define GRUB_KERNEL_MACHINE_MOD_ALIGN GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_ALIGN) +#define GRUB_KERNEL_MACHINE_MOD_GAP GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_GAP) #define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE) #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE) #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h index e4ff65174..3fc0b9e23 100644 --- a/include/grub/powerpc/kernel.h +++ b/include/grub/powerpc/kernel.h @@ -19,11 +19,4 @@ #ifndef GRUB_KERNEL_CPU_HEADER #define GRUB_KERNEL_CPU_HEADER 1 -#define GRUB_MOD_ALIGN 0x1000 - -/* Minimal gap between _end and the start of the modules. It's a hack - for PowerMac to prevent "CLAIM failed" error. The real fix is to - rewrite grub-mkimage to generate valid ELF files. */ -#define GRUB_MOD_GAP 0x8000 - #endif diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index 5f80f28c1..f367269c4 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -144,6 +144,6 @@ grub_arch_modules_addr (void) #ifdef GRUB_MACHINE_QEMU return grub_core_entry_addr + grub_kernel_image_size; #else - return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN); + return ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); #endif } diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index 75f261a71..db9583d8b 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -284,5 +284,5 @@ grub_get_rtc (void) grub_addr_t grub_arch_modules_addr (void) { - return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); + return ALIGN_UP((grub_addr_t) _end + GRUB_KERNEL_MACHINE_MOD_GAP, GRUB_KERNEL_MACHINE_MOD_ALIGN); } diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 25ab5afe4..cc4a225d4 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -72,6 +72,7 @@ struct image_target_desc signed vaddr_offset; unsigned install_dos_part, install_bsd_part; grub_uint64_t link_addr; + unsigned mod_gap, mod_align; }; struct image_target_desc image_targets[] = @@ -92,7 +93,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN }, { .name = "i386-pc", @@ -150,7 +155,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR + .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR, + .elf_target = EM_386, + .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN, + .link_align = 4, }, { .name = "i386-qemu", @@ -228,7 +237,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR + .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR, + .elf_target = EM_PPC, + .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN, + .link_align = 4 }, { .name = "sparc64-ieee1275-raw", @@ -463,7 +476,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_size_t bss_size; grub_uint64_t start_address; void *rel_section; - grub_size_t reloc_size; + grub_size_t reloc_size, align; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); @@ -503,11 +516,11 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (image_target->voidp_sizeof == 4) kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size, image_target); + &reloc_size, &align, image_target); else kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size, image_target); + &reloc_size, &align, image_target); if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); @@ -961,6 +974,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_uint32_t target_addr; int header_size, footer_size = 0; int phnum = 1; + + if (image_target->id != IMAGE_YEELOONG_ELF) + phnum += 2; if (note) { @@ -994,7 +1010,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], /* No section headers. */ ehdr->e_shoff = grub_host_to_target32 (0); - ehdr->e_shentsize = grub_host_to_target16 (0); + if (image_target->id == IMAGE_YEELOONG_ELF) + ehdr->e_shentsize = grub_host_to_target16 (0); + else + ehdr->e_shentsize = grub_host_to_target16 (sizeof (Elf32_Shdr)); ehdr->e_shnum = grub_host_to_target16 (0); ehdr->e_shstrndx = grub_host_to_target16 (0); @@ -1012,14 +1031,44 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); - phdr->p_align = grub_host_to_target32 (image_target->link_align); + phdr->p_align = grub_host_to_target32 (align > image_target->link_align ? align : image_target->link_align); if (image_target->id == IMAGE_YEELOONG_ELF) ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER | EF_MIPS_PIC | EF_MIPS_CPIC); else ehdr->e_flags = 0; - phdr->p_filesz = grub_host_to_target32 (core_size); - phdr->p_memsz = grub_host_to_target32 (core_size); + if (image_target->id == IMAGE_YEELOONG_ELF) + { + phdr->p_filesz = grub_host_to_target32 (core_size); + phdr->p_memsz = grub_host_to_target32 (core_size); + } + else + { + grub_uint32_t target_addr_mods; + phdr->p_filesz = grub_host_to_target32 (kernel_size); + phdr->p_memsz = grub_host_to_target32 (kernel_size + bss_size); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_GNU_STACK); + phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_paddr = phdr->p_vaddr = phdr->p_filesz = phdr->p_memsz = 0; + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_filesz = phdr->p_memsz + = grub_host_to_target32 (core_size - kernel_size); + + target_addr_mods = ALIGN_UP (target_addr + kernel_size + bss_size + + image_target->mod_gap, + image_target->mod_align); + phdr->p_vaddr = grub_host_to_target32 (target_addr_mods); + phdr->p_paddr = grub_host_to_target32 (target_addr_mods); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + } if (note) { @@ -1040,14 +1089,15 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); note->descriptor.load_base = grub_host_to_target32 (0x00004000); - phdr[1].p_type = grub_host_to_target32 (PT_NOTE); - phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (image_target->voidp_sizeof); - phdr[1].p_vaddr = 0; - phdr[1].p_paddr = 0; - phdr[1].p_filesz = grub_host_to_target32 (note_size); - phdr[1].p_memsz = 0; - phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (note_size); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); } free (core_img); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index abfe56d42..e9fdc7428 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -523,6 +523,7 @@ static Elf_Addr * SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, const char *strtab, grub_size_t *exec_size, grub_size_t *kernel_sz, + grub_size_t *all_align, struct image_target_desc *image_target) { int i; @@ -530,11 +531,21 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Addr *section_addresses; Elf_Shdr *s; + *all_align = 1; + section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); current_address = 0; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC) + && grub_host_to_target32 (s->sh_addralign) > *all_align) + *all_align = grub_host_to_target32 (s->sh_addralign); + + /* .text */ for (i = 0, s = sections; i < num_sections; @@ -546,7 +557,6 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, if (align) current_address = ALIGN_UP (current_address + image_target->vaddr_offset, align) - image_target->vaddr_offset; - grub_util_info ("locating the section %s at 0x%x", name, current_address); section_addresses[i] = current_address; @@ -589,6 +599,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, grub_size_t *kernel_sz, grub_size_t *bss_size, grub_size_t total_module_size, grub_uint64_t *start, void **reloc_section, grub_size_t *reloc_size, + grub_size_t *align, struct image_target_desc *image_target) { char *kernel_img, *out_img; @@ -631,44 +642,47 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, section_addresses = SUFFIX (locate_sections) (sections, section_entsize, num_sections, strtab, - exec_size, kernel_sz, image_target); + exec_size, kernel_sz, align, + image_target); + + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; + + if (image_target->id != IMAGE_EFI) + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + + image_target->vaddr_offset, align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + + image_target->vaddr_offset; + current_address += grub_host_to_target_addr (s->sh_size); + } + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + *bss_size = current_address - *kernel_sz; + } + else + *bss_size = 0; if (image_target->id == IMAGE_EFI) { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; - -#if 0 - { - Elf_Addr current_address = *kernel_sz; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target_addr (s->sh_size); - } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; - } -#else - *bss_size = 0; -#endif - symtab_section = NULL; for (i = 0, s = sections; i < num_sections; @@ -699,7 +713,6 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, } else { - *bss_size = 0; *reloc_size = 0; *reloc_section = NULL; } From 8ea6ecb36d0df734d1cef2c0290c114b649c703d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 21:11:16 +0200 Subject: [PATCH 37/38] Some cleanups --- conf/common.rmk | 2 +- conf/i386-pc.rmk | 2 +- include/grub/i386/coreboot/kernel.h | 28 -- include/grub/i386/efi/kernel.h | 27 -- include/grub/i386/ieee1275/kernel.h | 1 - include/grub/i386/kernel.h | 22 -- include/grub/i386/pc/kernel.h | 4 - include/grub/i386/qemu/kernel.h | 4 - include/grub/kernel.h | 4 + include/grub/mips/kernel.h | 34 -- include/grub/mips/qemu-mips/boot.h | 0 include/grub/mips/qemu-mips/kernel.h | 4 - include/grub/mips/yeeloong/boot.h | 0 include/grub/mips/yeeloong/kernel.h | 1 - include/grub/offsets.h | 2 + include/grub/powerpc/ieee1275/kernel.h | 35 -- include/grub/sparc64/ieee1275/kernel.h | 9 - include/grub/sparc64/kernel.h | 30 -- include/grub/types.h | 36 -- include/grub/x86_64/efi/kernel.h | 27 -- include/grub/x86_64/kernel.h | 1 - kern/efi/init.c | 1 - kern/i386/coreboot/init.c | 5 +- kern/i386/coreboot/startup.S | 2 +- kern/i386/ieee1275/startup.S | 1 - kern/ieee1275/cmain.c | 1 - kern/ieee1275/init.c | 3 +- kern/ieee1275/openfw.c | 1 - kern/mips/init.c | 1 - kern/mips/startup.S | 6 +- kern/mips/yeeloong/init.c | 1 - kern/powerpc/ieee1275/startup.S | 2 +- util/elf/grub-mkimage.c | 463 ------------------------- util/grub-mkimagexx.c | 3 + util/i386/pc/grub-setup.c | 7 + util/sparc64/ieee1275/grub-setup.c | 7 + 36 files changed, 34 insertions(+), 743 deletions(-) delete mode 100644 include/grub/i386/coreboot/kernel.h delete mode 100644 include/grub/i386/efi/kernel.h delete mode 100644 include/grub/i386/ieee1275/kernel.h delete mode 100644 include/grub/i386/kernel.h delete mode 100644 include/grub/mips/kernel.h delete mode 100644 include/grub/mips/qemu-mips/boot.h delete mode 100644 include/grub/mips/yeeloong/boot.h delete mode 100644 include/grub/powerpc/ieee1275/kernel.h delete mode 100644 include/grub/sparc64/kernel.h delete mode 100644 include/grub/x86_64/efi/kernel.h delete mode 100644 include/grub/x86_64/kernel.h delete mode 100644 util/elf/grub-mkimage.c diff --git a/conf/common.rmk b/conf/common.rmk index 98dca34f9..f9e7eb194 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -118,7 +118,7 @@ kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ list.h handler.h command.h i18n.h env_private.h libgcc.h ifneq ($(platform), emu) -kernel_img_HEADERS += machine/memory.h machine/loader.h machine/kernel.h +kernel_img_HEADERS += machine/memory.h machine/loader.h endif symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index f0da94b42..4c55f28f6 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -53,7 +53,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \ term/i386/pc/console.c term/i386/vga_common.c \ symlist.c kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ - machine/pxe.h i386/pit.h + machine/pxe.h i386/pit.h machine/kernel.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8200 $(COMMON_CFLAGS) diff --git a/include/grub/i386/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h deleted file mode 100644 index fb60668cc..000000000 --- a/include/grub/i386/coreboot/kernel.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 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_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#include - -#ifndef ASM_FILE -extern char grub_prefix[]; -#endif - -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h deleted file mode 100644 index 0cb39a215..000000000 --- a/include/grub/i386/efi/kernel.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2007 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_MACHINE_KERNEL_HEADER -#define GRUB_MACHINE_KERNEL_HEADER 1 - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ - diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h deleted file mode 100644 index dccf8cbe1..000000000 --- a/include/grub/i386/ieee1275/kernel.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h deleted file mode 100644 index 45c7abd72..000000000 --- a/include/grub/i386/kernel.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,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 . - */ - -#ifndef GRUB_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - -#endif diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index f0a9d4fc2..1de37a5d5 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -41,10 +41,6 @@ extern grub_int32_t grub_install_dos_part; /* The BSD partition number of the installed partition. */ extern grub_int32_t grub_install_bsd_part; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - /* The boot BIOS drive number. */ extern grub_uint8_t EXPORT_VAR(grub_boot_drive); diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index e29f0aeb2..0aa2b3d09 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -34,10 +34,6 @@ extern grub_int32_t grub_kernel_image_size; /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h index f7740b2e3..fed875db1 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -90,4 +90,8 @@ void grub_machine_set_prefix (void); /* Register all the exported symbols. This is automatically generated. */ void grub_register_exported_symbols (void); +#if ! defined (ASM_FILE) && !defined (GRUB_MACHINE_EMU) +extern char grub_prefix[]; +#endif + #endif /* ! GRUB_KERNEL_HEADER */ diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h deleted file mode 100644 index bc4d43b2b..000000000 --- a/include/grub/mips/kernel.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 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_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - -#define GRUB_MOD_ALIGN 0x1 -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - -#ifndef ASM_FILE - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif - -#endif diff --git a/include/grub/mips/qemu-mips/boot.h b/include/grub/mips/qemu-mips/boot.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/mips/qemu-mips/kernel.h b/include/grub/mips/qemu-mips/kernel.h index dbf74c1b2..230455dbf 100644 --- a/include/grub/mips/qemu-mips/kernel.h +++ b/include/grub/mips/qemu-mips/kernel.h @@ -27,10 +27,6 @@ void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/yeeloong/boot.h b/include/grub/mips/yeeloong/boot.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h index 230455dbf..c08405e83 100644 --- a/include/grub/mips/yeeloong/kernel.h +++ b/include/grub/mips/yeeloong/kernel.h @@ -20,7 +20,6 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include -#include #ifndef ASM_FILE diff --git a/include/grub/offsets.h b/include/grub/offsets.h index a7f252e85..ae0b2557e 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -136,6 +136,8 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 +#define GRUB_KERNEL_MIPS_YEELOONG_MOD_ALIGN 0x1 + /* Minimal gap between _end and the start of the modules. It's a hack for PowerMac to prevent "CLAIM failed" error. The real fix is to rewrite grub-mkimage to generate valid ELF files. */ diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h deleted file mode 100644 index 75d6c62a6..000000000 --- a/include/grub/powerpc/ieee1275/kernel.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 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_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#include -#include - -#define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 - -#ifndef ASM_FILE - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif - -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 012b5570c..5aa50b852 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -19,11 +19,6 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -#define GRUB_MOD_ALIGN 0x2000 - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 #ifndef ASM_FILE @@ -37,10 +32,6 @@ extern grub_int32_t grub_kernel_image_size; /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/sparc64/kernel.h b/include/grub/sparc64/kernel.h deleted file mode 100644 index 9f404b05d..000000000 --- a/include/grub/sparc64/kernel.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 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_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - -#define GRUB_MOD_ALIGN 0x2000 - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - -#define GRUB_KERNEL_CPU_PREFIX 0x2 -#define GRUB_KERNEL_CPU_DATA_END 0x42 - -#endif diff --git a/include/grub/types.h b/include/grub/types.h index 9eaafd0c1..6e9461f1d 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -178,21 +178,6 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_be_to_cpu16(x) ((grub_uint16_t) (x)) # define grub_be_to_cpu32(x) ((grub_uint32_t) (x)) # define grub_be_to_cpu64(x) ((grub_uint64_t) (x)) -# ifdef GRUB_TARGET_WORDS_BIGENDIAN -# define grub_target_to_host16(x) ((grub_uint16_t) (x)) -# define grub_target_to_host32(x) ((grub_uint32_t) (x)) -# define grub_target_to_host64(x) ((grub_uint64_t) (x)) -# define grub_host_to_target16(x) ((grub_uint16_t) (x)) -# define grub_host_to_target32(x) ((grub_uint32_t) (x)) -# define grub_host_to_target64(x) ((grub_uint64_t) (x)) -# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */ -# define grub_target_to_host16(x) grub_swap_bytes16(x) -# define grub_target_to_host32(x) grub_swap_bytes32(x) -# define grub_target_to_host64(x) grub_swap_bytes64(x) -# define grub_host_to_target16(x) grub_swap_bytes16(x) -# define grub_host_to_target32(x) grub_swap_bytes32(x) -# define grub_host_to_target64(x) grub_swap_bytes64(x) -# endif #else /* ! WORDS_BIGENDIAN */ # define grub_cpu_to_le16(x) ((grub_uint16_t) (x)) # define grub_cpu_to_le32(x) ((grub_uint32_t) (x)) @@ -206,27 +191,6 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_be_to_cpu16(x) grub_swap_bytes16(x) # define grub_be_to_cpu32(x) grub_swap_bytes32(x) # define grub_be_to_cpu64(x) grub_swap_bytes64(x) -# ifdef GRUB_TARGET_WORDS_BIGENDIAN -# define grub_target_to_host16(x) grub_swap_bytes16(x) -# define grub_target_to_host32(x) grub_swap_bytes32(x) -# define grub_target_to_host64(x) grub_swap_bytes64(x) -# define grub_host_to_target16(x) grub_swap_bytes16(x) -# define grub_host_to_target32(x) grub_swap_bytes32(x) -# define grub_host_to_target64(x) grub_swap_bytes64(x) -# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */ -# define grub_target_to_host16(x) ((grub_uint16_t) (x)) -# define grub_target_to_host32(x) ((grub_uint32_t) (x)) -# define grub_target_to_host64(x) ((grub_uint64_t) (x)) -# define grub_host_to_target16(x) ((grub_uint16_t) (x)) -# define grub_host_to_target32(x) ((grub_uint32_t) (x)) -# define grub_host_to_target64(x) ((grub_uint64_t) (x)) -# endif #endif /* ! WORDS_BIGENDIAN */ -#if GRUB_TARGET_SIZEOF_VOID_P == 8 -# define grub_host_to_target_addr(x) grub_host_to_target64(x) -#else -# define grub_host_to_target_addr(x) grub_host_to_target32(x) -#endif - #endif /* ! GRUB_TYPES_HEADER */ diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h deleted file mode 100644 index 0cb39a215..000000000 --- a/include/grub/x86_64/efi/kernel.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2007 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_MACHINE_KERNEL_HEADER -#define GRUB_MACHINE_KERNEL_HEADER 1 - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ - diff --git a/include/grub/x86_64/kernel.h b/include/grub/x86_64/kernel.h deleted file mode 100644 index 25ac57e40..000000000 --- a/include/grub/x86_64/kernel.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/kern/efi/init.c b/kern/efi/init.c index a0b4ff779..afd21055d 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -24,7 +24,6 @@ #include #include #include -#include void grub_efi_init (void) diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index f367269c4..08f2cce3a 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -33,8 +32,10 @@ #include #include #include -#include #include +#ifdef GRUB_MACHINE_QEMU +#include +#endif #define GRUB_FLOPPY_REG_DIGITAL_OUTPUT 0x3f2 diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index ecdc0b61c..bdefb69bc 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S index ad2ef329b..c0a08a954 100644 --- a/kern/i386/ieee1275/startup.S +++ b/kern/i386/ieee1275/startup.S @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/kern/ieee1275/cmain.c b/kern/ieee1275/cmain.c index c1185f82c..cdc8ca051 100644 --- a/kern/ieee1275/cmain.c +++ b/kern/ieee1275/cmain.c @@ -20,7 +20,6 @@ #include #include #include -#include #include int (*grub_ieee1275_entry_fn) (void *); diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index db9583d8b..f79b82776 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -29,10 +29,9 @@ #include #include #include -#include -#include #include #include +#include /* The minimal heap size we can live with. */ #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index cf9e1a870..5693f3be0 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -21,7 +21,6 @@ #include #include #include -#include #include enum grub_ieee1275_parse_type diff --git a/kern/mips/init.c b/kern/mips/init.c index 5adcedcbb..f220108d4 100644 --- a/kern/mips/init.c +++ b/kern/mips/init.c @@ -18,7 +18,6 @@ #include #include -#include void grub_machine_set_prefix (void) diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 876b2df71..1d18131be 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -20,7 +20,7 @@ #include #include #include -#include +#include #define BASE_ADDR 8 @@ -177,8 +177,8 @@ cont: lui $t1, %hi(_end) addiu $t1, %lo(_end) - addiu $t1, (GRUB_MOD_ALIGN-1) - li $t3, (GRUB_MOD_ALIGN-1) + addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) + li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) nor $t3, $t3, $0 and $t1, $t1, $t3 diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 6bba27b51..47aa774a0 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -26,7 +26,6 @@ #include #include #include -#include extern void grub_video_sm712_init (void); extern void grub_video_init (void); diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S index 979f260f8..96d153778 100644 --- a/kern/powerpc/ieee1275/startup.S +++ b/kern/powerpc/ieee1275/startup.S @@ -18,7 +18,7 @@ */ #include -#include +#include .extern __bss_start .extern _end diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c deleted file mode 100644 index f37837c19..000000000 --- a/util/elf/grub-mkimage.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2005,2006,2007,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 . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "progname.h" - -#define GRUB_IEEE1275_NOTE_NAME "PowerPC" -#define GRUB_IEEE1275_NOTE_TYPE 0x1275 - -/* These structures are defined according to the CHRP binding to IEEE1275, - "Client Program Format" section. */ - -struct grub_ieee1275_note_hdr -{ - grub_uint32_t namesz; - grub_uint32_t descsz; - grub_uint32_t type; - char name[sizeof (GRUB_IEEE1275_NOTE_NAME)]; -}; - -struct grub_ieee1275_note_desc -{ - grub_uint32_t real_mode; - grub_uint32_t real_base; - grub_uint32_t real_size; - grub_uint32_t virt_base; - grub_uint32_t virt_size; - grub_uint32_t load_base; -}; - -struct grub_ieee1275_note -{ - struct grub_ieee1275_note_hdr header; - struct grub_ieee1275_note_desc descriptor; -}; - -void -load_note (Elf32_Phdr *phdr, FILE *out) -{ - struct grub_ieee1275_note note; - int note_size = sizeof (struct grub_ieee1275_note); - - grub_util_info ("adding CHRP NOTE segment"); - - note.header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); - note.header.descsz = grub_host_to_target32 (note_size); - note.header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); - strcpy (note.header.name, GRUB_IEEE1275_NOTE_NAME); - note.descriptor.real_mode = grub_host_to_target32 (0xffffffff); - note.descriptor.real_base = grub_host_to_target32 (0x00c00000); - note.descriptor.real_size = grub_host_to_target32 (0xffffffff); - note.descriptor.virt_base = grub_host_to_target32 (0xffffffff); - note.descriptor.virt_size = grub_host_to_target32 (0xffffffff); - note.descriptor.load_base = grub_host_to_target32 (0x00004000); - - /* Write the note data to the new segment. */ - grub_util_write_image_at (¬e, note_size, - grub_target_to_host32 (phdr->p_offset), out); - - /* Fill in the rest of the segment header. */ - phdr->p_type = grub_host_to_target32 (PT_NOTE); - phdr->p_flags = grub_host_to_target32 (PF_R); - phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr->p_vaddr = 0; - phdr->p_paddr = 0; - phdr->p_filesz = grub_host_to_target32 (note_size); - phdr->p_memsz = 0; -} - -void -load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, - char *mods[], FILE *out, char *memdisk_path, char *config_path) -{ - char *module_img; - struct grub_util_path_list *path_list; - struct grub_util_path_list *p; - struct grub_module_info *modinfo; - size_t offset; - size_t total_module_size; - size_t memdisk_size = 0; - size_t config_size = 0; - - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); - - offset = sizeof (struct grub_module_info); - total_module_size = sizeof (struct grub_module_info); - - if (memdisk_path) - { - memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); - grub_util_info ("the size of memory disk is 0x%x", memdisk_size); - total_module_size += memdisk_size + sizeof (struct grub_module_header); - } - - if (config_path) - { - config_size = ALIGN_UP(grub_util_get_image_size (config_path), 512); - grub_util_info ("the size of memory disk is 0x%x", config_size); - total_module_size += config_size + sizeof (struct grub_module_header); - } - - for (p = path_list; p; p = p->next) - { - total_module_size += (grub_util_get_image_size (p->name) - + sizeof (struct grub_module_header)); - } - - grub_util_info ("the total module size is 0x%x", total_module_size); - - module_img = xmalloc (total_module_size); - modinfo = (struct grub_module_info *) module_img; - modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); - modinfo->offset = grub_host_to_target32 (sizeof (struct grub_module_info)); - modinfo->size = grub_host_to_target32 (total_module_size); - - /* Load all the modules, with headers, into module_img. */ - for (p = path_list; p; p = p->next) - { - struct grub_module_header *header; - size_t mod_size; - - grub_util_info ("adding module %s", p->name); - - mod_size = grub_util_get_image_size (p->name); - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_ELF; - header->size = grub_host_to_target32 (mod_size + sizeof (*header)); - - grub_util_load_image (p->name, module_img + offset + sizeof (*header)); - - offset += sizeof (*header) + mod_size; - } - - if (memdisk_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_MEMDISK; - header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (memdisk_path, module_img + offset); - offset += memdisk_size; - } - - if (config_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_CONFIG; - header->size = grub_host_to_target32 (config_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (config_path, module_img + offset); - offset += config_size; - } - - - /* Write the module data to the new segment. */ - grub_util_write_image_at (module_img, total_module_size, - grub_host_to_target32 (phdr->p_offset), out); - - /* Fill in the rest of the segment header. */ - phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr->p_vaddr = grub_host_to_target32 (modbase); - phdr->p_paddr = grub_host_to_target32 (modbase); - phdr->p_filesz = grub_host_to_target32 (total_module_size); - phdr->p_memsz = grub_host_to_target32 (total_module_size); -} - -void -add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path, char *config_path) -{ - Elf32_Ehdr ehdr; - Elf32_Phdr *phdrs = NULL; - Elf32_Phdr *phdr; - FILE *in; - char *kernel_path; - grub_addr_t grub_end = 0; - off_t offset, first_segment; - int i, phdr_size; - - /* Read ELF header. */ - kernel_path = grub_util_get_path (dir, "kernel.img"); - in = fopen (kernel_path, "rb"); - if (! in) - grub_util_error ("cannot open %s", kernel_path); - - grub_util_read_at (&ehdr, sizeof (ehdr), 0, in); - - offset = ALIGN_UP (sizeof (ehdr), GRUB_TARGET_SIZEOF_LONG); - ehdr.e_phoff = grub_host_to_target32 (offset); - - phdr_size = (grub_target_to_host16 (ehdr.e_phentsize) * - grub_target_to_host16 (ehdr.e_phnum)); - - if (mods[0] != NULL) - phdr_size += grub_target_to_host16 (ehdr.e_phentsize); - - if (chrp) - phdr_size += grub_target_to_host16 (ehdr.e_phentsize); - - phdrs = xmalloc (phdr_size); - offset += ALIGN_UP (phdr_size, GRUB_TARGET_SIZEOF_LONG); - - first_segment = offset; - - /* Copy all existing segments. */ - for (i = 0; i < grub_target_to_host16 (ehdr.e_phnum); i++) - { - char *segment_img; - grub_size_t segment_end; - - phdr = phdrs + i; - - /* Read segment header. */ - grub_util_read_at (phdr, sizeof (Elf32_Phdr), - (grub_target_to_host32 (ehdr.e_phoff) - + (i * grub_target_to_host16 (ehdr.e_phentsize))), - in); - grub_util_info ("copying segment %d, type %d", i, - grub_target_to_host32 (phdr->p_type)); - - /* Locate _end. */ - segment_end = grub_target_to_host32 (phdr->p_paddr) - + grub_target_to_host32 (phdr->p_memsz); - grub_util_info ("segment %u end 0x%lx", i, segment_end); - if (segment_end > grub_end) - grub_end = segment_end; - - /* Read segment data and write it to new file. */ - segment_img = xmalloc (grub_target_to_host32 (phdr->p_filesz)); - - grub_util_read_at (segment_img, grub_target_to_host32 (phdr->p_filesz), - grub_target_to_host32 (phdr->p_offset), in); - - phdr->p_offset = grub_host_to_target32 (offset); - grub_util_write_image_at (segment_img, grub_target_to_host32 (phdr->p_filesz), - offset, out); - offset += ALIGN_UP (grub_target_to_host32 (phdr->p_filesz), - GRUB_TARGET_SIZEOF_LONG); - - free (segment_img); - } - - if (mods[0] != NULL) - { - grub_addr_t modbase; - - /* Place modules just after grub segment. */ - modbase = ALIGN_UP(grub_end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); - - /* Construct new segment header for modules. */ - phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum); - ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1); - - /* Fill in p_offset so the callees know where to write. */ - phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), - GRUB_TARGET_SIZEOF_LONG)); - - load_modules (modbase, phdr, dir, mods, out, memdisk_path, config_path); - } - - if (chrp) - { - /* Construct new segment header for the CHRP note. */ - phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum); - ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1); - - /* Fill in p_offset so the callees know where to write. */ - phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), - GRUB_TARGET_SIZEOF_LONG)); - - load_note (phdr, out); - } - - /* Don't bother preserving the section headers. */ - ehdr.e_shoff = 0; - ehdr.e_shnum = 0; - ehdr.e_shstrndx = 0; - - /* Write entire segment table to the file. */ - grub_util_write_image_at (phdrs, phdr_size, grub_target_to_host32 (ehdr.e_phoff), out); - - /* Write ELF header. */ - grub_util_write_image_at (&ehdr, sizeof (ehdr), 0, out); - - if (prefix) - { - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error ("prefix too long"); - grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_MACHINE_PREFIX, out); - } - - free (phdrs); - free (kernel_path); -} - -static struct option options[] = - { - {"directory", required_argument, 0, 'd'}, - {"prefix", required_argument, 0, 'p'}, - {"memdisk", required_argument, 0, 'm'}, - {"config", required_argument, 0, 'c'}, - {"output", required_argument, 0, 'o'}, - {"help", no_argument, 0, 'h'}, - {"note", no_argument, 0, 'n'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - { 0, 0, 0, 0 }, - }; - -static void -usage (int status) -{ - if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s -o FILE [OPTION]... [MODULES]\n\ -\n\ -Make a bootable image of GRUB.\n\ -\n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ - -p, --prefix=DIR set grub_prefix directory\n\ - -m, --memdisk=FILE embed FILE as a memdisk image\n\ - -c, --config=FILE embed FILE as boot config\n\ - -o, --output=FILE output a generated image to FILE\n\ - -h, --help display this message and exit\n\ - -n, --note add NOTE segment for CHRP Open Firmware\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n\ -", program_name, GRUB_LIBDIR, PACKAGE_BUGREPORT); - - exit (status); -} - -int -main (int argc, char *argv[]) -{ - FILE *fp; - char *output = NULL; - char *dir = NULL; - char *prefix = NULL; - char *memdisk = NULL; - char *config = NULL; - int chrp = 0; - - set_program_name (argv[0]); - - grub_util_init_nls (); - - while (1) - { - int c = getopt_long (argc, argv, "d:p:m:c:o:hVvn", options, 0); - if (c == -1) - break; - - switch (c) - { - case 'd': - if (dir) - free (dir); - dir = xstrdup (optarg); - break; - case 'p': - if (prefix) - free (prefix); - prefix = xstrdup (optarg); - break; - case 'm': - if (memdisk) - free (memdisk); - memdisk = xstrdup (optarg); - - if (prefix) - free (prefix); - prefix = xstrdup ("(memdisk)/boot/grub"); - - break; - case 'c': - if (config) - free (config); - config = xstrdup (optarg); - - break; - - case 'h': - usage (0); - break; - case 'n': - chrp = 1; - break; - case 'o': - if (output) - free (output); - output = xstrdup (optarg); - break; - case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); - return 0; - case 'v': - verbosity++; - break; - default: - usage (1); - break; - } - } - - if (!output) - usage (1); - - fp = fopen (output, "wb"); - if (! fp) - grub_util_error ("cannot open %s", output); - - add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk, - config); - - fclose (fp); - - return 0; -} diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index e9fdc7428..4a257e329 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -17,6 +17,9 @@ * along with GRUB. If not, see . */ +#undef ELF_R_SYM +#undef ELF_R_TYPE + #if defined(MKIMAGE_ELF32) # define SUFFIX(x) x ## 32 # define ELFCLASSXX ELFCLASS32 diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..f479d5090 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -57,6 +57,13 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P #define DEFAULT_BOOT_FILE "boot.img" #define DEFAULT_CORE_FILE "core.img" +#define grub_target_to_host16(x) grub_le_to_cpu16(x) +#define grub_target_to_host32(x) grub_le_to_cpu32(x) +#define grub_target_to_host64(x) grub_le_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_le16(x) +#define grub_host_to_target32(x) grub_cpu_to_le32(x) +#define grub_host_to_target64(x) grub_cpu_to_le64(x) + void grub_putchar (int c) { diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index b511a96b2..fbf6ba036 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -76,6 +76,13 @@ #define DEFAULT_BOOT_FILE "boot.img" #define DEFAULT_CORE_FILE "core.img" +#define grub_target_to_host16(x) grub_be_to_cpu16(x) +#define grub_target_to_host32(x) grub_be_to_cpu32(x) +#define grub_target_to_host64(x) grub_be_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_be16(x) +#define grub_host_to_target32(x) grub_cpu_to_be32(x) +#define grub_host_to_target64(x) grub_cpu_to_be64(x) + /* This is the blocklist used in the diskboot image. */ struct boot_blocklist { From 88d046d01efb74d256ccab953ebe0dbe82b0ee2e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 21:27:41 +0200 Subject: [PATCH 38/38] Switch to new grub-mkimage syntax --- util/grub-install.in | 19 +++++++++++-------- util/grub-mkrescue.in | 4 ++-- util/i386/efi/grub-install.in | 2 +- util/ieee1275/grub-install.in | 4 ++-- util/powerpc/ieee1275/grub-mkrescue.in | 4 ++-- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index 142d5792f..8a93ace8c 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -35,11 +35,7 @@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${t localedir=@datadir@/locale grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` -if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` -else - grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` -fi +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` @@ -346,16 +342,23 @@ else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 fi +case "${target_cpu}-${platform}" + i386-pc) mkimage_target=i386-pc ;; + sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; + mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; + *) mkimage_target=i386-coreboot; +esac + if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then - $grub_mkimage ${config_opt} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 # Now perform the installation. $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ ${install_device} || exit 1 elif [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O elf --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O ${mkimage_target} --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 else - $grub_mkimage ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage -O ${mkimage_target} ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 fi echo "Installation finished. No error reported." diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 7d553a767..a5430534a 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -160,7 +160,7 @@ EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} - grub-mkelfimage -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ + grub-mkimage -O i386-coreboot -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ memdisk tar search iso9660 configfile sh \ ata at_keyboard rm -f ${memdisk_img} @@ -171,7 +171,7 @@ fi if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ + grub-mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index cc4d950d2..9b4270ff6 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -213,7 +213,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma # The order in this list is critical. Be careful when modifying it. modules="$modules $fs_module $partmap_module $devabstraction_module" -$grub_mkimage --output=${grubdir}/grub.efi $modules || exit 1 +$grub_mkimage -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit 1 # Prompt the user to check if the device map is correct. echo "Installation finished. No error reported." diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 363f312db..4d00cc217 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -34,7 +34,7 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` -grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` @@ -189,7 +189,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma modules="$modules $fs_module $partmap_module $devabstraction_module" # Now perform the installation. -"$grub_mkimage" --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 +"$grub_mkimage" -O ${target_cpu}-ieee1275 --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 if test $update_nvram = yes; then set $ofpathname dummy diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in index 0110e799c..16658505b 100644 --- a/util/powerpc/ieee1275/grub-mkrescue.in +++ b/util/powerpc/ieee1275/grub-mkrescue.in @@ -30,7 +30,7 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` -grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage # Print the usage. @@ -104,7 +104,7 @@ boot_dir=${iso_dir}/boot/grub mkdir ${iso_dir}/boot mkdir ${boot_dir} core_img=${boot_dir}/grub.img -${grub_mkimage} -n -d ${input_dir}/ -o ${core_img} ${modules} +${grub_mkimage} -O powerpc-ieee1275 -n -d ${input_dir}/ -o ${core_img} ${modules} genisoimage -hfs -part -no-desktop -r -J -o ${output_image} \ -map ${map_file} -hfs-bless ${boot_dir} -chrp-boot -sysid PPC \ ${iso_dir}