From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1VSpjb-0004GJ-B3 for mharc-grub-devel@gnu.org; Sun, 06 Oct 2013 10:55:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40936) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VSpjE-0004Ek-Tq for grub-devel@gnu.org; Sun, 06 Oct 2013 10:55:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VSpiu-0003iW-Bn for grub-devel@gnu.org; Sun, 06 Oct 2013 10:54:40 -0400 Received: from mail-ee0-x236.google.com ([2a00:1450:4013:c00::236]:45898) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VSpit-0003gf-05 for grub-devel@gnu.org; Sun, 06 Oct 2013 10:54:20 -0400 Received: by mail-ee0-f54.google.com with SMTP id e53so2689897eek.41 for ; Sun, 06 Oct 2013 07:54:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type; bh=EYvM6s7hgLsRXJK2pAeImY2rwZ1gSAjWBNJpB5XK6/I=; b=zAr1Fs1dAH+ySYPv+wA/v3lFVlymxvbdyaWVai2b5Hcv4BOHoi2bLO1Qr84z3t1MaT lYNcvZhKCbR5BBAIKAu89xdWV67HItq5cGANrGW+aWJjorBM8AZuTatkwyAMdTIlWZZe 2SHOsbmLccwWHOF5OIZxZzM1ItCzdSAeChezm/vO02+GmlINHtGbcfZ9oh3WW6Yiu7jd G17OUa7kqX/nvTRwoPzjapmq4QDNoSDRaBqUJHl5Pcr5RkKKCggjwf20YXL91MrZswB6 E68TQ60XXZRrk7gpmWUznkhrZSDuhDPRyKl0s210VLBiVGMo+F913swGcA/+xqcRr34W KZgw== X-Received: by 10.14.184.132 with SMTP id s4mr41039985eem.13.1381071257162; Sun, 06 Oct 2013 07:54:17 -0700 (PDT) Received: from [192.168.1.113] (31-249.1-85.cust.bluewin.ch. [85.1.249.31]) by mx.google.com with ESMTPSA id bn13sm51995811eeb.11.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 06 Oct 2013 07:54:16 -0700 (PDT) Message-ID: <52517990.1020505@gmail.com> Date: Sun, 06 Oct 2013 16:54:08 +0200 From: =?UTF-8?B?VmxhZGltaXIgJ8+GLWNvZGVyL3BoY29kZXInIFNlcmJpbmVua28=?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130821 Icedove/17.0.8 MIME-Version: 1.0 To: The development of GRUB 2 Subject: Re: [RFC] grub-install C rewrite References: <524431E6.60807@gmail.com> In-Reply-To: <524431E6.60807@gmail.com> X-Enigmail-Version: 1.5.1 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="----enig2JSGICUDLKHXJILLBWCEK" X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4013:c00::236 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 06 Oct 2013 14:55:00 -0000 This is an OpenPGP/MIME signed message (RFC 4880 and 3156) ------enig2JSGICUDLKHXJILLBWCEK Content-Type: multipart/mixed; boundary="------------050304090405030404060303" This is a multi-part message in MIME format. --------------050304090405030404060303 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On 26.09.2013 15:08, Vladimir '=CF=86-coder/phcoder' Serbinenko wrote: > Hello, all. Recently I made some order in hostdisk.c and getroot.c > involving splitting in OS-specific parts. > In the same time I added WinAPI version of getroot/hostdisk allowing > grub-probe to work on windows natively > Also on-going is AROS-specific parts. > Windows and AROS are not friendly with bash. > The attempt to make both multiple files of same type work and handling > whitespaces/newlines/... in filenames would result in very ugly code > with loads of evals. > Current code may have subtle assumptions on behaviour of common tools > like sed and on locale (E.g. "[a-z]" doesn't cover u if locale is Eston= ian). > So to check viability I rewrote grub-install in C. This is mostly proof= > of concept with loads of FIXMEs but I could boot i386-pc install made > with it. In many aspects (static variables, some tests, general > structure) it's reminiscent of sh version of grub-install it's based on= =2E > Some functionality is likely to stay OS-specific, e.g. executing > compressors or determining firmware. Attached is the second iteration of this patch. Now the biggest problem is in reading /etc/default/grub and getting GRUB_DISTRIBUTOR and GRUB_ENABLE_CRYPTODISK. Trouble is that now this file is simply included in bash script and e.g. Debian uses it to determine GRUB_DISTRIBUTOR based on lsb_release output. Does anyone have an elegant solution for thi= s? --------------050304090405030404060303 Content-Type: text/x-diff; name="install_c.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="install_c.diff" =3D=3D=3D modified file 'Makefile.util.def' --- Makefile.util.def 2013-10-03 23:29:10 +0000 +++ Makefile.util.def 2013-10-04 13:50:03 +0000 @@ -159,6 +159,7 @@ mansection =3D 1; =20 common =3D util/grub-mkimage.c; + common =3D util/mkimage.c; common =3D util/resolve.c; common =3D grub-core/kern/emu/argp_common.c; =20 @@ -208,6 +209,7 @@ mansection =3D 1; =20 common =3D util/grub-editenv.c; + common =3D util/editenv.c; =20 ldadd =3D libgrubmods.a; ldadd =3D libgrubgcry.a; @@ -308,6 +310,7 @@ installdir =3D sbin; mansection =3D 8; common =3D util/grub-setup.c; + common =3D util/setup_bios.c; common =3D grub-core/kern/emu/argp_common.c; common =3D grub-core/lib/reed_solomon.c; =20 @@ -316,7 +319,7 @@ ldadd =3D libgrubgcry.a; ldadd =3D grub-core/gnulib/libgnu.a; ldadd =3D '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR= ) $(LIBGEOM)'; - cppflags =3D '-DGRUB_SETUP_BIOS=3D1'; + cppflags =3D '-DGRUB_SETUP_FUNC=3Dgrub_bios_setup'; }; =20 program =3D { @@ -324,6 +327,7 @@ installdir =3D sbin; mansection =3D 8; common =3D util/grub-setup.c; + common =3D util/setup_sparc.c; common =3D grub-core/kern/emu/argp_common.c; common =3D grub-core/lib/reed_solomon.c; common =3D util/ieee1275/ofpath.c; @@ -333,7 +337,7 @@ ldadd =3D libgrubgcry.a; ldadd =3D grub-core/gnulib/libgnu.a; ldadd =3D '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR= ) $(LIBGEOM)'; - cppflags =3D '-DGRUB_SETUP_SPARC64=3D1'; + cppflags =3D '-DGRUB_SETUP_FUNC=3Dgrub_sparc_setup'; }; =20 program =3D { @@ -464,14 +468,33 @@ common =3D util/grub-mkstandalone.in; }; =20 -script =3D { +program =3D { mansection =3D 8; installdir =3D sbin; name =3D grub-install; =20 - common =3D util/grub-install_header; - common =3D util/grub-install.in; + common =3D util/mkimage.c; + common =3D util/grub-install.c; + common =3D util/grub-install-common.c; + common =3D util/setup_bios.c; + common =3D util/setup_sparc.c; + common =3D grub-core/lib/reed_solomon.c; + common =3D util/random.c; + common =3D util/ieee1275/ofpath.c; + common =3D util/editenv.c; + + common =3D grub-core/kern/arm/dl_helper.c; + + common =3D util/resolve.c; enable =3D noemu; + common =3D grub-core/kern/emu/argp_common.c; + + ldadd =3D '$(LIBLZMA)'; + ldadd =3D libgrubmods.a; + ldadd =3D libgrubgcry.a; + ldadd =3D libgrubkern.a; + ldadd =3D grub-core/gnulib/libgnu.a; + ldadd =3D '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR= ) $(LIBGEOM)'; }; =20 script =3D { =3D=3D=3D modified file 'configure.ac' --- configure.ac 2013-09-23 11:48:10 +0000 +++ configure.ac 2013-10-04 10:59:26 +0000 @@ -73,14 +73,10 @@ TARGET_CFLAGS=3D"$TARGET_CFLAGS -Os" fi =20 -BUILD_CPPFLAGS=3D"$BUILD_CPPFLAGS -DLOCALEDIR=3D\\\"\$(localedir)\\\"" - # Default HOST_CPPFLAGS HOST_CPPFLAGS=3D"$HOST_CPPFLAGS -Wall -W" HOST_CPPFLAGS=3D"$HOST_CPPFLAGS -I\$(top_builddir)/include" HOST_CPPFLAGS=3D"$HOST_CPPFLAGS -DGRUB_UTIL=3D1" -HOST_CPPFLAGS=3D"$HOST_CPPFLAGS -DGRUB_LIBDIR=3D\\\"\$(pkglibdir)\\\"" -HOST_CPPFLAGS=3D"$HOST_CPPFLAGS -DLOCALEDIR=3D\\\"\$(localedir)\\\"" =20 TARGET_CPPFLAGS=3D"$TARGET_CPPFLAGS -Wall -W" TARGET_CPPFLAGS=3D"$TARGET_CPPFLAGS -I\$(top_srcdir)/include" @@ -1344,6 +1340,19 @@ AM_CONDITIONAL([COND_CYGWIN], [test x$target_os =3D xcygwin]) AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" =3D x]) =20 +test "x$prefix" =3D xNONE && prefix=3D"$ac_default_prefix" +test "x$exec_prefix" =3D xNONE && exec_prefix=3D"${prefix}" +datarootdir=3D"$(eval echo "$datarootdir")" +grub_libdir=3D"$(eval echo "$libdir")" +grub_localedir=3D"$(eval echo "$localedir")" +grub_datadir=3D"$(eval echo "$datadir")" +grub_sysconfdir=3D"$(eval echo "$sysconfdir")" +AC_DEFINE_UNQUOTED(LOCALEDIR, "$grub_localedir", [Locale dir]) +AC_DEFINE_UNQUOTED(GRUB_LIBDIR, "$grub_libdir", [Library dir]) +AC_DEFINE_UNQUOTED(GRUB_DATADIR, "$grub_datadir", [Data dir]) +AC_DEFINE_UNQUOTED(GRUB_SYSCONFDIR, "$sysconfdir", [Configuration dir]) + + # Output files. cpudir=3D"${target_cpu}" if test x${cpudir} =3D xmipsel; then =3D=3D=3D added file 'include/grub/util/install.h' --- include/grub/util/install.h 1970-01-01 00:00:00 +0000 +++ include/grub/util/install.h 2013-10-05 16:58:59 +0000 @@ -0,0 +1,189 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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_UTIL_INSTALL_HEADER +#define GRUB_UTIL_INSTALL_HEADER 1 + +#define GRUB_INSTALL_OPTIONS \ + { "modules", GRUB_INSTALL_OPTIONS_MODULES, N_("MODULES"), \ + 0, N_("pre-load specified modules MODULES"), 1 }, \ + { "install-modules", GRUB_INSTALL_OPTIONS_INSTALL_MODULES, \ + N_("MODULES"), 0, \ + N_("install only MODULES and their dependencies [default=3Dall]"), 1= }, \ + { "themes", GRUB_INSTALL_OPTIONS_INSTALL_THEMES, N_("THEMES"), \ + 0, N_("install THEMES [default=3D%s]"), 1 }, \ + { "fonts", GRUB_INSTALL_OPTIONS_INSTALL_FONTS, N_("FONTS"), \ + 0, N_("install FONTS [default=3D%s]"), 1 }, \ + { "locales", GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, N_("LOCALES"),\ + 0, N_("install only LOCALES [default=3Dall]"), 1 }, \ + { "compress", GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, \ + "no,xz,gz,lzo", OPTION_ARG_OPTIONAL, \ + N_("compress GRUB files [optional]"), 1 }, \ + /* TRANSLATORS: platform here isn't identifier. It can be translated= =2E */ \ + { "directory", 'd', N_("DIR"), 0, \ + N_("use images and modules under DIR [default=3D%s/]"), 1 = }, \ + { "override-directory", GRUB_INSTALL_OPTIONS_DIRECTORY2, \ + N_("DIR"), OPTION_HIDDEN, \ + N_("use images and modules under DIR [default=3D%s/]"), 1 = }, \ + { "grub-mkimage", GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, \ + "FILE", OPTION_HIDDEN, 0, 1 }, \ + /* TRANSLATORS: "embed" is a verb (command description). "*/ \ + { "pubkey", 'k', N_("FILE"), 0, \ + N_("embed FILE as public key for signature checking"), 0} + +int +grub_install_parse (int key, char *arg); + +void +grub_install_push_module (const char *val); + +char * +grub_install_help_filter (int key, const char *text, + void *input __attribute__ ((unused))); + +enum grub_install_plat + { + GRUB_INSTALL_PLATFORM_I386_PC, + GRUB_INSTALL_PLATFORM_I386_EFI, + GRUB_INSTALL_PLATFORM_I386_QEMU, + GRUB_INSTALL_PLATFORM_I386_COREBOOT, + GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, + GRUB_INSTALL_PLATFORM_I386_IEEE1275, + GRUB_INSTALL_PLATFORM_X86_64_EFI, + GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, + GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, + GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, + GRUB_INSTALL_PLATFORM_MIPSEL_ARC, + GRUB_INSTALL_PLATFORM_MIPS_ARC, + GRUB_INSTALL_PLATFORM_IA64_EFI, + GRUB_INSTALL_PLATFORM_ARM_UBOOT, + GRUB_INSTALL_PLATFORM_ARM_EFI, + GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, + GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, + }; + +enum grub_install_options { + GRUB_INSTALL_OPTIONS_DIRECTORY =3D 'd', + GRUB_INSTALL_OPTIONS_MODULES =3D 0x201, + GRUB_INSTALL_OPTIONS_INSTALL_MODULES, + GRUB_INSTALL_OPTIONS_INSTALL_THEMES, + GRUB_INSTALL_OPTIONS_INSTALL_FONTS, + GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, + GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, + GRUB_INSTALL_OPTIONS_DIRECTORY2, + GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE +}; + +void +grub_install_args_finish (void); + +extern char *grub_install_source_directory; + +char * +grub_install_concat_ext (size_t n, ...); +char * +grub_install_concat (size_t n, ...); + +enum grub_install_plat +grub_install_get_target (const char *src); +void +grub_install_mkdir_p (const char *dst); + +void +grub_install_copy_files (const char *src, + const char *dst, + enum grub_install_plat platid); +char * +grub_install_get_platform_name (enum grub_install_plat platid); + +const char * +grub_install_get_platform_cpu (enum grub_install_plat platid); + +const char * +grub_install_get_platform_platform (enum grub_install_plat platid); + + +typedef enum { + GRUB_COMPRESSION_AUTO, + GRUB_COMPRESSION_NONE, + GRUB_COMPRESSION_XZ, + GRUB_COMPRESSION_LZMA +} grub_compression_t; + +void +grub_install_make_image_wrap (const char *dir, const char *prefix, + const char *outname, char *memdisk_path, + char *config_path, + const char *format, int note, + grub_compression_t comp); + +void +grub_install_copy_file (const char *src, + const char *dst); + +struct grub_install_image_target_desc; + +void +grub_install_generate_image (const char *dir, const char *prefix, + FILE *out, const char *outname, char *mods[], + char *memdisk_path, char **pubkey_paths, + size_t npubkeys, + char *config_path, + struct grub_install_image_target_desc *image_target, int note, + grub_compression_t comp); + +struct grub_install_image_target_desc * +grub_install_get_image_target (const char *arg); +void +grub_bios_setup (const char *dir, + const char *boot_file, const char *core_file, + const char *dest, int force, + int fs_probe, int allow_floppy); +void +grub_sparc_setup (const char *dir, + const char *boot_file, const char *core_file, + const char *dest, int force, + int fs_probe, int allow_floppy); + +char * +grub_install_get_image_targets_string (void); + +const char * +grub_util_get_target_dirname (struct grub_install_image_target_desc *t);= + +#if !defined (__MINGW32__) && !defined (__CYGWIN__) + +int +grub_util_exec (char **argv); +int +grub_util_check_executable (const char *fn); +void +grub_util_exec_redirect (char **argv, const char *stdin_file, + const char *stdout_file); +int +grub_util_exec_redirect_null (char **argv); + +#endif + +int +grub_install_is_regular_file (const char *dir); + +void +grub_install_create_envblk_file (const char *name); + +#endif =3D=3D=3D added file 'util/editenv.c' --- util/editenv.c 1970-01-01 00:00:00 +0000 +++ util/editenv.c 2013-10-04 13:49:28 +0000 @@ -0,0 +1,66 @@ +/* grub-editenv.c - tool to edit environment block. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by= + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define DEFAULT_ENVBLK_SIZE 1024 + +void +grub_install_create_envblk_file (const char *name) +{ + FILE *fp; + char *buf; + char *namenew; + + buf =3D xmalloc (DEFAULT_ENVBLK_SIZE); + + namenew =3D xasprintf ("%s.new", name); + fp =3D fopen (namenew, "wb"); + if (! fp) + grub_util_error (_("cannot open `%s': %s"), namenew, + strerror (errno)); + + memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1= ); + memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', + DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1); + + if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) !=3D DEFAULT_ENVBLK_SIZE)= + grub_util_error (_("cannot write to `%s': %s"), namenew, + strerror (errno)); + + fsync (fileno (fp)); + free (buf); + fclose (fp); + + if (rename (namenew, name) < 0) + grub_util_error (_("cannot rename the file %s to %s"), namenew, name= ); + free (namenew); +} =3D=3D=3D modified file 'util/getroot_unix.c' --- util/getroot_unix.c 2013-09-24 17:19:31 +0000 +++ util/getroot_unix.c 2013-10-04 14:29:13 +0000 @@ -143,6 +143,77 @@ return path; } =20 +int +grub_util_exec (char **argv) +{ + pid_t pid; + int status =3D -1; + + pid =3D fork (); + if (pid < 0) + grub_util_error (_("Unable to fork: %s"), strerror (errno)); + else if (pid =3D=3D 0) + { + /* Child. */ + + /* Close fd's. */ + grub_util_devmapper_cleanup (); + grub_diskfilter_fini (); + + /* Ensure child is not localised. */ + setenv ("LC_ALL", "C", 1); + + execvp (argv[0], argv); + exit (127); + } + + waitpid (pid, &status, 0); + if (!WIFEXITED (status)) + return -1; + return WEXITSTATUS (status); +} + +void +grub_util_exec_redirect (char **argv, const char *stdin_file, + const char *stdout_file) +{ + pid_t mdadm_pid; + + mdadm_pid =3D fork (); + if (mdadm_pid < 0) + grub_util_error (_("Unable to fork: %s"), strerror (errno)); + else if (mdadm_pid =3D=3D 0) + { + int in, out; + /* Child. */ + =20 + /* Close fd's. */ + grub_util_devmapper_cleanup (); + grub_diskfilter_fini (); + + in =3D open (stdin_file, O_RDONLY); + dup2 (in, STDIN_FILENO); + close (in); + + out =3D open (stdout_file, O_WRONLY | O_CREAT, 0700); + dup2 (out, STDOUT_FILENO); + close (out); + + /* Ensure child is not localised. */ + setenv ("LC_ALL", "C", 1); + + execvp (argv[0], argv); + exit (127); + } +} + +void +grub_util_exec_redirect_null (char **argv, const char *stdin_file, + const char *stdout_file) +{ + grub_util_exec_redirect (argv, "/dev/null", "/dev/null"); +} + pid_t grub_util_exec_pipe (char **argv, int *fd) { @@ -518,11 +589,15 @@ } =20 char ** -grub_guess_root_devices (const char *dir) +grub_guess_root_devices (const char *dir_in) { char **os_dev =3D NULL; struct stat st; dev_t dev; + char *dir =3D canonicalize_file_name (dir_in); + + if (!dir) + grub_util_error (_("failed to get canonical path of `%s'"), dir_in);= =20 #ifdef __linux__ if (!os_dev) =3D=3D=3D modified file 'util/grub-editenv.c' --- util/grub-editenv.c 2013-09-27 00:08:32 +0000 +++ util/grub-editenv.c 2013-10-05 16:57:05 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include =20 #include #include @@ -32,7 +33,6 @@ =20 #include "progname.h" =20 -#define DEFAULT_ENVBLK_SIZE 1024 #define DEFAULT_ENVBLK_PATH DEFAULT_DIRECTORY "/" GRUB_ENVBLK_DEFCFG =20 static struct argp_option options[] =3D { @@ -108,38 +108,6 @@ NULL, help_filter, NULL }; =20 -static void -create_envblk_file (const char *name) -{ - FILE *fp; - char *buf; - char *namenew; - - buf =3D xmalloc (DEFAULT_ENVBLK_SIZE); - - namenew =3D xasprintf ("%s.new", name); - fp =3D fopen (namenew, "wb"); - if (! fp) - grub_util_error (_("cannot open `%s': %s"), namenew, - strerror (errno)); - - memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1= ); - memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', - DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1); - - if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) !=3D DEFAULT_ENVBLK_SIZE)= - grub_util_error (_("cannot write to `%s': %s"), namenew, - strerror (errno)); - - fsync (fileno (fp)); - free (buf); - fclose (fp); - - if (rename (namenew, name) < 0) - grub_util_error (_("cannot rename the file %s to %s"), namenew, name= ); - free (namenew); -} - static grub_envblk_t open_envblk_file (const char *name) { @@ -152,7 +120,7 @@ if (! fp) { /* Create the file implicitly. */ - create_envblk_file (name); + grub_install_create_envblk_file (name); fp =3D fopen (name, "rb"); if (! fp) grub_util_error (_("cannot open `%s': %s"), name, @@ -300,7 +268,7 @@ } =20 if (strcmp (command, "create") =3D=3D 0) - create_envblk_file (filename); + grub_install_create_envblk_file (filename); else if (strcmp (command, "list") =3D=3D 0) list_variables (filename); else if (strcmp (command, "set") =3D=3D 0) =3D=3D=3D added file 'util/grub-install-common.c' --- util/grub-install-common.c 1970-01-01 00:00:00 +0000 +++ util/grub-install-common.c 2013-10-05 16:59:27 +0000 @@ -0,0 +1,810 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009= ,2010,2011,2012,2013 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 +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +char * +grub_install_help_filter (int key, const char *text, + void *input __attribute__ ((unused))) +{ + switch (key) + { + case GRUB_INSTALL_OPTIONS_INSTALL_THEMES: + return xasprintf(text, "starfield"); + case GRUB_INSTALL_OPTIONS_INSTALL_FONTS: + return xasprintf(text, "unicode"); + case GRUB_INSTALL_OPTIONS_DIRECTORY: + case GRUB_INSTALL_OPTIONS_DIRECTORY2: + return xasprintf(text, GRUB_LIBDIR PACKAGE); =20 + default: + return (char *) text; + } +} + +static char **compress_argv; +static char *copy_buf; + +#define COPY_BUF_SIZE 1048576 + +static char * +grub_install_concat_real (size_t n, int ext, va_list ap) +{ + size_t totlen =3D 0; + char **l =3D xmalloc ((n + ext) * sizeof (l[0])); + char *r, *p, *pi; + size_t i; + int first =3D 1; + + for (i =3D 0; i < n + ext; i++) + { + l[i] =3D va_arg (ap, char *); + if (l[i]) + totlen +=3D strlen (l[i]) + 1; + } + + r =3D xmalloc (totlen + 10); + + p =3D r; + for (i =3D 0; i < n; i++) + { + pi =3D l[i]; + if (!pi) + continue; + while (*pi =3D=3D '/') + pi++; + if ((p !=3D r || (pi !=3D l[i] && first)) && (p =3D=3D r || *(p - = 1) !=3D '/')) + *p++ =3D '/'; + first =3D 0; + p =3D stpcpy (p, l[i]); + while (p !=3D r && p !=3D r + 1 && *(p - 1) =3D=3D '/') + p--; + } + + if (ext && l[i]) + p =3D stpcpy (p, l[i]); + + *p =3D '\0'; + + free (l); + + return r; +} + +char * +grub_install_concat (size_t n, ...) +{ + va_list ap; + char *r; + + va_start (ap, n); + + r =3D grub_install_concat_real (n, 0, ap); + + va_end (ap); + + return r; +} + +char * +grub_install_concat_ext (size_t n, ...) +{ + va_list ap; + char *r; + + va_start (ap, n); + + r =3D grub_install_concat_real (n, 1, ap); + + va_end (ap); + + return r; +} + +void +grub_install_copy_file (const char *src, + const char *dst) +{ + FILE *in, *out; + in =3D fopen (src, "rb"); + if (!in) + { + grub_util_warn (_("cannot open `%s': %s"), src, strerror (errno));= + return; + } + out =3D fopen (dst, "wb"); + if (!out) + { + grub_util_warn (_("cannot open `%s': %s"), dst, strerror (errno));= + fclose (in); + return; + } + + if (!copy_buf) + copy_buf =3D xmalloc (COPY_BUF_SIZE); +=20 + while (1) + { + size_t r; + r =3D fread (copy_buf, 1, COPY_BUF_SIZE, in); + if (r =3D=3D 0) + break; + fwrite (copy_buf, 1, r, out); + } + fclose (in); + fclose (out); + + return; +} + +int +grub_install_compress_file (const char *in_name, + const char *out_name, + int is_needed) +{ + FILE *in, *out; + in =3D fopen (in_name, "rb"); + if (!in && !is_needed && errno =3D=3D ENOENT) + return 0; + if (!in) + { + grub_util_warn (_("cannot open `%s': %s"), in_name, strerror (errn= o)); + return 0; + } + out =3D fopen (out_name, "wb"); + if (!out) + { + grub_util_warn (_("cannot open `%s': %s"), out_name, strerror (err= no)); + fclose (in); + return 0; + } + + if (!copy_buf) + copy_buf =3D xmalloc (COPY_BUF_SIZE); + + if (compress_argv) + { + fclose (in); + fclose (out); + grub_util_exec_redirect (compress_argv, in_name, + out_name); + return 1; + } + + while (1) + { + size_t r; + r =3D fread (copy_buf, 1, COPY_BUF_SIZE, in); + if (r =3D=3D 0) + break; + fwrite (copy_buf, 1, r, out); + } + fclose (in); + fclose (out); + + return 1; +} + +static int +is_path_separator (char c) +{ +#if defined (__MINGW32__) || defined (__CYGWIN__) + if (c =3D=3D '\\') + return 1; +#endif + if (c =3D=3D '/') + return 1; + return 0; +} + +void +grub_install_mkdir_p (const char *dst) +{ + char *t =3D xstrdup (dst); + char *p; + for (p =3D t; *p; p++) + { + if (is_path_separator (*p)) + { + char s =3D *p; + *p =3D '\0'; + mkdir (t, 0700); + *p =3D s; + } + } + mkdir (t, 0700); +} + +static void +clean_grub_dir (const char *di) +{ + DIR *d; + struct dirent *de; + + d =3D opendir (di); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + di, strerror (errno)); + + while ((de =3D readdir (d))) + { + const char *ext =3D strrchr (de->d_name, '.'); + if ((ext && (strcmp (ext, ".mod") =3D=3D 0 + || strcmp (ext, ".lst") =3D=3D 0 + || strcmp (ext, ".img") =3D=3D 0 + || strcmp (ext, ".mo") =3D=3D 0) + && strcmp (de->d_name, "menu.lst") !=3D 0) + || strcmp (de->d_name, "efiemu32.o") =3D=3D 0 + || strcmp (de->d_name, "efiemu64.o") =3D=3D 0) + { + char *x =3D grub_install_concat (2, di, de->d_name); + if (unlink (x) < 0) + grub_util_error ("cannont delete `%s': %s", x, strerror (errno)); + free (x); + } + } + closedir (d); +} + +struct install_list +{ + int is_default; + char **entries; + size_t n_entries; + size_t n_alloc; +}; + +struct install_list install_modules =3D { 1, 0, 0, 0 }; +struct install_list modules =3D { 1, 0, 0, 0 }; +struct install_list install_locales =3D { 1, 0, 0, 0 }; +struct install_list install_fonts =3D { 1, 0, 0, 0 }; +struct install_list install_themes =3D { 1, 0, 0, 0 }; +char *grub_install_source_directory =3D NULL; + +void +grub_install_push_module (const char *val) +{ + modules.is_default =3D 0; + if (modules.n_entries + 1 >=3D modules.n_alloc) + { + modules.n_alloc <<=3D 1; + if (modules.n_alloc < 16) + modules.n_alloc =3D 16; + modules.entries =3D xrealloc (modules.entries, + modules.n_alloc * sizeof (modules.entries)); + } + modules.entries[modules.n_entries++] =3D xstrdup (val); + modules.entries[modules.n_entries] =3D NULL; +} + +static void +handle_install_list (struct install_list *il, const char *val, + int default_all) +{ + const char *ptr; + char **ce; + il->is_default =3D 0; + free (il->entries); + il->entries =3D NULL; + il->n_entries =3D 0; + if (strcmp (val, "all") =3D=3D 0 && default_all) + { + il->is_default =3D 1; + return; + } + ptr =3D val; + while (1) + { + while (*ptr && grub_isspace (*ptr)) + ptr++; + if (!*ptr) + break; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + il->n_entries++; + } + il->n_alloc =3D il->n_entries + 1; + il->entries =3D xmalloc (il->n_alloc * sizeof (il->entries[0])); + for (ce =3D il->entries; ; ce++) + { + const char *bptr; + while (*ptr && grub_isspace (*ptr)) + ptr++; + if (!*ptr) + break; + bptr =3D ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + *ce =3D xmalloc (ptr - bptr + 1); + memcpy (*ce, bptr, ptr - bptr); + (*ce)[ptr - bptr] =3D '\0'; + ce++; + } + *ce =3D NULL; +} + +static char *compress_gzip[] =3D { (char *) "gzip", (char *) "--best", + (char *) "--stdout", NULL }; +static char *compress_xz[] =3D { (char *) "xz", + (char *) "--lzma2=3Ddict=3D128KiB", + (char *) "--check=3Dnone", + (char *) "--stdout", NULL }; +static char *compress_lzo[] =3D {(char *) "lzop", + (char *) "-9",=20 + (char *) "-c", NULL }; +static char **pubkeys; +static size_t npubkeys; + +int +grub_install_parse (int key, char *arg) +{ + switch (key) + { + case 'k': + pubkeys =3D xrealloc (pubkeys, + sizeof (pubkeys[0]) + * (npubkeys + 1)); + pubkeys[npubkeys++] =3D xstrdup (arg); + return 1; + + case GRUB_INSTALL_OPTIONS_DIRECTORY: + case GRUB_INSTALL_OPTIONS_DIRECTORY2: + free (grub_install_source_directory); + grub_install_source_directory =3D xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_MODULES: + handle_install_list (&install_modules, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_MODULES: + handle_install_list (&modules, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_LOCALES: + handle_install_list (&install_locales, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_THEMES: + handle_install_list (&install_themes, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_FONTS: + handle_install_list (&install_fonts, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS: + if (strcmp (arg, "no") =3D=3D 0) + { + compress_argv =3D NULL; + return 1; + } + if (strcmp (arg, "gz") =3D=3D 0) + { + compress_argv =3D compress_gzip; + return 1; + } + if (strcmp (arg, "xz") =3D=3D 0) + { + compress_argv =3D compress_xz; + return 1; + } + if (strcmp (arg, "lzo") =3D=3D 0) + { + compress_argv =3D compress_lzo; + return 1; + } + grub_util_error (_("Unrecognized compression `%s'"), arg); + case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE: + return 1; + default: + return 0; + } +} + +void +grub_install_args_finish (void) +{ + if (compress_argv =3D=3D compress_gzip) + grub_install_push_module ("gzio"); + if (compress_argv =3D=3D compress_xz) + { + grub_install_push_module ("xzio"); + grub_install_push_module ("gcry_crc"); + } + if (compress_argv =3D=3D compress_lzo) + { + grub_install_push_module ("lzopio"); + grub_install_push_module ("adler32"); + grub_install_push_module ("gcry_crc"); + } +} + +void +grub_install_make_image_wrap (const char *dir, const char *prefix, + const char *outname, char *memdisk_path, + char *config_path, + const char *mkimage_target, int note, + grub_compression_t comp) +{ + FILE *fp =3D stdout; + struct grub_install_image_target_desc *tgt; + fp =3D fopen (outname, "wb"); + if (! fp) + grub_util_error (_("cannot open `%s': %s"), outname, + strerror (errno)); + tgt =3D grub_install_get_image_target (mkimage_target); + if (!tgt) + grub_util_error (_("unknown target format %s\n"), mkimage_target); + + + + grub_install_generate_image (dir, prefix, fp, outname, + modules.entries, memdisk_path, + pubkeys, npubkeys, config_path, tgt, + note, comp); + fflush (fp); + fsync (fileno (fp)); + fclose (fp); +} + +static void +copy_by_ext (const char *srcd, + const char *dstd, + const char *extf, + int req) +{ + DIR *d; + struct dirent *de; + + d =3D opendir (srcd); + if (!d && !req) + return; + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + srcd, strerror (errno)); + + while ((de =3D readdir (d))) + { + const char *ext =3D strrchr (de->d_name, '.'); + if (ext && strcmp (ext, extf) =3D=3D 0) + { + char *srcf =3D grub_install_concat (2, srcd, de->d_name); + char *dstf =3D grub_install_concat (2, dstd, de->d_name); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + } + closedir (d); +} + +static void +copy_all (const char *srcd, + const char *dstd) +{ + DIR *d; + struct dirent *de; + + d =3D opendir (srcd); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + srcd, strerror (errno)); + + while ((de =3D readdir (d))) + { + char *srcf; + char *dstf; + if (strcmp (de->d_name, ".") =3D=3D 0 + || strcmp (de->d_name, "..") =3D=3D 0) + continue; + srcf =3D grub_install_concat (2, srcd, de->d_name); + dstf =3D grub_install_concat (2, dstd, de->d_name); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + closedir (d); +} + +static void +copy_locales (const char *dstd) +{ + DIR *d; + struct dirent *de; + + d =3D opendir (LOCALEDIR); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + LOCALEDIR, strerror (errno)); + + while ((de =3D readdir (d))) + { + char *srcf =3D grub_install_concat_ext (3, LOCALEDIR, de->d_name, + PACKAGE, ".mo"); + char *dstf =3D grub_install_concat_ext (2, dstd, de->d_name, ".mo"= ); + grub_install_compress_file (srcf, dstf, 0); + free (srcf); + free (dstf); + } + closedir (d); +} + +static struct +{ + enum grub_install_plat val; + const char *cpu; + const char *platform; +} platforms[] =3D + { + { GRUB_INSTALL_PLATFORM_I386_PC, "i386", "pc" }, + { GRUB_INSTALL_PLATFORM_I386_EFI, "i386", "efi" }, + { GRUB_INSTALL_PLATFORM_I386_QEMU, "i386", "qemu" }, + { GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386", "coreboot" }, + { GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386", "multiboot" }, + { GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386", "ieee1275" }, + { GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64", "efi" }, + { GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel", "loongson" }, + { GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel", "qemu_mips" }, + { GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips", "qemu_mips" }, + { GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel", "arc" }, + { GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips", "arc" }, + { GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, "sparc64", "ieee1275" }, + { GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc", "ieee1275" }, + { GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64", "efi" }, + { GRUB_INSTALL_PLATFORM_ARM_EFI, "arm", "efi" }, + { GRUB_INSTALL_PLATFORM_ARM_UBOOT, "arm", "uboot" }, + };=20 + +char * +grub_install_get_platform_name (enum grub_install_plat platid) +{ + return xasprintf ("%s-%s", platforms[platid].cpu, + platforms[platid].platform); +} + +const char * +grub_install_get_platform_cpu (enum grub_install_plat platid) +{ + return platforms[platid].cpu; +} + +const char * +grub_install_get_platform_platform (enum grub_install_plat platid) +{ + return platforms[platid].platform; +} + +int +grub_install_is_regular_file (const char *dir) +{ + struct stat st; + if (stat (dir, &st) < 0) + return 0; + return S_ISREG (st.st_mode); +} + +void +grub_install_copy_files (const char *src, + const char *dst, + enum grub_install_plat platid) +{ + char *dst_platform, *dst_locale, *dst_fonts; + char *platform =3D xasprintf ("%s-%s", platforms[platid].cpu, + platforms[platid].platform); + const char *pkgdatadir =3D secure_getenv ("pkgdatadir"); + if (!pkgdatadir) + pkgdatadir =3D GRUB_DATADIR "/" PACKAGE; + + dst_platform =3D grub_install_concat (2, dst, platform); + dst_locale =3D grub_install_concat (2, dst, "locale"); + dst_fonts =3D grub_install_concat (2, dst, "fonts"); + grub_install_mkdir_p (dst_platform); + grub_install_mkdir_p (dst_locale); + clean_grub_dir (dst); + clean_grub_dir (dst_platform); + clean_grub_dir (dst_locale); + + if (install_modules.is_default) + copy_by_ext (src, dst_platform, ".mod", 1); + else + { + struct grub_util_path_list *path_list, *p; + + path_list =3D grub_util_resolve_dependencies (src, "moddep.lst", + install_modules.entries); + for (p =3D path_list; p; p =3D p->next) + { + char *srcf =3D grub_install_concat_ext (2, src, p->name, ".mo"); + char *dstf =3D grub_install_concat_ext (2, dst, p->name, ".mo"); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + } + + const char *pkglib_DATA[] =3D {"efiemu32.o", "efiemu64.o", + "moddep.lst", "command.lst", + "fs.lst", "partmap.lst", + "parttool.lst", + "video.lst", "crypto.lst", + "terminal.lst" }; + size_t i; + + for (i =3D 0; i < ARRAY_SIZE (pkglib_DATA); i++) + { + char *srcf =3D grub_install_concat (2, src, pkglib_DATA[i]); + char *dstf =3D grub_install_concat (2, dst_platform, pkglib_DATA[i= ]); + if (i =3D=3D 0 || i =3D=3D 1) + grub_install_compress_file (srcf, dstf, 0); + else + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + + if (install_locales.is_default) + { + char *srcd =3D grub_install_concat (2, src, "po"); + copy_by_ext (srcd, dst_locale, ".mo", 0); + copy_locales (dst_locale); + free (srcd); + } + else + { + for (i =3D 0; i < install_locales.n_entries; i++) + { + char *srcf =3D grub_install_concat_ext (3, src, + "po", + install_locales.entries[i], + ".mo"); + char *dstf =3D grub_install_concat_ext (2, dst_locale, + install_locales.entries[i], + ".mo"); + if (grub_install_compress_file (srcf, dstf, 0)) + { + free (srcf); + free (dstf); + continue; + } + free (srcf); + srcf =3D grub_install_concat_ext (4, + LOCALEDIR, + install_locales.entries[i], + "LC_MESSAGES", + PACKAGE, + ".mo"); + if (grub_install_compress_file (srcf, dstf, 0)) + { + free (srcf); + free (dstf); + continue; + } + grub_util_error (_("cannot find locale `%s'"), + install_locales.entries[i]); + } + } + + if (install_themes.is_default) + { + install_themes.is_default =3D 0; + install_themes.n_entries =3D 1; + install_themes.entries =3D xmalloc (2 * sizeof (install_themes.ent= ries[0])); + install_themes.entries[0] =3D xstrdup ("starfield"); + install_themes.entries[1] =3D NULL; + } + + for (i =3D 0; i < install_themes.n_entries; i++) + { + char *srcf =3D grub_install_concat (4, pkgdatadir, "themes", + install_themes.entries[i], + "theme.txt"); + if (grub_install_is_regular_file (srcf)) + { + char *srcd =3D grub_install_concat (3, pkgdatadir, "themes", + install_themes.entries[i]); + char *dstd =3D grub_install_concat (3, dst, "themes", + install_themes.entries[i]); + copy_all (srcd, dstd); + free (srcd); + free (dstd); + } + } + + if (install_fonts.is_default) + { + install_fonts.is_default =3D 0; + install_fonts.n_entries =3D 1; + install_fonts.entries =3D xmalloc (2 * sizeof (install_fonts.entri= es[0])); + install_fonts.entries[0] =3D xstrdup ("unicode"); + install_fonts.entries[1] =3D NULL; + } + + for (i =3D 0; i < install_fonts.n_entries; i++) + { + char *srcf =3D grub_install_concat_ext (2, pkgdatadir, + install_fonts.entries[i], + ".pf2"); + char *dstf =3D grub_install_concat_ext (2, dst_fonts, + install_fonts.entries[i], + ".pf2"); + + grub_install_compress_file (srcf, dstf, 0); + free (srcf); + free (dstf); + } +} + +enum grub_install_plat +grub_install_get_target (const char *src) +{ + char *fn; + FILE *f; + char buf[2048]; + size_t r; + char *c, *pl, *p; + size_t i; + fn =3D grub_install_concat (2, src, "modinfo.sh"); + f =3D fopen (fn, "r"); + if (!f) + grub_util_error (_("%s doesn't exist. Please specify --target or --d= irectory"),=20 + fn); + r =3D fread (buf, 1, sizeof (buf) - 1, f); + buf[r] =3D '\0'; + c =3D strstr (buf, "grub_modinfo_target_cpu=3D"); + if (!c || (c !=3D buf && !grub_isspace (*(c-1)))) + grub_util_error (_("invalid modinfo file `%s'"), fn); + pl =3D strstr (buf, "grub_modinfo_platform=3D"); + if (!pl || (pl !=3D buf && !grub_isspace (*(pl-1)))) + grub_util_error (_("invalid modinfo file `%s'"), fn); + c +=3D sizeof ("grub_modinfo_target_cpu=3D") - 1; + pl +=3D sizeof ("grub_modinfo_platform=3D") - 1; + for (p =3D c; *p && !grub_isspace (*p); p++); + *p =3D '\0'; + for (p =3D pl; *p && !grub_isspace (*p); p++); + *p =3D '\0'; + + for (i =3D 0; i < ARRAY_SIZE (platforms); i++) + if (strcmp (platforms[i].cpu, c) =3D=3D 0 + && strcmp (platforms[i].platform, pl) =3D=3D 0) + return platforms[i].val; + grub_util_error (_("Unknown platform `%s-%s'"), c, pl); +} =3D=3D=3D added file 'util/grub-install.c' --- util/grub-install.c 1970-01-01 00:00:00 +0000 +++ util/grub-install.c 2013-10-04 14:37:48 +0000 @@ -0,0 +1,1684 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009= ,2010,2011,2012,2013 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 +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "argp.h" + +#include "progname.h" + +static char *target; +static int removable =3D 0; +static int recheck =3D 0; +static int update_nvram =3D 1; +static char *install_device =3D NULL; +static char *debug_image =3D NULL; +static char *rootdir =3D NULL; +static char *bootdir =3D NULL; +static int efi_quiet =3D 0; +static int allow_floppy =3D 0; +static int force_file_id =3D 0; +static char *disk_module =3D NULL; +static char *efidir =3D NULL; +static int force =3D 0; +static int have_abstractions =3D 0; +static int have_cryptodisk =3D 0; +static char * bootloader_id; +static int have_load_cfg =3D 0; +static FILE * load_cfg_f =3D NULL; +static char *load_cfg; + +enum + { + OPTION_BOOT_DIRECTORY =3D 0x301, + OPTION_ROOT_DIRECTORY, + OPTION_TARGET, + OPTION_SETUP, + OPTION_MKRELPATH,=20 + OPTION_MKDEVICEMAP,=20 + OPTION_PROBE,=20 + OPTION_EDITENV,=20 + OPTION_ALLOW_FLOPPY,=20 + OPTION_RECHECK,=20 + OPTION_FORCE, + OPTION_FORCE_FILE_ID, + OPTION_MODULE,=20 + OPTION_NO_NVRAM,=20 + OPTION_REMOVABLE,=20 + OPTION_BOOTLOADER_ID,=20 + OPTION_EFI_DIRECTORY, + OPTION_FONT, + OPTION_DEBUG, + OPTION_DEBUG_IMAGE, + OPTION_NO_FLOPPY, + OPTION_DISK_MODULE + }; + +static error_t=20 +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_FORCE_FILE_ID: + force_file_id =3D 1; + return 0; + /* Accept and ignore for compatibility. */ + case OPTION_FONT: + case OPTION_SETUP: + case OPTION_MKRELPATH: + case OPTION_PROBE: + case OPTION_EDITENV: + case OPTION_MKDEVICEMAP: + case OPTION_NO_FLOPPY: + return 0; + case OPTION_ROOT_DIRECTORY: + /* Accept for compatibility. */ + free (rootdir); + rootdir =3D xstrdup (arg); + return 0; + + case OPTION_BOOT_DIRECTORY: + free (bootdir); + bootdir =3D xstrdup (arg); + return 0; + + case OPTION_EFI_DIRECTORY: + free (efidir); + efidir =3D xstrdup (arg); + return 0; + + case OPTION_DISK_MODULE: + free (disk_module); + disk_module =3D xstrdup (arg); + return 0; + + case OPTION_TARGET: + free (target); + target =3D xstrdup (arg); + return 0; + + case OPTION_DEBUG_IMAGE: + free (debug_image); + debug_image =3D xstrdup (arg); + return 0; + + case OPTION_NO_NVRAM: + update_nvram =3D 0; + return 0; + + case OPTION_FORCE: + force =3D 1; + return 0; + + case OPTION_RECHECK: + recheck =3D 1; + return 0; + + case OPTION_REMOVABLE: + removable =3D 1; + return 0; + + case OPTION_ALLOW_FLOPPY: + allow_floppy =3D 1; + return 0; + + case OPTION_DEBUG: + verbosity++; + return 0; + + case OPTION_BOOTLOADER_ID: + free (bootloader_id); + bootloader_id =3D xstrdup (arg); + return 0; + + case ARGP_KEY_ARG: + if (install_device) + grub_util_error ("%s", _("More than one install device?")); + install_device =3D xstrdup (arg); + return 0; + + default: + return ARGP_ERR_UNKNOWN; + } +} + + +static struct argp_option options[] =3D { + GRUB_INSTALL_OPTIONS, + {"boot-directory", OPTION_BOOT_DIRECTORY, N_("DIR"), + 0, N_("install GRUB images under the directory DIR/%s instead of the = %s directory"), 2}, + {"root-directory", OPTION_ROOT_DIRECTORY, N_("DIR"), + OPTION_HIDDEN, 0, 2}, + {"font", OPTION_FONT, N_("FILE"), + OPTION_HIDDEN, 0, 2}, + {"target", OPTION_TARGET, N_("TARGET"), + /* TRANSLATORS: "TARGET" as in "target platform". */ + 0, N_("install GRUB for TARGET platform [default=3D%s]"), 2}, + {"grub-setup", OPTION_SETUP, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-mkrelpath", OPTION_MKRELPATH, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-mkdevicemap", OPTION_MKDEVICEMAP, "FILE", OPTION_HIDDEN, 0, 2},= + {"grub-probe", OPTION_PROBE, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-editenv", OPTION_EDITENV, "FILE", OPTION_HIDDEN, 0, 2}, + {"allow-floppy", OPTION_ALLOW_FLOPPY, 0, 0, + /* TRANSLATORS: "may break" doesn't just mean that option wouldn't ha= ve any + effect but that it will make the resulting install unbootable from= HDD. */ + N_("make the drive also bootable as floppy (default for fdX devices).= " + " May break on some BIOSes."), 2}, + {"recheck", OPTION_RECHECK, 0, 0, + N_("delete device map if it already exists"), 2}, + {"force", OPTION_FORCE, 0, 0, + N_("install even if problems are detected"), 2}, + {"force-file-id", OPTION_FORCE_FILE_ID, 0, 0, + N_("use identifier file even if UUID is available"), 2}, + {"disk-module", OPTION_MODULE, N_("MODULE"), 0, + N_("disk module to use (biosdisk or native). " + "This option is only available on BIOS target."), 2}, + {"no-nvram", OPTION_NO_NVRAM, 0, 0, + N_("don't update the `boot-device' NVRAM variable. " + "This option is only available on IEEE1275 targets."), 2}, + + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2}, + {"debug-image", OPTION_DEBUG_IMAGE, "STR", OPTION_HIDDEN, 0, 2}, + {"removable", OPTION_REMOVABLE, 0, 0, + N_("the installation device is removable. " + "This option is only available on EFI."), 2}, + {"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0, + N_("the ID of bootloader. This option is only available on EFI."), 2}= , + {"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0, + N_("use DIR as the EFI System Partition root."), 2}, + {0, 0, 0, 0, 0, 0} +}; + +static int +is_directory (const char *dir) +{ + struct stat st; + if (stat (dir, &st) < 0) + return 0; + return S_ISDIR (st.st_mode); +} + +#ifdef __linux__ +static int +is_not_empty_directory (const char *dir) +{ + DIR *d; + struct dirent *de; + + d =3D opendir (dir); + if (!d) + return 0; + while ((de =3D readdir (d))) + { + if (strcmp (de->d_name, ".") =3D=3D 0 + || strcmp (de->d_name, "..") =3D=3D 0) + continue; + closedir (d); + return 1; + } + + closedir (d); + return 0; +} + + +#include + +static int +is_64_kernel (void) +{ + struct utsname un; + + if (uname (&un) < 0) + return 0; + + return strcmp (un.machine, "x86_64") =3D=3D 0; +} + +#endif + +static const char * +get_default_platform (void) +{ +#ifdef __powerpc__ + return "powerpc-ieee1275"; +#elif defined (__sparc__) || defined (__sparc64__) + return "sparc64-ieee1275"; +#elif defined (__MIPSEL__) + return "mipsel-loongson"; +#elif defined (__MIPSEB__) + return "mips-arc"; +#elif defined (__ia64__) + return "ia64-efi"; +#elif defined (__arm__) + return "arm-uboot"; +#elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) + /* + On Linux, we need the efivars kernel modules. + If no EFI is available this module just does nothing + besides a small hello and if we detect efi we'll load it + anyway later. So it should be safe to + try to load it here. + */ +#ifdef __linux__ + grub_util_exec ((char * []){ (char *) "modprobe", (char *) "-q", + (char *) "efivars", NULL }); +#endif + if (is_not_empty_directory ("/sys/firmware/efi")) + { + if (is_64_kernel ()) + return "x86_64-efi"; + else + return "i386-efi"; + } + else if (is_not_empty_directory ("/proc/device-tree")) + return "i386-ieee1275"; + else + return "i386-pc"; +#else + return NULL; +#endif +} + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unus= ed))) +{ + switch (key) + { + case OPTION_BOOT_DIRECTORY: + return xasprintf (text, GRUB_DIR_NAME, GRUB_BOOT_DIR_NAME "/" GRUB= _DIR_NAME); + case OPTION_TARGET: + return xasprintf (text, get_default_platform ()); + case ARGP_KEY_HELP_POST_DOC: + return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_= DIR_NAME); + default: + return grub_install_help_filter (key, text, input); + } +} + +/* TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you= + install to. */ +struct argp argp =3D { + options, argp_parser, N_("[OPTION] [INSTALL_DEVICE]"), + N_("Install GRUB on your drive.")"\v" + N_("INSTALL_DEVICE must be system device filename.\n" + "%s copies GRUB images into %s. On some platforms, it" + " may also install GRUB into the boot sector."),=20 + NULL, help_filter, NULL +}; + +static int +probe_raid_level (grub_disk_t disk) +{ + /* disk might be NULL in the case of a LVM physical volume with no LVM= + signature. Ignore such cases here. */ + if (!disk) + return -1; + + if (disk->dev->id !=3D GRUB_DISK_DEVICE_DISKFILTER_ID) + return -1; + + if (disk->name[0] !=3D 'm' || disk->name[1] !=3D 'd') + return -1; + + if (!((struct grub_diskfilter_lv *) disk->data)->segments) + return -1; + return ((struct grub_diskfilter_lv *) disk->data)->segments->type; +} + +static void +probe_mods (grub_disk_t disk) +{ + grub_partition_t part; + grub_disk_memberlist_t list =3D NULL, tmp; + int raid_level; + + if (disk->partition =3D=3D NULL) + grub_util_info ("no partition map found for %s", disk->name); + + for (part =3D disk->partition; part; part =3D part->parent) + { + char buf[50]; + if (strcmp (part->partmap->name, "openbsd") =3D=3D 0 + || strcmp (part->partmap->name, "netbsd") =3D=3D 0) + { + grub_install_push_module ("part_bsd"); + continue; + } + snprintf (buf, sizeof (buf), "part_%s", part->partmap->name); + grub_install_push_module (buf); + } + + if (disk->dev->id =3D=3D GRUB_DISK_DEVICE_DISKFILTER_ID) + { + grub_diskfilter_get_partmap (disk, grub_install_push_module); + have_abstractions =3D 1; + } + + if (disk->dev->id =3D=3D GRUB_DISK_DEVICE_DISKFILTER_ID + && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) =3D=3D 0= || + grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) =3D=3D 0)) + grub_install_push_module ("lvm"); + + if (disk->dev->id =3D=3D GRUB_DISK_DEVICE_DISKFILTER_ID + && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) =3D=3D 0)= + grub_install_push_module ("ldm"); + + if (disk->dev->id =3D=3D GRUB_DISK_DEVICE_CRYPTODISK_ID) + { + grub_util_cryptodisk_get_abstraction (disk, + grub_install_push_module); + have_abstractions =3D 1; + have_cryptodisk =3D 1; + } + + raid_level =3D probe_raid_level (disk); + if (raid_level >=3D 0) + { + grub_install_push_module ("diskfilter"); + if (disk->dev->raidname) + grub_install_push_module (disk->dev->raidname (disk)); + } + if (raid_level =3D=3D 5) + grub_install_push_module ("raid5rec"); + if (raid_level =3D=3D 6) + grub_install_push_module ("raid6rec"); + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->memberlist) + list =3D disk->dev->memberlist (disk); + while (list) + { + probe_mods (list->disk); + tmp =3D list->next; + free (list); + list =3D tmp; + } +} + +static int +have_bootdev (enum grub_install_plat pl) +{ + switch (pl) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + return 1; + + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + return 0; + } + return 0; +} + +static void +probe_cryptodisk_uuid (grub_disk_t disk) +{ + grub_disk_memberlist_t list =3D NULL, tmp; + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->memberlist) + { + list =3D disk->dev->memberlist (disk); + } + while (list) + { + probe_cryptodisk_uuid (list->disk); + tmp =3D list->next; + free (list); + list =3D tmp; + } + if (disk->dev->id =3D=3D GRUB_DISK_DEVICE_CRYPTODISK_ID) + { + const char *uuid =3D grub_util_cryptodisk_get_uuid (disk); + if (!load_cfg_f) + load_cfg_f =3D fopen (load_cfg, "wb"); + have_load_cfg =3D 1; + + fprintf (load_cfg_f, "cryptomount -u %s\n", + uuid); + } +} + +static int +is_same_disk (const char *a, const char *b) +{ + while (1) + { + if ((*a =3D=3D ',' || *a =3D=3D '\0') && (*b =3D=3D ',' || *b =3D=3D= '\0')) + return 1; + if (*a !=3D *b) + return 0; + if (*a =3D=3D '\\') + { + if (a[1] !=3D b[1]) + return 0; + a +=3D 2; + b +=3D 2; + continue; + } + a++; + b++; + } +} + +char * +get_rndstr (void) +{ + grub_uint8_t rnd[15]; + const size_t sz =3D sizeof (rnd) * GRUB_CHAR_BIT / 5; + char * ret =3D xmalloc (sz + 1); + size_t i; + if (grub_get_random (rnd, sizeof (rnd))) + grub_util_error ("%s", _("couldn't retrieve random data")); + for (i =3D 0; i < sz; i++) + { + grub_size_t b =3D i * 5; + grub_uint8_t r; + grub_size_t f1 =3D GRUB_CHAR_BIT - b % GRUB_CHAR_BIT; + grub_size_t f2; + if (f1 > 5) + f1 =3D 5; + f2 =3D 5 - f1; + r =3D (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1)= - 1); + if (f2) + r |=3D (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1; + if (r < 10) + ret[i] =3D '0' + r; + else + ret[i] =3D 'a' + (r - 10); + } + ret[sz] =3D '\0'; + return ret; +} + +static char * +escape (const char *in) +{ + char *ptr; + char *ret; + int overhead =3D 0; + + for (ptr =3D (char*)in; *ptr; ptr++) + if (*ptr =3D=3D '\'') + overhead +=3D 3; + ret =3D grub_malloc (ptr - in + overhead + 1); + if (!ret) + return NULL; + + grub_strchrsub (ret, in, '\'', "'\\''"); + return ret; +} + +static int is_cryptodisk_enabled =3D 0; +static char *grub_distributor =3D 0; + +static int +load_config (void) +{ + char *fn =3D grub_install_concat (3, GRUB_SYSCONFDIR, + "default", "grub"); + FILE *f =3D fopen (fn, "r"); + const char *v; + v =3D secure_getenv ("GRUB_ENABLE_CRYPTODISK"); + if (v && v[0] =3D=3D 'y' && v[1] =3D=3D '\0') + is_cryptodisk_enabled =3D 1; + + v =3D secure_getenv ("GRUB_DISTRIBUTOR"); + if (v) + grub_distributor =3D xstrdup (v); + + if (f) + { + /* FIXME: GRUB_DISTRIBUTOR, GRUB_ENABLE_CRYPTODISK. */ + fclose (f); + } + return 0; +} + +static void +device_map_check_duplicates (const char *dev_map) +{ + FILE *fp; + char buf[1024]; /* XXX */ + size_t alloced =3D 8; + size_t filled =3D 0; + char **d; + size_t i; + + d =3D xmalloc (alloced * sizeof (d[0])); + + if (dev_map[0] =3D=3D '\0') + return; + + fp =3D fopen (dev_map, "r"); + if (! fp) + return; + + while (fgets (buf, sizeof (buf), fp)) + { + char *p =3D buf; + char *e; + + /* Skip leading spaces. */ + while (*p && grub_isspace (*p)) + p++; + + /* If the first character is `#' or NUL, skip this line. */ + if (*p =3D=3D '\0' || *p =3D=3D '#') + continue; + + if (*p !=3D '(') + continue; + + p++; + + e =3D p; + p =3D strchr (p, ')'); + if (! p) + continue; + + if (filled >=3D alloced) + { + alloced *=3D 2; + d =3D xrealloc (d, alloced * sizeof (d[0])); + } + + *p =3D '\0'; + + d[filled++] =3D xstrdup (e); + } + + fclose (fp); + + qsort (d, sizeof (d[0]), filled, (int (*) (const void *, const void *)= )strcmp); + + for (i =3D 0; i + 1 < filled; i++) + if (strcmp (d[i], d[i+1]) =3D=3D 0) + { + grub_util_error ("the drive %s is defined multiple times in the device = map %s", + d[i], dev_map); + } + + for (i =3D 0; i < filled; i++) + free (d[i]); + + free (d); +} + +static grub_err_t +write_to_disk (grub_device_t dev, const char *fn) +{ + char *core_img; + size_t core_size; + grub_err_t err; + + core_size =3D grub_util_get_image_size (fn); + + core_img =3D grub_util_read_image (fn); =20 + + err =3D grub_disk_write (dev->disk, 0, 0, + core_size, core_img); + free (core_img); + return err; +} + +static int +is_prep_partition (grub_device_t dev) +{ + if (!dev->disk) + return 0; + if (!dev->disk->partition) + return 0; + if (strcmp(dev->disk->partition->partmap->name, "msdos") =3D=3D 0) + return (dev->disk->partition->msdostype =3D=3D 0x41); + + if (strcmp (dev->disk->partition->partmap->name, "gpt") =3D=3D 0) + { + struct grub_gpt_partentry gptdata; + grub_partition_t p =3D dev->disk->partition; + int ret =3D 0; + dev->disk->partition =3D dev->disk->partition->parent; + + if (grub_disk_read (dev->disk, p->offset, p->index, + sizeof (gptdata), &gptdata) =3D=3D 0) + { + const grub_gpt_part_type_t template =3D { + grub_cpu_to_le32_compile_time (0x9e1a2d38), + grub_cpu_to_le16_compile_time (0xc612), + grub_cpu_to_le16_compile_time (0x4316), + { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b } + }; + + ret =3D grub_memcmp (&template, &gptdata.type, + sizeof (template)) =3D=3D 0; + } + dev->disk->partition =3D p; + return ret; + } + + return 0; +} + +static int +is_prep_empty (grub_device_t dev) +{ + grub_disk_addr_t dsize, addr; + grub_uint32_t buffer[32768]; + + dsize =3D grub_disk_get_size (dev->disk); + for (addr =3D 0; addr < dsize; + addr +=3D sizeof (buffer) / GRUB_DISK_SECTOR_SIZE) + { + grub_size_t sz =3D sizeof (buffer); + grub_uint32_t *ptr; + + if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr) + sz =3D (dsize - addr) * GRUB_DISK_SECTOR_SIZE; + grub_disk_read (dev->disk, addr, 0, sz, buffer); + + if (addr =3D=3D 0 && grub_memcmp (buffer, ELFMAG, SELFMAG) =3D=3D = 0) + return 1; + + for (ptr =3D buffer; ptr < buffer + sz / sizeof (*buffer); ptr++) + if (*ptr) + return 0; + } + + return 1; +} + +static void +remove_old_efi_entries (const char *efi_distributor) +{ + int fd; + pid_t pid =3D grub_util_exec_pipe ((char * []){ (char *) "efibootmgr",= NULL }, &fd); + char *line =3D NULL; + size_t len =3D 0; + + if (!pid) + { + grub_util_warn (_("Unable to open stream from %s: %s"), + "efibootmgr", strerror (errno)); + return; + } + + FILE *fp =3D fdopen (fd, "r"); + if (!fp) + { + grub_util_warn (_("Unable to open stream from %s: %s"), + "efibootmgr", strerror (errno)); + return; + } + + line =3D xmalloc (80); + len =3D 80; + while (1) + { + int ret; + char *bootnum; + ret =3D getline (&line, &len, fp); + if (ret =3D=3D -1) + break; + if (grub_memcmp (line, "Boot", sizeof ("Boot") - 1) !=3D 0 + || line[sizeof ("Boot") - 1] < '0' + || line[sizeof ("Boot") - 1] > '9') + continue; + if (!strcasestr (line, efi_distributor)) + continue; + bootnum =3D line + sizeof ("Boot") - 1; + bootnum[4] =3D '\0'; + if (efi_quiet) + grub_util_exec ((char * []){ (char *) "efibootmgr", (char *) "--quiet",= + (char *) "-b", bootnum, (char *) "-B", NULL }); + else + grub_util_exec ((char * []){ (char *) "efibootmgr", + (char *) "-b", bootnum, (char *) "-B", NULL }); + } + + free (line); +} + +static char * +get_ofpathname (const char *dev) +{ + char *ret =3D xmalloc (2 * PATH_MAX); + char *end =3D ret + 2 * PATH_MAX - 1; + int fd; + pid_t pid; + char *ptr =3D ret; + + pid =3D grub_util_exec_pipe ((char * []){ (char *) "ofpathname", + (char *) dev, NULL }, &fd); + if (!pid) + goto fail; + + FILE *fp =3D fdopen (fd, "r"); + if (!fp) + goto fail; + + while (!feof (fp) && ptr < end) + { + size_t r; + r =3D fread (ptr, 1, end - ptr, fp); + ptr +=3D r; + } + + fclose (fp); + + return ret; + + fail: + grub_util_error (_("couldn't find IEEE1275 device tree path for %s.\nY= ou will have to set `boot-device' variable manually"), + dev); +} + +int +main (int argc, char *argv[]) +{ + int is_efi =3D 0; + const char *efi_distributor; + const char *efi_file =3D NULL; + char **grub_devices; + grub_fs_t grub_fs; + grub_device_t grub_dev =3D NULL; + enum grub_install_plat platform; + char *grubdir, *device_map; + char **curdev, **curdrive; + char **grub_drives; + char *relative_grubdir; + char **efidir_device_names; + grub_device_t efidir_grub_dev; + char *efidir_grub_devname; + + set_program_name (argv[0]); + + grub_util_init_nls (); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + grub_install_args_finish (); + + if (verbosity > 1) + grub_env_set ("debug", "all"); + + load_config (); + + if (!bootloader_id && grub_distributor) + { + char *ptr; + bootloader_id =3D xstrdup (grub_distributor); + for (ptr =3D bootloader_id; *ptr && *ptr !=3D ' '; ptr++) + if (*ptr >=3D 'A' && *ptr <=3D 'Z') + *ptr =3D *ptr - 'A' + 'a'; + *ptr =3D '\0'; + } + if (!bootloader_id || bootloader_id[0] =3D=3D '\0') + { + free (bootloader_id); + bootloader_id =3D xstrdup ("grub"); + } + + if (!grub_install_source_directory) + { + if (!target) + { + const char * t; + t =3D get_default_platform (); + if (!t) + grub_util_error ("%s",=20 + _("Unable to determine your platform." + " Use --target.") + ); + target =3D xstrdup (t);=20 + } + grub_install_source_directory + =3D grub_install_concat (3, GRUB_LIBDIR, PACKAGE, target); + } + + platform =3D grub_install_get_target (grub_install_source_directory); + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + if (!disk_module) + disk_module =3D xstrdup ("biosdisk"); + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + break; + + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + disk_module =3D xstrdup ("native"); + break; + } + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + if (!install_device) + grub_util_error ("%s", _("install device isn't specified")); + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + free (install_device); + install_device =3D NULL; + break; + } + + if (!bootdir) + bootdir =3D grub_install_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME= ); + + { + char * t =3D grub_install_concat (2, bootdir, GRUB_DIR_NAME); + grub_install_mkdir_p (t); + grubdir =3D canonicalize_file_name (t); + if (!grubdir) + grub_util_error (_("failed to get canonical path of `%s'"), t); + free (t); + } + device_map =3D grub_install_concat (2, grubdir, "device.map"); + + if (recheck) + unlink (device_map); + + + device_map_check_duplicates (device_map); + grub_util_biosdisk_init (device_map); + + /* Initialize all modules. */ + grub_init_all (); + grub_gcry_init_all (); + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + is_efi =3D 1; + break; + default: + is_efi =3D 0; + break; + } + + /* Find the EFI System Partition. */ + + if (is_efi) + { + grub_fs_t fs; + free (install_device); + install_device =3D NULL; + if (!efidir) + { + char *d =3D grub_install_concat (2, bootdir, "efi"); + char *dr =3D NULL; + if (!is_directory (d)) + { + free (d); + d =3D grub_install_concat (2, bootdir, "EFI"); + } + /* + The EFI System Partition may have been given directly using + --root-directory. + */ + if (!is_directory (d) + && rootdir && grub_strcmp (rootdir, "/") !=3D 0) + { + free (d); + d =3D xstrdup (rootdir); + } + if (is_directory (d)) + dr =3D grub_make_system_path_relative_to_its_root (d); + /* Is it a mount point? */ + if (dr && dr[0] =3D=3D '\0') + efidir =3D d; + else + free (d); + free (dr); + } + if (!efidir) + grub_util_error ("%s", _("cannot find EFI directory")); + efidir_device_names =3D grub_guess_root_devices (efidir); + if (!efidir_device_names || !efidir_device_names[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), + efidir); + install_device =3D efidir_device_names[0]; + + for (curdev =3D efidir_device_names; *curdev; curdev++) + grub_util_pull_device (*curdev); + =20 + efidir_grub_devname =3D grub_util_get_grub_dev (efidir_device_name= s[0]); + if (!efidir_grub_devname) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device= =2Emap"), + efidir_device_names[0]); + + efidir_grub_dev =3D grub_device_open (efidir_grub_devname); + if (! efidir_grub_dev) + grub_util_error ("%s", grub_errmsg); + + fs =3D grub_fs_probe (efidir_grub_dev); + if (! fs) + grub_util_error ("%s", grub_errmsg); + + if (grub_strcmp (fs->name, "fat") !=3D 0) + grub_util_error (_("%s doesn't look like an EFI partition.\n"), efidir)= ; + + /* The EFI specification requires that an EFI System Partition mus= t + contain an "EFI" subdirectory, and that OS loaders are stored in + subdirectories below EFI. Vendors are expected to pick names that do + not collide with other vendors. To minimise collisions, we use the + name of our distributor if possible. + */ + char *t; + efi_distributor =3D bootloader_id; + if (removable) + { + /* The specification makes stricter requirements of removable + devices, in order that only one image can be automatically loaded + from them. The image must always reside under /EFI/BOOT, and it + must have a specific file name depending on the architecture. + */ + efi_distributor =3D "BOOT"; + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + efi_file =3D "BOOTIA32.EFI"; + break; + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + efi_file =3D "BOOTX64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_IA64_EFI: + efi_file =3D "BOOTIA64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + efi_file =3D "BOOTARM.EFI"; + break; + default: + grub_util_error ("%s", _("You've found a bug")); + break; + } + } + else + { + /* It is convenient for each architecture to have a different + efi_file, so that different versions can be installed in parallel.= + */ + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + efi_file =3D "grubia32.efi"; + break; + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + efi_file =3D "grubx64.efi"; + break; + case GRUB_INSTALL_PLATFORM_IA64_EFI: + efi_file =3D "grubia64.efi"; + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + efi_file =3D "grubarm.efi"; + break; + default: + efi_file =3D "grub.efi"; + break; + } + } + t =3D grub_install_concat (3, efidir, "EFI", efi_distributor); + free (efidir); + efidir =3D t; + grub_install_mkdir_p (efidir); + } + + grub_install_copy_files (grub_install_source_directory, + grubdir, platform); + + char *envfile =3D grub_install_concat (2, grubdir, "grubenv"); + if (!grub_install_is_regular_file (envfile)) + grub_install_create_envblk_file (envfile); + + size_t ndev =3D 0; + + /* Write device to a variable so we don't have to traverse /dev every = time. */ + grub_devices =3D grub_guess_root_devices (grubdir); + if (!grub_devices || !grub_devices[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)")= , + grubdir); + + for (curdev =3D grub_devices; *curdev; curdev++) + { + grub_util_pull_device (*curdev); + ndev++; + } + + grub_drives =3D xmalloc (sizeof (grub_drives[0]) * (ndev + 1));=20 + + for (curdev =3D grub_devices, curdrive =3D grub_drives; *curdev; curde= v++, + curdrive++) + { + *curdrive =3D grub_util_get_grub_dev (*curdev); + if (! *curdrive) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device= =2Emap"), + *curdev); + } + *curdrive =3D 0; + + grub_dev =3D grub_device_open (grub_drives[0]); + if (! grub_dev) + grub_util_error ("%s", grub_errmsg); + + grub_fs =3D grub_fs_probe (grub_dev); + if (! grub_fs) + grub_util_error ("%s", grub_errmsg); + + grub_install_push_module (grub_fs->name); + + if (grub_dev->disk) + probe_mods (grub_dev->disk); + + for (curdrive =3D grub_drives + 1; *curdrive; curdrive++) + { + grub_device_t dev =3D grub_device_open (*curdrive); + if (!dev) + continue; + if (dev->disk) + probe_mods (dev->disk); + grub_device_close (dev); + } + + if (!is_cryptodisk_enabled && have_cryptodisk) + grub_util_error (_("attempt to install to cryptodisk without cryptod= isk enabled. " + "Set `%s' in file `%s'."), "GRUB_ENABLE_CRYPTODISK=3D1", GRUB_S= YSCONFDIR "/default/grub"); + + if (disk_module && grub_strcmp (disk_module, "ata") =3D=3D 0) + grub_install_push_module ("pata"); + else if (disk_module && grub_strcmp (disk_module, "native") =3D=3D 0) + { + grub_install_push_module ("pata"); + grub_install_push_module ("ahci"); + grub_install_push_module ("ohci"); + grub_install_push_module ("uhci"); + grub_install_push_module ("usbms"); + } + else if (disk_module && disk_module[0]) + grub_install_push_module (disk_module); + + relative_grubdir =3D grub_make_system_path_relative_to_its_root (grubd= ir); + if (relative_grubdir[0] =3D=3D '\0') + { + free (relative_grubdir); + relative_grubdir =3D xstrdup ("/"); + } + + char *platname =3D grub_install_get_platform_name (platform); + char *platdir; + { + char *t =3D grub_install_concat (2, grubdir, + platname); + platdir =3D canonicalize_file_name (t); + if (!platdir) + grub_util_error (_("failed to get canonical path of `%s'"), + t); + free (t); + } + load_cfg =3D grub_install_concat (2, platdir, + "load.cfg"); + + unlink (load_cfg); + + if (debug_image && debug_image[0]) + { + load_cfg_f =3D fopen (load_cfg, "wb"); + have_load_cfg =3D 1; + fprintf (load_cfg_f, "set debug=3D'%s'\n", + debug_image); + } + char *prefix_drive =3D NULL; + char *install_drive =3D NULL; + + if (install_device) + { + if (install_device[0] =3D=3D '(' + && install_device[grub_strlen (install_device) - 1] =3D=3D ')') + install_drive =3D xstrdup (install_device); + else + { + grub_util_pull_device (install_device); + install_drive =3D grub_util_get_grub_dev (install_device); + if (!install_drive) + grub_util_error (_("cannot find a GRUB drive for %s. Check your de= vice.map"), + install_device); + } + } + + if (!have_abstractions) + { + if ((disk_module && grub_strcmp (disk_module, "biosdisk") !=3D 0) + || grub_drives[1] + || (!install_drive + && platform !=3D GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) + || (install_drive && !is_same_disk (grub_drives[0], install_drive)) + || !have_bootdev (platform)) + { + char *uuid =3D NULL; + /* generic method (used on coreboot and ata mod). */ + if (!force_file_id && grub_fs->uuid && grub_fs->uuid (grub_dev, + &uuid)) + { + grub_print_error (); + grub_errno =3D 0; + uuid =3D NULL; + } + + if (!load_cfg_f) + load_cfg_f =3D fopen (load_cfg, "wb"); + have_load_cfg =3D 1; + if (uuid) + { + fprintf (load_cfg_f, "search.fs_uuid %s root ", + uuid); + grub_install_push_module ("search_fs_uuid"); + } + else + { + char *rndstr =3D get_rndstr (); + char *fl =3D grub_install_concat (3, grubdir, + "uuid", rndstr); + char *fldir =3D grub_install_concat (2, grubdir, + "uuid"); + char *relfl; + FILE *flf; + grub_install_mkdir_p (fldir); + flf =3D fopen (fl, "w"); + if (!flf) + grub_util_error ("Can't create file: %s", strerror (errno)); + fclose (flf); + relfl =3D grub_make_system_path_relative_to_its_root (fl); + fprintf (load_cfg_f, "search.file %s root ", + relfl); + grub_install_push_module ("search_fs_file"); + } + if (disk_module && disk_module[0] && grub_strcmp (disk_module, "biosd= isk") !=3D 0) + { + /* FIXME: hints=3D"`echo "${grub_device}" | xargs "$grub_probe" -= -device-map=3D"${device_map}" --target=3Dbaremetal_hints --device`" + */ + } + else + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + /* FIXME: hints=3D"`echo "${grub_device}" | xargs "$grub_probe" --devi= ce-map=3D"${device_map}" --target=3Dbios_hints --device`"*/ + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + /* FIXME: hints=3D"`echo "${grub_device}" | xargs "$grub_p= robe" --device-map=3D"${device_map}" --target=3Defi_hints --device`"*/ + break; + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + /* FIXME: hints=3D"`echo "${grub_device}" | xargs "$grub_p= robe" --device-map=3D"${device_map}" --target=3Dieee1275_hints --device`"= */ + break; + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + /* FIXME: hints=3D"`echo "${grub_device}" | xargs "$grub_p= robe" --device-map=3D"${device_map}" --target=3Dbaremetal_hints --device`= "*(*/ + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + grub_util_warn ("%s", _("no hints available for your platform. Expect = reduced performance")); + break; + } + fprintf (load_cfg_f, "\n"); + char *escaped_relpath =3D escape (relative_grubdir); + fprintf (load_cfg_f, "set prefix=3D($root)'%s'\n", + escaped_relpath); + } + else + { + /* We need to hardcode the partition number in the core image's prefi= x. */ + char *p; + for (p =3D grub_drives[0]; *p; ) + { + if (*p =3D=3D '\\' && p[1]) + { + p +=3D 2; + continue; + } + if (*p =3D=3D ',' || *p =3D=3D '\0') + break; + p++; + } + prefix_drive =3D xasprintf ("(%s)", p); + } + } + else + { + if (is_cryptodisk_enabled) + { + if (grub_dev->disk) + probe_cryptodisk_uuid (grub_dev->disk); + + for (curdrive =3D grub_drives + 1; *curdrive; curdrive++) + { + grub_device_t dev =3D grub_device_open (*curdrive); + if (!dev) + continue; + if (dev->disk) + probe_cryptodisk_uuid (dev->disk); + grub_device_close (dev); + } + } + prefix_drive =3D xasprintf ("(%s)", grub_drives[0]); + } + + char mkimage_target[200]; + const char *core_name =3D NULL; + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + core_name =3D "core.efi"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + core_name =3D "core.elf"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s-elf", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + core_name =3D "core.elf"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + + + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + core_name =3D "core.img"; + break; + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + strcpy (mkimage_target, "sparc64-ieee1275-raw"); + core_name =3D "core.img"; + break; + } + + if (!core_name) + grub_util_error ("%s", _("You've found a bug")); + + if (load_cfg_f) + fclose (load_cfg_f); + + char *imgfile =3D grub_install_concat (2, platdir, + core_name); + char *prefix =3D xasprintf ("%s%s", prefix_drive ? : "", + relative_grubdir); + grub_install_make_image_wrap (/* source dir */ grub_install_source_di= rectory, + /*prefix */ prefix, + /* output */ imgfile, + /* memdisk */ NULL, + have_load_cfg ? load_cfg : NULL, + /* image target */ mkimage_target, + 0, GRUB_COMPRESSION_AUTO); + /* Backward-compatibility kludges. */ + switch (platform) + { + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + { + char *dst =3D grub_install_concat (2, bootdir, "grub.elf"); + grub_install_copy_file (imgfile, dst); + free (dst); + } + break; + + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + { + char *dst =3D grub_install_concat (2, grubdir, "grub"); + grub_install_copy_file (imgfile, dst); + free (dst); + } + break; + + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + { + char *dst =3D grub_install_concat (2, platdir, "grub.efi"); + grub_install_make_image_wrap (/* source dir */ grub_install_source_dir= ectory, + /* prefix */ "", + /* output */ dst, + /* memdisk */ NULL, + have_load_cfg ? load_cfg : NULL, + /* image target */ mkimage_target, + 0, GRUB_COMPRESSION_AUTO); + } + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + break; + } + + /* Perform the platform-dependent install */ + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + { + char *boot_img_src =3D grub_install_concat (2,=20 + grub_install_source_directory, + "boot.img"); + char *boot_img =3D grub_install_concat (2, platdir, + "boot.img"); + grub_install_copy_file (boot_img_src, boot_img); + + grub_util_info ("grub_bios_setup %s %s %s --directory=3D'%s' --device-m= ap=3D'%s' '%s'", + allow_floppy ? "--allow-floppy " : "", + verbosity ? "--verbose " : "", + force ? "--force " : "", + platdir, + device_map, + install_device); + =09 + /* Now perform the installation. */ + grub_bios_setup (platdir, NULL, NULL, + install_drive, force, + 1, allow_floppy); + break; + } + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + { + char *boot_img_src =3D grub_install_concat (2,=20 + grub_install_source_directory, + "boot.img"); + char *boot_img =3D grub_install_concat (2, platdir, + "boot.img"); + grub_install_copy_file (boot_img_src, boot_img); + + grub_util_info ("grub_sparc_setup %s %s %s --directory=3D'%s' --device-= map=3D'%s' '%s'", + allow_floppy ? "--allow-floppy " : "", + verbosity ? "--verbose " : "", + force ? "--force " : "", + platdir, + device_map, + install_drive); + =09 + /* Now perform the installation. */ + grub_sparc_setup (platdir, NULL, NULL, + install_device, force, + 1, allow_floppy); + break; + } + + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + /* If a install device is defined, copy the core.elf to PReP parti= tion. */ + if (install_device && install_device[0]) + { + grub_device_t ins_dev; + ins_dev =3D grub_device_open (install_drive); + if (!ins_dev || !is_prep_partition (ins_dev)) + { + grub_util_error ("%s", _("the chosen partition is not a PReP part= ition")); + } + if (is_prep_empty (ins_dev)) + { + if (write_to_disk (ins_dev, imgfile)) + grub_util_error ("%s", _("failed to copy Grub to the PReP partition"))= ; + } + else + { + char *s =3D xasprintf ("dd if=3D/dev/zero of=3D%s", install_devic= e); + grub_util_error ("the PReP partition is not empty. If you are sur= e you want to use it, run dd to clear it: `%s'", + s); + } + grub_device_close (ins_dev); + } + /* fallthrough. */ + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + if (update_nvram) + { + char *boot_device; + + if (grub_util_exec_redirect_null ((char * []){ (char *) "ofpathname",= (char *) "--version", NULL })) + { + /* TRANSLATORS: This message is shown when required executable `%= s' + isn't found. */ + grub_util_error (_("%s: not found"), "ofpathname"); + } + + /* Get the Open Firmware device tree path translation. */ + if (platform !=3D GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275 || !install_= device + || install_device[0] =3D=3D '\0') + { + char *relpath =3D grub_make_system_path_relative_to_its_root (img= file); + char *ptr; + char *dev =3D grub_util_get_os_disk (grub_devices[0]); + char *ofpath; + int partno =3D grub_dev->disk->partition ? grub_dev->disk->partit= ion->number + 1 : 0; + + for (ptr =3D relpath; *ptr; ptr++) + if (*ptr =3D=3D '/') + *ptr =3D '\\'; + ofpath =3D get_ofpathname (dev); + boot_device =3D xasprintf ("%s:%d,%s", + ofpath, partno, relpath); + } + else + { + char *dev =3D grub_util_get_os_disk (install_device); + boot_device =3D get_ofpathname (dev); + } + if (grub_util_exec ((char * []){ (char *) "nvsetenv", (char *) "boot-= device", + boot_device, NULL })) + { + char *cmd =3D xasprintf ("setenv boot-device %s", boot_device); + grub_util_error ("`nvsetenv' failed. \nYou will have to set `boot= -device' variable manually. At the IEEE1275 prompt, type:\n %s\n",=20 + cmd); + } + } + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + grub_util_exec ((char * []){ (char *) "dvhtool", (char *) "-d", + install_device, (char *) "--unix-to-vh",=20 + imgfile, + (char *) "grub", NULL }); + grub_util_warn ("%s", _("You will have to set `SystemPartition' an= d `OSLoader' manually.")); + + break; + + case GRUB_INSTALL_PLATFORM_I386_EFI: + { + char *dst =3D grub_install_concat (2, efidir, "grub.efi"); + /* For old macs. Suggested by Peter Jones. */ + grub_install_copy_file (imgfile, dst); + free (dst); + } + + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + { + char *dst =3D grub_install_concat (2, efidir, efi_file); + grub_install_copy_file (imgfile, dst); + free (dst); + } + if (!removable) + { + /* Try to make this image bootable using the EFI Boot Manager, if ava= ilable. */ + + if (grub_util_exec_redirect_null ((char * []){ (char *) "efibootmgr",= (char *) "--version", NULL })) + { + /* TRANSLATORS: This message is shown when required executable `%= s' + isn't found. */ + grub_util_error (_("%s: not found"), "efibootmgr"); + } + if (!efi_distributor || efi_distributor[0] =3D=3D '\0') + grub_util_error ("%s", "EFI distributor id isn't specified."); + + /* On Linux, we need the efivars kernel modules. */ +#ifdef __linux__ + grub_util_exec ((char * []){ (char *) "modprobe", (char *) "-q", + (char *) "efivars", NULL }); +#endif + /* Delete old entries from the same distributor. */ + remove_old_efi_entries (efi_distributor); + + char * efidir_disk =3D grub_util_get_os_disk (efidir_device_names[0])= ; + int efidir_part =3D efidir_grub_dev->disk->partition ? efidir_grub_de= v->disk->partition->number + 1 : 1; + char * efifile_path =3D xasprintf ("\\EFI\\%s\\%s", + efi_distributor, + efi_file); + char *efidir_part_str =3D xasprintf ("%d", efidir_part); + + grub_util_exec ((char * []){ (char *) "efibootmgr", (char *) "--quiet= ", + (char *) "-c", (char *) "-d", efidir_disk, + (char *) "-p", efidir_part_str, (char *) "-w", + (char *) "-L", bootloader_id, (char *) "-l",=20 + efifile_path, NULL }); + free (efidir_part_str); + } + break; + + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + grub_util_warn ("%s", + _("WARNING: no platform-specific install was performed")); + break; + } + + fprintf (stderr, "%s\n", _("Installation finished. No error reported."= )); + + /* Free resources. */ + grub_gcry_fini_all (); + grub_fini_all (); + + return 0; +} =3D=3D=3D modified file 'util/grub-mkimage.c' --- util/grub-mkimage.c 2013-08-23 07:01:11 +0000 +++ util/grub-mkimage.c 2013-10-04 00:39:55 +0000 @@ -43,1786 +43,14 @@ #include #include #include +#include +#include =20 #define _GNU_SOURCE 1 #include =20 #include "progname.h" =20 -#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) - -#ifdef HAVE_LIBLZMA -#include -#endif - -#define TARGET_NO_FIELD 0xffffffff - -typedef enum { - COMPRESSION_AUTO, COMPRESSION_NONE, COMPRESSION_XZ, COMPRESSION_LZMA -} grub_compression_t; - -struct image_target_desc -{ - const char *dirname; - const char *names[6]; - grub_size_t voidp_sizeof; - int bigendian; - enum { - IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, - IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_SPARC64_CDCORE, - IMAGE_I386_IEEE1275, - IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, - IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, - IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT - } id; - enum - { - PLATFORM_FLAGS_NONE =3D 0, - PLATFORM_FLAGS_DECOMPRESSORS =3D 2, - PLATFORM_FLAGS_MODULES_BEFORE_KERNEL =3D 4, - } flags; - unsigned total_module_size; - unsigned decompressor_compressed_size; - unsigned decompressor_uncompressed_size; - unsigned decompressor_uncompressed_addr; - unsigned link_align; - grub_uint16_t elf_target; - unsigned section_align; - signed vaddr_offset; - grub_uint64_t link_addr; - unsigned mod_gap, mod_align; - grub_compression_t default_compression; - grub_uint16_t pe_target; -}; - -#define EFI32_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) - -#define EFI64_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) - -struct image_target_desc image_targets[] =3D - { - { - .dirname =3D "i386-coreboot", - .names =3D { "i386-coreboot", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_COREBOOT, - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, - .elf_target =3D EM_386, - .link_align =3D 4, - .mod_gap =3D GRUB_KERNEL_I386_COREBOOT_MOD_GAP, - .mod_align =3D GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN - }, - { - .dirname =3D "i386-multiboot", - .names =3D { "i386-multiboot", NULL}, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_COREBOOT, - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, - .elf_target =3D EM_386, - .link_align =3D 4, - .mod_gap =3D GRUB_KERNEL_I386_COREBOOT_MOD_GAP, - .mod_align =3D GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN - }, - { - .dirname =3D "i386-pc", - .names =3D { "i386-pc", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_I386_PC,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_I386_PC_COMPRE= SSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_I386_PC_UNCO= MPRESSED_SIZE, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_I386_PC_LINK_ADDR, - .default_compression =3D COMPRESSION_LZMA - }, - { - .dirname =3D "i386-pc", - .names =3D { "i386-pc-pxe", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_I386_PC_PXE,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_I386_PC_COMPRE= SSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_I386_PC_UNCO= MPRESSED_SIZE, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_I386_PC_LINK_ADDR, - .default_compression =3D COMPRESSION_LZMA - }, - { - .dirname =3D "i386-efi", - .names =3D { "i386-efi", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_EFI, - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset =3D EFI32_HEADER_SIZE, - .pe_target =3D GRUB_PE32_MACHINE_I386, - .elf_target =3D EM_386, - }, - { - .dirname =3D "i386-ieee1275", - .names =3D { "i386-ieee1275", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_I386_IEEE1275,=20 - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_I386_IEEE1275_LINK_ADDR, - .elf_target =3D EM_386, - .mod_gap =3D GRUB_KERNEL_I386_IEEE1275_MOD_GAP, - .mod_align =3D GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN, - .link_align =3D 4, - }, - { - .dirname =3D "i386-qemu", - .names =3D { "i386-qemu", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_QEMU,=20 - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_I386_QEMU_LINK_ADDR - }, - { - .dirname =3D "x86_64-efi", - .names =3D { "x86_64-efi", NULL }, - .voidp_sizeof =3D 8, - .bigendian =3D 0,=20 - .id =3D IMAGE_EFI,=20 - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset =3D EFI64_HEADER_SIZE, - .pe_target =3D GRUB_PE32_MACHINE_X86_64, - .elf_target =3D EM_X86_64, - }, - { - .dirname =3D "mipsel-loongson", - .names =3D { "mipsel-yeeloong-flash", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_YEELOONG_FLASH,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE= , - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, - .elf_target =3D EM_MIPS, - .link_align =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, - .default_compression =3D COMPRESSION_NONE - }, - { - .dirname =3D "mipsel-loongson", - .names =3D { "mipsel-fuloong2f-flash", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_FULOONG2F_FLASH,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE= , - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, - .elf_target =3D EM_MIPS, - .link_align =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, - .default_compression =3D COMPRESSION_NONE - }, - { - .dirname =3D "mipsel-loongson", - .names =3D { "mipsel-loongson-elf", "mipsel-yeeloong-elf", - "mipsel-fuloong2f-elf", "mipsel-fuloong2e-elf", - "mipsel-fuloong-elf", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_LOONGSON_ELF,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE= , - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, - .elf_target =3D EM_MIPS, - .link_align =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, - .default_compression =3D COMPRESSION_NONE - }, - { - .dirname =3D "powerpc-ieee1275", - .names =3D { "powerpc-ieee1275", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 1, - .id =3D IMAGE_PPC,=20 - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR, - .elf_target =3D EM_PPC, - .mod_gap =3D GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, - .mod_align =3D GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN, - .link_align =3D 4 - }, - { - .dirname =3D "sparc64-ieee1275", - .names =3D { "sparc64-ieee1275-raw", NULL }, - .voidp_sizeof =3D 8, - .bigendian =3D 1,=20 - .id =3D IMAGE_SPARC64_RAW, - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_S= IZE, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR - }, - { - .dirname =3D "sparc64-ieee1275", - .names =3D { "sparc64-ieee1275-cdcore", NULL }, - .voidp_sizeof =3D 8, - .bigendian =3D 1,=20 - .id =3D IMAGE_SPARC64_CDCORE, - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_S= IZE, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR - }, - { - .dirname =3D "sparc64-ieee1275", - .names =3D { "sparc64-ieee1275-aout", NULL }, - .voidp_sizeof =3D 8, - .bigendian =3D 1, - .id =3D IMAGE_SPARC64_AOUT, - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_S= IZE, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR - }, - { - .dirname =3D "ia64-efi", - .names =3D {"ia64-efi", NULL}, - .voidp_sizeof =3D 8, - .bigendian =3D 0,=20 - .id =3D IMAGE_EFI,=20 - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset =3D EFI64_HEADER_SIZE, - .pe_target =3D GRUB_PE32_MACHINE_IA64, - .elf_target =3D EM_IA_64, - }, - { - .dirname =3D "mips-arc", - .names =3D {"mips-arc", NULL}, - .voidp_sizeof =3D 4, - .bigendian =3D 1, - .id =3D IMAGE_MIPS_ARC,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_MIPS_ARC_LINK_ADDR, - .elf_target =3D EM_MIPS, - .link_align =3D GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, - .default_compression =3D COMPRESSION_NONE - }, - { - .dirname =3D "mipsel-arc", - .names =3D {"mipsel-arc", NULL}, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_MIPS_ARC,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR, - .elf_target =3D EM_MIPS, - .link_align =3D GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, - .default_compression =3D COMPRESSION_NONE - }, - { - .dirname =3D "mipsel-qemu_mips", - .names =3D { "mipsel-qemu_mips-elf", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_LOONGSON_ELF,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZ= E, - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, - .elf_target =3D EM_MIPS, - .link_align =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, - .default_compression =3D COMPRESSION_NONE - }, - { - .dirname =3D "mips-qemu_mips", - .names =3D { "mips-qemu_mips-flash", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 1, - .id =3D IMAGE_QEMU_MIPS_FLASH,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZ= E, - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, - .elf_target =3D EM_MIPS, - .link_align =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, - .default_compression =3D COMPRESSION_NONE - }, - { - .dirname =3D "mipsel-qemu_mips", - .names =3D { "mipsel-qemu_mips-flash", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_QEMU_MIPS_FLASH,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZ= E, - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, - .elf_target =3D EM_MIPS, - .link_align =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, - .default_compression =3D COMPRESSION_NONE - }, - { - .dirname =3D "mips-qemu_mips", - .names =3D { "mips-qemu_mips-elf", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 1, - .id =3D IMAGE_LOONGSON_ELF,=20 - .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, - .total_module_size =3D GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZ= E, - .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, - .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, - .section_align =3D 1, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, - .elf_target =3D EM_MIPS, - .link_align =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, - .default_compression =3D COMPRESSION_NONE - }, - { - .dirname =3D "arm-uboot", - .names =3D { "arm-uboot", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0, - .id =3D IMAGE_UBOOT,=20 - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN, - .vaddr_offset =3D 0, - .link_addr =3D GRUB_KERNEL_ARM_UBOOT_LINK_ADDR, - .elf_target =3D EM_ARM, - .mod_gap =3D GRUB_KERNEL_ARM_UBOOT_MOD_GAP, - .mod_align =3D GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN, - .link_align =3D 4 - }, - { - .dirname =3D "arm-efi", - .names =3D { "arm-efi", NULL }, - .voidp_sizeof =3D 4, - .bigendian =3D 0,=20 - .id =3D IMAGE_EFI,=20 - .flags =3D PLATFORM_FLAGS_NONE, - .total_module_size =3D TARGET_NO_FIELD, - .decompressor_compressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_size =3D TARGET_NO_FIELD, - .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, - .section_align =3D GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset =3D ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe32_optional_head= er) - + 4 * sizeof (struct grub_pe32_section_t= able), - GRUB_PE32_SECTION_ALIGNMENT), - .pe_target =3D GRUB_PE32_MACHINE_ARMTHUMB_MIXED, - .elf_target =3D EM_ARM, - }, - }; - -#define grub_target_to_host32(x) (grub_target_to_host32_real (image_targ= et, (x))) -#define grub_host_to_target32(x) (grub_host_to_target32_real (image_targ= et, (x))) -#define grub_target_to_host64(x) (grub_target_to_host64_real (image_targ= et, (x))) -#define grub_host_to_target64(x) (grub_host_to_target64_real (image_targ= et, (x))) -#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (imag= e_target, (x))) -#define grub_target_to_host16(x) (grub_target_to_host16_real (image_targ= et, (x))) -#define grub_host_to_target16(x) (grub_host_to_target16_real (image_targ= et, (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_uint64_t -grub_host_to_target64_real (struct image_target_desc *image_target, grub= _uint64_t in) -{ - if (image_target->bigendian) - return grub_cpu_to_be64 (in); - else - return grub_cpu_to_le64 (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); -} - -static inline grub_uint64_t -grub_host_to_target_addr_real (struct image_target_desc *image_target, g= rub_uint64_t in) -{ - if (image_target->voidp_sizeof =3D=3D 8) - return grub_host_to_target64_real (image_target, in); - else - return grub_host_to_target32_real (image_target, in); -} - -static inline grub_uint64_t -grub_target_to_host_real (struct image_target_desc *image_target, grub_u= int64_t in) -{ - if (image_target->voidp_sizeof =3D=3D 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 - -/* These structures are defined according to the CHRP binding to IEEE127= 5, - "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; -}; - -#define grub_target_to_host(val) grub_target_to_host_real(image_target, = (val)) - -#include - -static void *SzAlloc(void *p, size_t size) { p =3D p; return xmalloc(siz= e); } -static void SzFree(void *p, void *address) { p =3D p; free(address); } -static ISzAlloc g_Alloc =3D { SzAlloc, SzFree }; - -static void -compress_kernel_lzma (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) -{ - CLzmaEncProps props; - unsigned char out_props[5]; - size_t out_props_size =3D 5; - - LzmaEncProps_Init(&props); - props.dictSize =3D 1 << 16; - props.lc =3D 3; - props.lp =3D 0; - props.pb =3D 2; - props.numThreads =3D 1; - - *core_img =3D xmalloc (kernel_size); - - *core_size =3D kernel_size; - if (LzmaEncode ((unsigned char *) *core_img, core_size, - (unsigned char *) kernel_img, - kernel_size, - &props, out_props, &out_props_size, - 0, NULL, &g_Alloc, &g_Alloc) !=3D SZ_OK) - grub_util_error ("%s", _("cannot compress the kernel image")); -} - -#ifdef HAVE_LIBLZMA -static void -compress_kernel_xz (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) -{ - lzma_stream strm =3D LZMA_STREAM_INIT; - lzma_ret xzret; - lzma_options_lzma lzopts =3D { - .dict_size =3D 1 << 16, - .preset_dict =3D NULL, - .preset_dict_size =3D 0, - .lc =3D 3, - .lp =3D 0, - .pb =3D 2, - .mode =3D LZMA_MODE_NORMAL, - .nice_len =3D 64, - .mf =3D LZMA_MF_BT4, - .depth =3D 0, - }; - lzma_filter fltrs[] =3D { - { .id =3D LZMA_FILTER_LZMA2, .options =3D &lzopts}, - { .id =3D LZMA_VLI_UNKNOWN, .options =3D NULL} - }; - - xzret =3D lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE); - if (xzret !=3D LZMA_OK) - grub_util_error ("%s", _("cannot compress the kernel image")); - - *core_img =3D xmalloc (kernel_size); - - *core_size =3D kernel_size; - strm.next_in =3D (unsigned char *) kernel_img; - strm.avail_in =3D kernel_size; - strm.next_out =3D (unsigned char *) *core_img; - strm.avail_out =3D *core_size; - - while (1) - { - xzret =3D lzma_code (&strm, LZMA_FINISH); - if (xzret =3D=3D LZMA_OK) - continue; - if (xzret =3D=3D LZMA_STREAM_END) - break; - grub_util_error ("%s", _("cannot compress the kernel image")); - } - - *core_size -=3D strm.avail_out; -} -#endif - -static void -compress_kernel (struct image_target_desc *image_target, char *kernel_im= g, - size_t kernel_size, char **core_img, size_t *core_size, - grub_compression_t comp) -{ - if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS - && (comp =3D=3D COMPRESSION_LZMA)) - { - compress_kernel_lzma (kernel_img, kernel_size, core_img, - core_size); - return; - } - -#ifdef HAVE_LIBLZMA - if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS - && (comp =3D=3D COMPRESSION_XZ)) - { - compress_kernel_xz (kernel_img, kernel_size, core_img, - core_size); - return; - } -#endif - - if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS - && (comp !=3D COMPRESSION_NONE)) - grub_util_error (_("unknown compression %d\n"), comp); - - *core_img =3D xmalloc (kernel_size); - memcpy (*core_img, kernel_img, kernel_size); - *core_size =3D kernel_size; -} - -struct fixup_block_list -{ - struct fixup_block_list *next; - int state; - struct grub_pe32_fixup_block b; -}; - -#pragma GCC diagnostic ignored "-Wcast-align" - -#define MKIMAGE_ELF32 1 -#include "grub-mkimagexx.c" -#undef MKIMAGE_ELF32 - -#define MKIMAGE_ELF64 1 -#include "grub-mkimagexx.c" -#undef MKIMAGE_ELF64 - -static void -generate_image (const char *dir, const char *prefix, - FILE *out, const char *outname, char *mods[], - char *memdisk_path, char **pubkey_paths, size_t npubkeys, - char *config_path, struct image_target_desc *image_target, int note, - grub_compression_t comp) -{ - char *kernel_img, *core_img; - size_t kernel_size, total_module_size, core_size, exec_size; - size_t memdisk_size =3D 0, config_size =3D 0, config_size_pure =3D 0; - size_t prefix_size =3D 0; - char *kernel_path; - size_t offset; - struct grub_util_path_list *path_list, *p, *next; - grub_size_t bss_size; - grub_uint64_t start_address; - void *rel_section =3D 0; - grub_size_t reloc_size =3D 0, align; - size_t decompress_size =3D 0; - - if (comp =3D=3D COMPRESSION_AUTO) - comp =3D image_target->default_compression; - - if (image_target->id =3D=3D IMAGE_I386_PC - || image_target->id =3D=3D IMAGE_I386_PC_PXE) - comp =3D COMPRESSION_LZMA; - - path_list =3D grub_util_resolve_dependencies (dir, "moddep.lst", mods)= ; - - kernel_path =3D grub_util_get_path (dir, "kernel.img"); - - if (image_target->voidp_sizeof =3D=3D 8) - total_module_size =3D sizeof (struct grub_module_info64); - else - total_module_size =3D sizeof (struct grub_module_info32); - - { - size_t i; - for (i =3D 0; i < npubkeys; i++) - { - size_t curs; - curs =3D ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i])); - grub_util_info ("the size of public key %zd is 0x%llx", - i, (unsigned long long) curs); - total_module_size +=3D curs + sizeof (struct grub_module_header); - } - } - - if (memdisk_path) - { - memdisk_size =3D ALIGN_UP(grub_util_get_image_size (memdisk_path),= 512); - grub_util_info ("the size of memory disk is 0x%llx", - (unsigned long long) memdisk_size); - total_module_size +=3D memdisk_size + sizeof (struct grub_module_h= eader); - } - - if (config_path) - { - config_size_pure =3D grub_util_get_image_size (config_path) + 1; - config_size =3D ALIGN_ADDR (config_size_pure); - grub_util_info ("the size of config file is 0x%llx", - (unsigned long long) config_size); - total_module_size +=3D config_size + sizeof (struct grub_module_he= ader); - } - - if (prefix) - { - prefix_size =3D ALIGN_ADDR (strlen (prefix) + 1); - total_module_size +=3D prefix_size + sizeof (struct grub_module_he= ader); - } - - for (p =3D path_list; p; p =3D p->next) - total_module_size +=3D (ALIGN_ADDR (grub_util_get_image_size (p->nam= e)) - + sizeof (struct grub_module_header)); - - grub_util_info ("the total module size is 0x%llx", - (unsigned long long) total_module_size); - - if (image_target->voidp_sizeof =3D=3D 4) - kernel_img =3D load_image32 (kernel_path, &exec_size, &kernel_size, = &bss_size, - total_module_size, &start_address, &rel_section, - &reloc_size, &align, image_target); - else - kernel_img =3D load_image64 (kernel_path, &exec_size, &kernel_size, = &bss_size, - total_module_size, &start_address, &rel_section, - &reloc_size, &align, image_target); - - if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) - && (image_target->total_module_size !=3D TARGET_NO_FIELD)) - *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) - =3D grub_host_to_target32 (total_module_size); - - if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) - memmove (kernel_img + total_module_size, kernel_img, kernel_size); - - if (image_target->voidp_sizeof =3D=3D 8) - { - /* Fill in the grub_module_info structure. */ - struct grub_module_info64 *modinfo; - if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) - modinfo =3D (struct grub_module_info64 *) kernel_img; - else - modinfo =3D (struct grub_module_info64 *) (kernel_img + kernel_size); - memset (modinfo, 0, sizeof (struct grub_module_info64)); - modinfo->magic =3D grub_host_to_target32 (GRUB_MODULE_MAGIC); - modinfo->offset =3D grub_host_to_target_addr (sizeof (struct grub_= module_info64)); - modinfo->size =3D grub_host_to_target_addr (total_module_size); - if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) - offset =3D sizeof (struct grub_module_info64); - else - offset =3D kernel_size + sizeof (struct grub_module_info64); - } - else - { - /* Fill in the grub_module_info structure. */ - struct grub_module_info32 *modinfo; - if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) - modinfo =3D (struct grub_module_info32 *) kernel_img; - else - modinfo =3D (struct grub_module_info32 *) (kernel_img + kernel_size); - memset (modinfo, 0, sizeof (struct grub_module_info32)); - modinfo->magic =3D grub_host_to_target32 (GRUB_MODULE_MAGIC); - modinfo->offset =3D grub_host_to_target_addr (sizeof (struct grub_= module_info32)); - modinfo->size =3D grub_host_to_target_addr (total_module_size); - if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) - offset =3D sizeof (struct grub_module_info32); - else - offset =3D kernel_size + sizeof (struct grub_module_info32); - } - - for (p =3D path_list; p; p =3D p->next) - { - struct grub_module_header *header; - size_t mod_size, orig_size; - - orig_size =3D grub_util_get_image_size (p->name); - mod_size =3D ALIGN_ADDR (orig_size); - - header =3D (struct grub_module_header *) (kernel_img + offset); - memset (header, 0, sizeof (struct grub_module_header)); - header->type =3D grub_host_to_target32 (OBJ_TYPE_ELF); - header->size =3D grub_host_to_target32 (mod_size + sizeof (*header= )); - offset +=3D sizeof (*header); - memset (kernel_img + offset + orig_size, 0, mod_size - orig_size);= - - grub_util_load_image (p->name, kernel_img + offset); - offset +=3D mod_size; - } - - { - size_t i; - for (i =3D 0; i < npubkeys; i++) - { - size_t curs; - struct grub_module_header *header; - - curs =3D grub_util_get_image_size (pubkey_paths[i]); - - header =3D (struct grub_module_header *) (kernel_img + offset); - memset (header, 0, sizeof (struct grub_module_header)); - header->type =3D grub_host_to_target32 (OBJ_TYPE_PUBKEY); - header->size =3D grub_host_to_target32 (curs + sizeof (*header)); - offset +=3D sizeof (*header); - - grub_util_load_image (pubkey_paths[i], kernel_img + offset); - offset +=3D ALIGN_ADDR (curs); - } - } - - if (memdisk_path) - { - struct grub_module_header *header; - - header =3D (struct grub_module_header *) (kernel_img + offset); - memset (header, 0, sizeof (struct grub_module_header)); - header->type =3D grub_host_to_target32 (OBJ_TYPE_MEMDISK); - header->size =3D grub_host_to_target32 (memdisk_size + sizeof (*he= ader)); - offset +=3D sizeof (*header); - - grub_util_load_image (memdisk_path, kernel_img + offset); - offset +=3D memdisk_size; - } - - if (config_path) - { - struct grub_module_header *header; - - header =3D (struct grub_module_header *) (kernel_img + offset); - memset (header, 0, sizeof (struct grub_module_header)); - header->type =3D grub_host_to_target32 (OBJ_TYPE_CONFIG); - header->size =3D grub_host_to_target32 (config_size + sizeof (*hea= der)); - offset +=3D sizeof (*header); - - grub_util_load_image (config_path, kernel_img + offset); - *(kernel_img + offset + config_size_pure - 1) =3D 0; - offset +=3D config_size; - } - - if (prefix) - { - struct grub_module_header *header; - - header =3D (struct grub_module_header *) (kernel_img + offset); - memset (header, 0, sizeof (struct grub_module_header)); - header->type =3D grub_host_to_target32 (OBJ_TYPE_PREFIX); - header->size =3D grub_host_to_target32 (prefix_size + sizeof (*hea= der)); - offset +=3D sizeof (*header); - - grub_memset (kernel_img + offset, 0, prefix_size); - grub_strcpy (kernel_img + offset, prefix); - offset +=3D prefix_size; - } - - grub_util_info ("kernel_img=3D%p, kernel_size=3D0x%llx", kernel_img, - (unsigned long long) kernel_size); - compress_kernel (image_target, kernel_img, kernel_size + total_module_= size, - &core_img, &core_size, comp); - free (kernel_img); - - grub_util_info ("the core size is 0x%llx", (unsigned long long) core_s= ize); - - if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)=20 - && image_target->total_module_size !=3D TARGET_NO_FIELD) - *((grub_uint32_t *) (core_img + image_target->total_module_size)) - =3D grub_host_to_target32 (total_module_size); - - if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) - { - char *full_img; - size_t full_size; - char *decompress_path, *decompress_img; - const char *name; - - switch (comp) - { - case COMPRESSION_XZ: - name =3D "xz_decompress.img"; - break; - case COMPRESSION_LZMA: - name =3D "lzma_decompress.img"; - break; - case COMPRESSION_NONE: - name =3D "none_decompress.img"; - break; - default: - grub_util_error (_("unknown compression %d\n"), comp); - } - =20 - decompress_path =3D grub_util_get_path (dir, name); - decompress_size =3D grub_util_get_image_size (decompress_path); - decompress_img =3D grub_util_read_image (decompress_path); - - if ((image_target->id =3D=3D IMAGE_I386_PC - || image_target->id =3D=3D IMAGE_I386_PC_PXE) - && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200) - grub_util_error ("%s", _("Decompressor is too big")); - - if (image_target->decompressor_compressed_size !=3D TARGET_NO_FIEL= D) - *((grub_uint32_t *) (decompress_img - + image_target->decompressor_compressed_size)) - =3D grub_host_to_target32 (core_size); - - if (image_target->decompressor_uncompressed_size !=3D TARGET_NO_FI= ELD) - *((grub_uint32_t *) (decompress_img - + image_target->decompressor_uncompressed_size)) - =3D grub_host_to_target32 (kernel_size + total_module_size); - - if (image_target->decompressor_uncompressed_addr !=3D TARGET_NO_FI= ELD) - { - if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) - *((grub_uint32_t *) (decompress_img + image_target->decompressor_un= compressed_addr)) - =3D grub_host_to_target_addr (image_target->link_addr - total_mod= ule_size); - else - *((grub_uint32_t *) (decompress_img + image_target->decompressor_un= compressed_addr)) - =3D grub_host_to_target_addr (image_target->link_addr); - } - full_size =3D core_size + decompress_size; - - full_img =3D xmalloc (full_size); - memset (full_img, 0, full_size);=20 - - memcpy (full_img, decompress_img, decompress_size); - - memcpy (full_img + decompress_size, core_img, core_size); - - memset (full_img + decompress_size + core_size, 0, - full_size - (decompress_size + core_size)); - - free (core_img); - core_img =3D full_img; - core_size =3D full_size; - } - - switch (image_target->id) - { - case IMAGE_I386_PC: - case IMAGE_I386_PC_PXE: - if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000 - || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS)) - || (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x6800= 0)) - grub_util_error (_("core image is too big (0x%x > 0x%x)"), - GRUB_KERNEL_I386_PC_LINK_ADDR + (unsigned) core_size, - 0x78000); - /* fallthrough */ - case IMAGE_COREBOOT: - case IMAGE_QEMU: - if (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000) - grub_util_error (_("kernel image is too big (0x%x > 0x%x)"), - (unsigned) kernel_size + (unsigned) bss_size - + GRUB_KERNEL_I386_PC_LINK_ADDR, - 0x68000); - break; - case IMAGE_LOONGSON_ELF: - case IMAGE_YEELOONG_FLASH: - case IMAGE_FULOONG2F_FLASH: - case IMAGE_EFI: - case IMAGE_MIPS_ARC: - case IMAGE_QEMU_MIPS_FLASH: - break; - case IMAGE_SPARC64_AOUT: - case IMAGE_SPARC64_RAW: - case IMAGE_SPARC64_CDCORE: - case IMAGE_I386_IEEE1275: - case IMAGE_PPC: - case IMAGE_UBOOT: - break; - } - - switch (image_target->id) - { - case IMAGE_I386_PC: - case IMAGE_I386_PC_PXE: - { - unsigned num; - char *boot_path, *boot_img; - size_t boot_size; - - num =3D ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BI= TS); - if (image_target->id =3D=3D IMAGE_I386_PC_PXE) - { - char *pxeboot_path, *pxeboot_img; - size_t pxeboot_size; - grub_uint32_t *ptr; - =20 - pxeboot_path =3D grub_util_get_path (dir, "pxeboot.img"); - pxeboot_size =3D grub_util_get_image_size (pxeboot_path); - pxeboot_img =3D grub_util_read_image (pxeboot_path); - =20 - grub_util_write_image (pxeboot_img, pxeboot_size, out, - outname); - free (pxeboot_img); - free (pxeboot_path); - - /* Remove Multiboot header to avoid confusing ipxe. */ - for (ptr =3D (grub_uint32_t *) core_img; - ptr < (grub_uint32_t *) (core_img + MULTIBOOT_SEARCH); ptr++) - if (*ptr =3D=3D grub_host_to_target32 (MULTIBOOT_HEADER_MAGIC) - && grub_target_to_host32 (ptr[0]) - + grub_target_to_host32 (ptr[1]) - + grub_target_to_host32 (ptr[2]) =3D=3D 0) - { - *ptr =3D 0; - break; - } - } - - boot_path =3D grub_util_get_path (dir, "diskboot.img"); - boot_size =3D grub_util_get_image_size (boot_path); - if (boot_size !=3D GRUB_DISK_SECTOR_SIZE) - grub_util_error (_("diskboot.img size must be %u bytes"), - GRUB_DISK_SECTOR_SIZE); - - boot_img =3D grub_util_read_image (boot_path); - - { - struct grub_pc_bios_boot_blocklist *block; - block =3D (struct grub_pc_bios_boot_blocklist *) (boot_img - + GRUB_DISK_SECTOR_SIZE - - sizeof (*block)); - block->len =3D grub_host_to_target16 (num); - - /* This is filled elsewhere. Verify it just in case. */ - assert (block->segment - =3D=3D grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG - + (GRUB_DISK_SECTOR_SIZE >> 4))); - } - - grub_util_write_image (boot_img, boot_size, out, outname); - free (boot_img); - free (boot_path); - } - break; - case IMAGE_EFI: - { - 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; - struct grub_pe32_section_table *mods_section, *reloc_section; - static const grub_uint8_t stub[] =3D GRUB_PE32_MSDOS_STUB; - int header_size; - int reloc_addr; - - if (image_target->voidp_sizeof =3D=3D 4) - header_size =3D EFI32_HEADER_SIZE; - else - header_size =3D EFI64_HEADER_SIZE; - - reloc_addr =3D ALIGN_UP (header_size + core_size, - image_target->section_align); - - pe_size =3D ALIGN_UP (reloc_addr + reloc_size, - image_target->section_align); - pe_img =3D xmalloc (reloc_addr + reloc_size); - memset (pe_img, 0, header_size); - memcpy ((char *) pe_img + header_size, core_img, core_size); - memcpy ((char *) pe_img + reloc_addr, rel_section, reloc_size); - header =3D pe_img; - - /* The magic. */ - 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 =3D (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_S= IZE - + GRUB_PE32_SIGNATURE_SIZE); - c->machine =3D grub_host_to_target16 (image_target->pe_target); - - c->num_sections =3D grub_host_to_target16 (4); - c->time =3D grub_host_to_target32 (time (0)); - c->characteristics =3D grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAG= E - | GRUB_PE32_LINE_NUMS_STRIPPED - | ((image_target->voidp_sizeof =3D=3D 4) - ? GRUB_PE32_32BIT_MACHINE - : 0) - | GRUB_PE32_LOCAL_SYMS_STRIPPED - | GRUB_PE32_DEBUG_STRIPPED); - - /* The PE Optional header. */ - if (image_target->voidp_sizeof =3D=3D 4) - { - struct grub_pe32_optional_header *o; - - c->optional_header_size =3D grub_host_to_target16 (sizeof (struct g= rub_pe32_optional_header)); - - o =3D (struct grub_pe32_optional_header *) - (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header)); - o->magic =3D grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size =3D grub_host_to_target32 (exec_size); - o->data_size =3D grub_cpu_to_le32 (reloc_addr - exec_size - - header_size); - o->bss_size =3D grub_cpu_to_le32 (bss_size); - o->entry_addr =3D grub_cpu_to_le32 (start_address); - o->code_base =3D grub_cpu_to_le32 (header_size); - - o->data_base =3D grub_host_to_target32 (header_size + exec_size); - - o->image_base =3D 0; - o->section_alignment =3D grub_host_to_target32 (image_target->secti= on_align); - o->file_alignment =3D grub_host_to_target32 (image_target->section_= align); - o->image_size =3D grub_host_to_target32 (pe_size); - o->header_size =3D grub_host_to_target32 (header_size); - o->subsystem =3D grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APP= LICATION); - - /* Do these really matter? */ - o->stack_reserve_size =3D grub_host_to_target32 (0x10000); - o->stack_commit_size =3D grub_host_to_target32 (0x10000); - o->heap_reserve_size =3D grub_host_to_target32 (0x10000); - o->heap_commit_size =3D grub_host_to_target32 (0x10000); - =20 - o->num_data_directories =3D grub_host_to_target32 (GRUB_PE32_NUM_DA= TA_DIRECTORIES); - - o->base_relocation_table.rva =3D grub_host_to_target32 (reloc_addr)= ; - o->base_relocation_table.size =3D grub_host_to_target32 (reloc_size= ); - sections =3D o + 1; - } - else - { - struct grub_pe64_optional_header *o; - - c->optional_header_size =3D grub_host_to_target16 (sizeof (struct g= rub_pe64_optional_header)); - - o =3D (struct grub_pe64_optional_header *)=20 - (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header)); - o->magic =3D grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); - o->code_size =3D grub_host_to_target32 (exec_size); - o->data_size =3D grub_cpu_to_le32 (reloc_addr - exec_size - - header_size); - o->bss_size =3D grub_cpu_to_le32 (bss_size); - o->entry_addr =3D grub_cpu_to_le32 (start_address); - o->code_base =3D grub_cpu_to_le32 (header_size); - o->image_base =3D 0; - o->section_alignment =3D grub_host_to_target32 (image_target->secti= on_align); - o->file_alignment =3D grub_host_to_target32 (image_target->section_= align); - o->image_size =3D grub_host_to_target32 (pe_size); - o->header_size =3D grub_host_to_target32 (header_size); - o->subsystem =3D grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APP= LICATION); - - /* Do these really matter? */ - o->stack_reserve_size =3D grub_host_to_target64 (0x10000); - o->stack_commit_size =3D grub_host_to_target64 (0x10000); - o->heap_reserve_size =3D grub_host_to_target64 (0x10000); - o->heap_commit_size =3D grub_host_to_target64 (0x10000); - =20 - o->num_data_directories - =3D grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - - o->base_relocation_table.rva =3D grub_host_to_target32 (reloc_addr)= ; - o->base_relocation_table.size =3D grub_host_to_target32 (reloc_size= ); - sections =3D o + 1; - } - /* The sections. */ - text_section =3D sections; - strcpy (text_section->name, ".text"); - text_section->virtual_size =3D grub_cpu_to_le32 (exec_size); - text_section->virtual_address =3D grub_cpu_to_le32 (header_size); - text_section->raw_data_size =3D grub_cpu_to_le32 (exec_size); - text_section->raw_data_offset =3D grub_cpu_to_le32 (header_size); - text_section->characteristics =3D grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_C= ODE - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ); - - data_section =3D text_section + 1; - strcpy (data_section->name, ".data"); - data_section->virtual_size =3D grub_cpu_to_le32 (kernel_size - exec_siz= e); - data_section->virtual_address =3D grub_cpu_to_le32 (header_size + exec_= size); - data_section->raw_data_size =3D grub_cpu_to_le32 (kernel_size - exec_si= ze); - data_section->raw_data_offset =3D grub_cpu_to_le32 (header_size + exec_= size); - data_section->characteristics - =3D grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - -#if 0 - bss_section =3D data_section + 1; - strcpy (bss_section->name, ".bss"); - bss_section->virtual_size =3D grub_cpu_to_le32 (bss_size); - bss_section->virtual_address =3D grub_cpu_to_le32 (header_size + kernel= _size); - bss_section->raw_data_size =3D 0; - bss_section->raw_data_offset =3D 0; - bss_section->characteristics - =3D 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 - =20 - mods_section =3D data_section + 1; - strcpy (mods_section->name, "mods"); - mods_section->virtual_size =3D grub_cpu_to_le32 (reloc_addr - kernel_si= ze - header_size); - mods_section->virtual_address =3D grub_cpu_to_le32 (header_size + kerne= l_size + bss_size); - mods_section->raw_data_size =3D grub_cpu_to_le32 (reloc_addr - kernel_s= ize - header_size); - mods_section->raw_data_offset =3D grub_cpu_to_le32 (header_size + kerne= l_size); - mods_section->characteristics - =3D grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - - reloc_section =3D mods_section + 1; - strcpy (reloc_section->name, ".reloc"); - reloc_section->virtual_size =3D grub_cpu_to_le32 (reloc_size); - reloc_section->virtual_address =3D grub_cpu_to_le32 (reloc_addr + bss_s= ize); - reloc_section->raw_data_size =3D grub_cpu_to_le32 (reloc_size); - reloc_section->raw_data_offset =3D grub_cpu_to_le32 (reloc_addr); - reloc_section->characteristics - =3D 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 =3D pe_img; - core_size =3D pe_size; - } - break; - case IMAGE_QEMU: - { - char *rom_img; - size_t rom_size; - char *boot_path, *boot_img; - size_t boot_size; - - boot_path =3D grub_util_get_path (dir, "boot.img"); - boot_size =3D grub_util_get_image_size (boot_path); - boot_img =3D grub_util_read_image (boot_path); - - /* Rom sizes must be 64k-aligned. */ - rom_size =3D ALIGN_UP (core_size + boot_size, 64 * 1024); - - rom_img =3D xmalloc (rom_size); - memset (rom_img, 0, rom_size); - - *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) - =3D grub_host_to_target32 ((grub_uint32_t) -rom_size); - - memcpy (rom_img, core_img, core_size); - - *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR)) - =3D grub_host_to_target32 ((grub_uint32_t) -rom_size); - - memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); - - free (core_img); - core_img =3D rom_img; - core_size =3D rom_size; - - 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 =3D core_size + sizeof (*aout_head); - aout_img =3D xmalloc (aout_size); - aout_head =3D aout_img; - grub_memset (aout_head, 0, sizeof (*aout_head)); - aout_head->a_midmag =3D grub_host_to_target32 ((AOUT_MID_SUN << 16) - | AOUT32_OMAGIC); - aout_head->a_text =3D grub_host_to_target32 (core_size); - aout_head->a_entry - =3D grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS);= - memcpy ((char *) aout_img + sizeof (*aout_head), core_img, core_size); - - free (core_img); - core_img =3D aout_img; - core_size =3D aout_size; - } - break; - case IMAGE_SPARC64_RAW: - { - unsigned int num; - char *boot_path, *boot_img; - size_t boot_size; - - num =3D ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BI= TS); - num <<=3D GRUB_DISK_SECTOR_BITS; - - boot_path =3D grub_util_get_path (dir, "diskboot.img"); - boot_size =3D grub_util_get_image_size (boot_path); - if (boot_size !=3D GRUB_DISK_SECTOR_SIZE) - grub_util_error (_("diskboot.img size must be %u bytes"), - GRUB_DISK_SECTOR_SIZE); - - boot_img =3D grub_util_read_image (boot_path); - - *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8)) - =3D grub_host_to_target32 (num); - - grub_util_write_image (boot_img, boot_size, out, outname); - free (boot_img); - free (boot_path); - } - break; - case IMAGE_SPARC64_CDCORE: - break; - case IMAGE_YEELOONG_FLASH: - case IMAGE_FULOONG2F_FLASH: - { - char *rom_img; - size_t rom_size; - char *boot_path, *boot_img; - size_t boot_size; - grub_uint8_t context[GRUB_MD_SHA512->contextsize]; - /* fwstart.img is the only part which can't be tested by using *-e= lf - target. Check it against the checksum. */ - const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] =3D=20 - { - 0x5f, 0x67, 0x46, 0x57, 0x31, 0x30, 0xc5, 0x0a, - 0xe9, 0x98, 0x18, 0xc9, 0xf3, 0xca, 0x45, 0xa5, - 0x75, 0x64, 0x6b, 0xbb, 0x24, 0xcd, 0xb4, 0xbc, - 0xf2, 0x3e, 0x23, 0xf9, 0xc2, 0x6a, 0x8c, 0xde, - 0x3b, 0x94, 0x9c, 0xcc, 0xa5, 0xa7, 0x58, 0xb1, - 0xbe, 0x8b, 0x3d, 0x73, 0x98, 0x18, 0x7e, 0x68, - 0x5e, 0x5f, 0x23, 0x7d, 0x7a, 0xe8, 0x51, 0xf7, - 0x1a, 0xaf, 0x2f, 0x54, 0x11, 0x2e, 0x5c, 0x25 - }; - const grub_uint8_t fuloong2f_fwstart_good_hash[512 / 8] =3D=20 - {=20 - 0x76, 0x9b, 0xad, 0x6e, 0xa2, 0x39, 0x47, 0x62, - 0x1f, 0xc9, 0x3a, 0x6d, 0x05, 0x5c, 0x43, 0x5c, - 0x29, 0x4a, 0x7e, 0x08, 0x2a, 0x31, 0x8f, 0x5d, - 0x02, 0x84, 0xa0, 0x85, 0xf2, 0xd1, 0xb9, 0x53, - 0xa2, 0xbc, 0xf2, 0xe1, 0x39, 0x1e, 0x51, 0xb5, - 0xaf, 0xec, 0x9e, 0xf2, 0xf1, 0xf3, 0x0a, 0x2f, - 0xe6, 0xf1, 0x08, 0x89, 0xbe, 0xbc, 0x73, 0xab, - 0x46, 0x50, 0xd6, 0x21, 0xce, 0x8e, 0x24, 0xa7 - }; - const grub_uint8_t *fwstart_good_hash; - =20 - if (image_target->id =3D=3D IMAGE_FULOONG2F_FLASH) - { - fwstart_good_hash =3D fuloong2f_fwstart_good_hash; - boot_path =3D grub_util_get_path (dir, "fwstart_fuloong2f.img"); - } - else - { - fwstart_good_hash =3D yeeloong_fwstart_good_hash; - boot_path =3D grub_util_get_path (dir, "fwstart.img"); - } - - boot_size =3D grub_util_get_image_size (boot_path); - boot_img =3D grub_util_read_image (boot_path); - - grub_memset (context, 0, sizeof (context)); - GRUB_MD_SHA512->init (context); - GRUB_MD_SHA512->write (context, boot_img, boot_size); - GRUB_MD_SHA512->final (context); - if (grub_memcmp (GRUB_MD_SHA512->read (context), fwstart_good_hash= , - GRUB_MD_SHA512->mdlen) !=3D 0) - /* TRANSLATORS: fwstart.img may still be good, just it wasn't checked. = */ - grub_util_warn ("%s", - _("fwstart.img doesn't match the known good version. " - "proceed at your own risk")); - - if (core_size + boot_size > 512 * 1024) - grub_util_error ("%s", _("firmware image is too big")); - rom_size =3D 512 * 1024; - - rom_img =3D xmalloc (rom_size); - memset (rom_img, 0, rom_size);=20 - - memcpy (rom_img, boot_img, boot_size); - - memcpy (rom_img + boot_size, core_img, core_size); - - memset (rom_img + boot_size + core_size, 0, - rom_size - (boot_size + core_size)); - - free (core_img); - core_img =3D rom_img; - core_size =3D rom_size; - } - break; - case IMAGE_QEMU_MIPS_FLASH: - { - char *rom_img; - size_t rom_size; - - if (core_size > 512 * 1024) - grub_util_error ("%s", _("firmware image is too big")); - rom_size =3D 512 * 1024; - - rom_img =3D xmalloc (rom_size); - memset (rom_img, 0, rom_size);=20 - - memcpy (rom_img, core_img, core_size); - - memset (rom_img + core_size, 0, - rom_size - core_size); - - free (core_img); - core_img =3D rom_img; - core_size =3D rom_size; - } - break; - - case IMAGE_UBOOT: - { - struct grub_uboot_image_header *hdr; - GRUB_PROPERLY_ALIGNED_ARRAY (crc32_context, GRUB_MD_CRC32->context= size); - - hdr =3D xmalloc (core_size + sizeof (struct grub_uboot_image_heade= r)); - memcpy (hdr + 1, core_img, core_size); - - memset (hdr, 0, sizeof (*hdr)); - hdr->ih_magic =3D grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAG= IC); - hdr->ih_time =3D grub_cpu_to_be32 (time (0)); - hdr->ih_size =3D grub_cpu_to_be32 (core_size); - hdr->ih_load =3D grub_cpu_to_be32 (image_target->link_addr); - hdr->ih_ep =3D grub_cpu_to_be32 (image_target->link_addr); - hdr->ih_type =3D GRUB_UBOOT_IH_TYPE_KERNEL; - hdr->ih_os =3D GRUB_UBOOT_IH_OS_LINUX; - hdr->ih_arch =3D GRUB_UBOOT_IH_ARCH_ARM; - hdr->ih_comp =3D GRUB_UBOOT_IH_COMP_NONE; - - GRUB_MD_CRC32->init(crc32_context); - GRUB_MD_CRC32->write(crc32_context, hdr + 1, core_size); - GRUB_MD_CRC32->final(crc32_context); - hdr->ih_dcrc =3D grub_get_unaligned32 (GRUB_MD_CRC32->read (crc32_= context)); - - GRUB_MD_CRC32->init(crc32_context); - GRUB_MD_CRC32->write(crc32_context, hdr, sizeof (*hdr)); - GRUB_MD_CRC32->final(crc32_context); - hdr->ih_hcrc =3D grub_get_unaligned32 (GRUB_MD_CRC32->read (crc32_= context)); - - free (core_img); - core_img =3D (char *) hdr; - core_size +=3D sizeof (struct grub_uboot_image_header); - } - break; - - case IMAGE_MIPS_ARC: - { - char *ecoff_img; - struct ecoff_header { - grub_uint16_t magic; - grub_uint16_t nsec; - grub_uint32_t time; - grub_uint32_t syms; - grub_uint32_t nsyms; - grub_uint16_t opt; - grub_uint16_t flags; - grub_uint16_t magic2; - grub_uint16_t version; - grub_uint32_t textsize; - grub_uint32_t datasize; - grub_uint32_t bsssize; - grub_uint32_t entry; - grub_uint32_t text_start; - grub_uint32_t data_start; - grub_uint32_t bss_start; - grub_uint32_t gprmask; - grub_uint32_t cprmask[4]; - grub_uint32_t gp_value; - }; - struct ecoff_section - { - char name[8]; - grub_uint32_t paddr; - grub_uint32_t vaddr; - grub_uint32_t size; - grub_uint32_t file_offset; - grub_uint32_t reloc; - grub_uint32_t gp; - grub_uint16_t nreloc; - grub_uint16_t ngp; - grub_uint32_t flags; - }; - struct ecoff_header *head; - struct ecoff_section *section; - grub_uint32_t target_addr; - size_t program_size; - - program_size =3D ALIGN_ADDR (core_size); - if (comp =3D=3D COMPRESSION_NONE) - target_addr =3D (image_target->link_addr - decompress_size); - else - target_addr =3D ALIGN_UP (image_target->link_addr - + kernel_size + total_module_size, 32); - - ecoff_img =3D xmalloc (program_size + sizeof (*head) + sizeof (*section= )); - grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*sec= tion)); - head =3D (void *) ecoff_img; - section =3D (void *) (head + 1); - head->magic =3D image_target->bigendian ? grub_host_to_target16 (0x160)= - : grub_host_to_target16 (0x166); - head->nsec =3D grub_host_to_target16 (1); - head->time =3D grub_host_to_target32 (0); - head->opt =3D grub_host_to_target16 (0x38); - head->flags =3D image_target->bigendian - ? grub_host_to_target16 (0x207) - : grub_host_to_target16 (0x103); - head->magic2 =3D grub_host_to_target16 (0x107); - head->textsize =3D grub_host_to_target32 (program_size); - head->entry =3D grub_host_to_target32 (target_addr); - head->text_start =3D grub_host_to_target32 (target_addr); - head->data_start =3D grub_host_to_target32 (target_addr + program_size)= ; - grub_memcpy (section->name, ".text", sizeof (".text") - 1);=20 - section->vaddr =3D grub_host_to_target32 (target_addr); - section->size =3D grub_host_to_target32 (program_size); - section->file_offset =3D grub_host_to_target32 (sizeof (*head) + sizeof= (*section)); - if (!image_target->bigendian) - { - section->paddr =3D grub_host_to_target32 (0xaa60); - section->flags =3D grub_host_to_target32 (0x20); - } - memcpy (section + 1, core_img, core_size); - free (core_img); - core_img =3D ecoff_img; - core_size =3D program_size + sizeof (*head) + sizeof (*section); - } - break; - case IMAGE_LOONGSON_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 =3D 0; - int phnum =3D 1; -=09 - if (image_target->id !=3D IMAGE_LOONGSON_ELF) - phnum +=3D 2; - - if (note) - { - phnum++; - footer_size +=3D sizeof (struct grub_ieee1275_note); - } - header_size =3D ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); - - program_size =3D ALIGN_ADDR (core_size); - - elf_img =3D 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 =3D (void *) elf_img; - phdr =3D (void *) (elf_img + sizeof (*ehdr)); - memcpy (ehdr->e_ident, ELFMAG, SELFMAG); - ehdr->e_ident[EI_CLASS] =3D ELFCLASS32; - if (!image_target->bigendian) - ehdr->e_ident[EI_DATA] =3D ELFDATA2LSB; - else - ehdr->e_ident[EI_DATA] =3D ELFDATA2MSB; - ehdr->e_ident[EI_VERSION] =3D EV_CURRENT; - ehdr->e_ident[EI_OSABI] =3D ELFOSABI_NONE; - ehdr->e_type =3D grub_host_to_target16 (ET_EXEC); - ehdr->e_machine =3D grub_host_to_target16 (image_target->elf_target); - ehdr->e_version =3D grub_host_to_target32 (EV_CURRENT); - - ehdr->e_phoff =3D grub_host_to_target32 ((char *) phdr - (char *) ehdr)= ; - ehdr->e_phentsize =3D grub_host_to_target16 (sizeof (*phdr)); - ehdr->e_phnum =3D grub_host_to_target16 (phnum); - - /* No section headers. */ - ehdr->e_shoff =3D grub_host_to_target32 (0); - if (image_target->id =3D=3D IMAGE_LOONGSON_ELF) - ehdr->e_shentsize =3D grub_host_to_target16 (0); - else - ehdr->e_shentsize =3D grub_host_to_target16 (sizeof (Elf32_Shdr)); - ehdr->e_shnum =3D grub_host_to_target16 (0); - ehdr->e_shstrndx =3D grub_host_to_target16 (0); - - ehdr->e_ehsize =3D grub_host_to_target16 (sizeof (*ehdr)); - - phdr->p_type =3D grub_host_to_target32 (PT_LOAD); - phdr->p_offset =3D grub_host_to_target32 (header_size); - phdr->p_flags =3D grub_host_to_target32 (PF_R | PF_W | PF_X); - - if (image_target->id =3D=3D IMAGE_LOONGSON_ELF) - { - if (comp =3D=3D COMPRESSION_NONE) - target_addr =3D (image_target->link_addr - decompress_size); - else - target_addr =3D ALIGN_UP (image_target->link_addr - + kernel_size + total_module_size, 32); - } - else - target_addr =3D image_target->link_addr; - ehdr->e_entry =3D grub_host_to_target32 (target_addr); - phdr->p_vaddr =3D grub_host_to_target32 (target_addr); - phdr->p_paddr =3D grub_host_to_target32 (target_addr); - phdr->p_align =3D grub_host_to_target32 (align > image_target->link_ali= gn ? align : image_target->link_align); - if (image_target->id =3D=3D IMAGE_LOONGSON_ELF) - ehdr->e_flags =3D grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER=20 - | EF_MIPS_PIC | EF_MIPS_CPIC); - else - ehdr->e_flags =3D 0; - if (image_target->id =3D=3D IMAGE_LOONGSON_ELF) - { - phdr->p_filesz =3D grub_host_to_target32 (core_size); - phdr->p_memsz =3D grub_host_to_target32 (core_size); - } - else - { - grub_uint32_t target_addr_mods; - phdr->p_filesz =3D grub_host_to_target32 (kernel_size); - phdr->p_memsz =3D grub_host_to_target32 (kernel_size + bss_size); - - phdr++; - phdr->p_type =3D grub_host_to_target32 (PT_GNU_STACK); - phdr->p_offset =3D grub_host_to_target32 (header_size + kernel_size= ); - phdr->p_paddr =3D phdr->p_vaddr =3D phdr->p_filesz =3D phdr->p_mems= z =3D 0; - phdr->p_flags =3D grub_host_to_target32 (PF_R | PF_W | PF_X); - phdr->p_align =3D grub_host_to_target32 (image_target->link_align);= - - phdr++; - phdr->p_type =3D grub_host_to_target32 (PT_LOAD); - phdr->p_offset =3D grub_host_to_target32 (header_size + kernel_size= ); - phdr->p_flags =3D grub_host_to_target32 (PF_R | PF_W | PF_X); - phdr->p_filesz =3D phdr->p_memsz - =3D grub_host_to_target32 (core_size - kernel_size); - - if (image_target->id =3D=3D IMAGE_COREBOOT) - target_addr_mods =3D GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR; - else - target_addr_mods =3D ALIGN_UP (target_addr + kernel_size + bss_si= ze - + image_target->mod_gap, - image_target->mod_align); - phdr->p_vaddr =3D grub_host_to_target32 (target_addr_mods); - phdr->p_paddr =3D grub_host_to_target32 (target_addr_mods); - phdr->p_align =3D grub_host_to_target32 (image_target->link_align);= - } - - if (note) - { - int note_size =3D sizeof (struct grub_ieee1275_note); - struct grub_ieee1275_note *note_ptr =3D (struct grub_ieee1275_note = *)=20 - (elf_img + program_size + header_size); - - grub_util_info ("adding CHRP NOTE segment"); - - note_ptr->header.namesz =3D grub_host_to_target32 (sizeof (GRUB_IEE= E1275_NOTE_NAME)); - note_ptr->header.descsz =3D grub_host_to_target32 (note_size); - note_ptr->header.type =3D grub_host_to_target32 (GRUB_IEEE1275_NOTE= _TYPE); - strcpy (note_ptr->header.name, GRUB_IEEE1275_NOTE_NAME); - note_ptr->descriptor.real_mode =3D grub_host_to_target32 (0xfffffff= f); - note_ptr->descriptor.real_base =3D grub_host_to_target32 (0x00c0000= 0); - note_ptr->descriptor.real_size =3D grub_host_to_target32 (0xfffffff= f); - note_ptr->descriptor.virt_base =3D grub_host_to_target32 (0xfffffff= f); - note_ptr->descriptor.virt_size =3D grub_host_to_target32 (0xfffffff= f); - note_ptr->descriptor.load_base =3D grub_host_to_target32 (0x0000400= 0); - - phdr++; - phdr->p_type =3D grub_host_to_target32 (PT_NOTE); - phdr->p_flags =3D grub_host_to_target32 (PF_R); - phdr->p_align =3D grub_host_to_target32 (image_target->voidp_sizeof= ); - phdr->p_vaddr =3D 0; - phdr->p_paddr =3D 0; - phdr->p_filesz =3D grub_host_to_target32 (note_size); - phdr->p_memsz =3D 0; - phdr->p_offset =3D grub_host_to_target32 (header_size + program_siz= e); - } - - free (core_img); - core_img =3D elf_img; - core_size =3D program_size + header_size + footer_size; - } - break; - } - - grub_util_write_image (core_img, core_size, out, outname); - free (core_img); - free (kernel_path); - - while (path_list) - { - next =3D path_list->next; - free ((void *) path_list->name); - free (path_list); - path_list =3D next; - } -} - =0C =20 static struct argp_option options[] =3D { @@ -1860,22 +88,7 @@ return xasprintf (text, DEFAULT_DIRECTORY); case 'O': { - int format_len =3D 0; - char *formats; - char *ptr; - char *ret; - unsigned i; - for (i =3D 0; i < ARRAY_SIZE (image_targets); i++) - format_len +=3D strlen (image_targets[i].names[0]) + 2; - ptr =3D formats =3D xmalloc (format_len); - for (i =3D 0; i < ARRAY_SIZE (image_targets); i++) - { - strcpy (ptr, image_targets[i].names[0]); - ptr +=3D strlen (image_targets[i].names[0]); - *ptr++ =3D ','; - *ptr++ =3D ' '; - } - ptr[-2] =3D 0; + char *formats =3D grub_install_get_image_targets_string (), *ret; ret =3D xasprintf ("%s\n%s %s", _("generate an image in FORMAT"), _("available formats:"), formats); free (formats); @@ -1900,10 +113,11 @@ char *font; char *config; int note; - struct image_target_desc *image_target; + struct grub_install_image_target_desc *image_target; grub_compression_t comp; }; =20 + static error_t argp_parser (int key, char *arg, struct argp_state *state) { @@ -1922,12 +136,7 @@ =20 case 'O': { - unsigned i, j; - for (i =3D 0; i < ARRAY_SIZE (image_targets); i++) - for (j =3D 0; image_targets[i].names[j] - && j < ARRAY_SIZE (image_targets[i].names); j++) - if (strcmp (arg, image_targets[i].names[j]) =3D=3D 0) - arguments->image_target =3D &image_targets[i]; + arguments->image_target =3D grub_install_get_image_target (arg); if (!arguments->image_target) { printf (_("unknown target format %s\n"), arg); @@ -1977,16 +186,16 @@ if (grub_strcmp (arg, "xz") =3D=3D 0) { #ifdef HAVE_LIBLZMA - arguments->comp =3D COMPRESSION_XZ; + arguments->comp =3D GRUB_COMPRESSION_XZ; #else grub_util_error ("%s", _("grub-mkimage is compiled without XZ support")); #endif } else if (grub_strcmp (arg, "none") =3D=3D 0) - arguments->comp =3D COMPRESSION_NONE; + arguments->comp =3D GRUB_COMPRESSION_NONE; else if (grub_strcmp (arg, "auto") =3D=3D 0) - arguments->comp =3D COMPRESSION_AUTO; + arguments->comp =3D GRUB_COMPRESSION_AUTO; else grub_util_error (_("Unknown compression format %s"), arg); break; @@ -2029,7 +238,7 @@ grub_util_init_nls (); =20 memset (&arguments, 0, sizeof (struct arguments)); - arguments.comp =3D COMPRESSION_AUTO; + arguments.comp =3D GRUB_COMPRESSION_AUTO; arguments.modules_max =3D argc + 1; arguments.modules =3D xmalloc ((arguments.modules_max + 1) * sizeof (arguments.modules[0])); @@ -2061,21 +270,24 @@ =20 if (!arguments.dir) { + const char *dn =3D grub_util_get_target_dirname (arguments.image_t= arget); arguments.dir =3D xmalloc (sizeof (GRUB_PKGLIBDIR) - + grub_strlen (arguments.image_target->dirname) + + grub_strlen (dn) + 1); memcpy (arguments.dir, GRUB_PKGLIBDIR, sizeof (GRUB_PKGLIBDIR) - 1); *(arguments.dir + sizeof (GRUB_PKGLIBDIR) - 1) =3D '/'; - strcpy (arguments.dir + sizeof (GRUB_PKGLIBDIR), - arguments.image_target->dirname); + strcpy (arguments.dir + sizeof (GRUB_PKGLIBDIR), dn); } =20 - generate_image (arguments.dir, arguments.prefix ? : DEFAULT_DIRECTORY,= fp, - arguments.output, - arguments.modules, arguments.memdisk, arguments.pubkeys, - arguments.npubkeys, arguments.config, - arguments.image_target, arguments.note, arguments.comp); + grub_install_generate_image (arguments.dir, + arguments.prefix ? : DEFAULT_DIRECTORY, fp, + arguments.output, + arguments.modules, arguments.memdisk, + arguments.pubkeys, + arguments.npubkeys, arguments.config, + arguments.image_target, arguments.note, + arguments.comp); =20 fflush (fp); fsync (fileno (fp)); =3D=3D=3D modified file 'util/grub-mkimagexx.c' --- util/grub-mkimagexx.c 2013-08-23 07:01:11 +0000 +++ util/grub-mkimagexx.c 2013-10-04 00:39:55 +0000 @@ -67,7 +67,7 @@ Elf_Shdr *symtab_section, Elf_Addr *section_addresses, Elf_Half section_entsize, Elf_Half num_sections, void *jumpers, Elf_Addr jumpers_addr, - struct image_target_desc *image_target) + struct grub_install_image_target_desc *image_target) { Elf_Word symtab_size, sym_size, num_syms; Elf_Off symtab_offset; @@ -140,7 +140,7 @@ /* 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) + struct grub_install_image_target_desc *image_target) { Elf_Sym *sym; =20 @@ -153,7 +153,7 @@ /* 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) + struct grub_install_image_target_desc *image_target) { return (Elf_Addr *) ((char *) e + grub_target_to_host (s->sh_offset) += offset); } @@ -161,7 +161,7 @@ #ifdef MKIMAGE_ELF64 static Elf_Addr SUFFIX (count_funcs) (Elf_Ehdr *e, Elf_Shdr *symtab_section, - struct image_target_desc *image_target) + struct grub_install_image_target_desc *image_target) { Elf_Word symtab_size, sym_size, num_syms; Elf_Off symtab_offset; @@ -195,7 +195,7 @@ const char *strtab, char *pe_target, Elf_Addr tramp_off, Elf_Addr got_off, - struct image_target_desc *image_target) + struct grub_install_image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; @@ -472,7 +472,7 @@ 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_install_image_target_desc *image_target) { struct grub_pe32_fixup_block *b; =20 @@ -569,7 +569,7 @@ Elf_Half section_entsize, Elf_Half num_sections, const char *strtab, Elf_Addr jumpers, grub_size_t njumpers, - struct image_target_desc *image_target) + struct grub_install_image_target_desc *image_target) { unsigned i; Elf_Shdr *s; @@ -755,7 +755,7 @@ /* 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_t= arget) +SUFFIX (is_text_section) (Elf_Shdr *s, struct grub_install_image_target_= desc *image_target) { if (image_target->id !=3D IMAGE_EFI=20 && grub_target_to_host32 (s->sh_type) !=3D SHT_PROGBITS) @@ -768,7 +768,7 @@ 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_t= arget) +SUFFIX (is_data_section) (Elf_Shdr *s, struct grub_install_image_target_= desc *image_target) { if (image_target->id !=3D IMAGE_EFI=20 && grub_target_to_host32 (s->sh_type) !=3D SHT_PROGBITS) @@ -779,7 +779,7 @@ =20 /* 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) +SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, struct grub_install= _image_target_desc *image_target) { if (size < sizeof (*e) || e->e_ident[EI_MAG0] !=3D ELFMAG0 @@ -802,7 +802,7 @@ 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) + struct grub_install_image_target_desc *image_target) { int i; Elf_Addr current_address; @@ -884,7 +884,7 @@ 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) + struct grub_install_image_target_desc *image_target) { char *kernel_img, *out_img; const char *strtab; =3D=3D=3D modified file 'util/grub-setup.c' --- util/grub-setup.c 2013-04-04 06:55:06 +0000 +++ util/grub-setup.c 2013-10-04 00:39:55 +0000 @@ -31,14 +31,6 @@ #include #include #include -#ifdef GRUB_SETUP_SPARC64 -#include -#include -#include -#else -#include -#include -#endif =20 #include #include @@ -53,6 +45,7 @@ #include #include #include +#include =20 #ifdef __linux__ #include @@ -63,917 +56,6 @@ #define _GNU_SOURCE 1 #include =20 -/* On SPARC this program fills in various fields inside of the 'boot' an= d 'core' - * image files. - * - * The 'boot' image needs to know the OBP path name of the root - * device. It also needs to know the initial block number of - * 'core' (which is 'diskboot' concatenated with 'kernel' and - * all the modules, this is created by grub-mkimage). This resulting - * 'boot' image is 512 bytes in size and is placed in the second block - * of a partition. - * - * The initial 'diskboot' block acts as a loader for the actual GRUB - * kernel. It contains the loading code and then a block list. - * - * The block list of 'core' starts at the end of the 'diskboot' image - * and works it's way backwards towards the end of the code of 'diskboot= '. - * - * We patch up the images with the necessary values and write out the - * result. - */ - -#define DEFAULT_BOOT_FILE "boot.img" -#define DEFAULT_CORE_FILE "core.img" - -#ifdef GRUB_SETUP_SPARC64 -#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) -#elif defined (GRUB_SETUP_BIOS) -#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) -#else -#error Complete this -#endif - -static void -write_rootdev (grub_device_t root_dev, - char *boot_img, grub_uint64_t first_sector) -{ -#ifdef GRUB_SETUP_BIOS - { - grub_uint8_t *boot_drive; - void *kernel_sector; - boot_drive =3D (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_D= RIVE); - kernel_sector =3D (boot_img + GRUB_BOOT_MACHINE_KERNEL_SECTOR); - - /* FIXME: can this be skipped? */ - *boot_drive =3D 0xFF; - - grub_set_unaligned64 (kernel_sector, grub_cpu_to_le64 (first_sector)= ); - } -#endif -#ifdef GRUB_SETUP_SPARC64 - { - void *kernel_byte; - kernel_byte =3D (boot_img + GRUB_BOOT_AOUT_HEADER_SIZE - + GRUB_BOOT_MACHINE_KERNEL_BYTE); - grub_set_unaligned64 (kernel_byte, - grub_cpu_to_be64 (first_sector << GRUB_DISK_SECTOR_BITS)); - } -#endif -} - -#ifdef GRUB_SETUP_SPARC64 -#define BOOT_SECTOR 1 -#else -#define BOOT_SECTOR 0 -#endif - -/* Helper for setup. */ -static void -save_first_sector (grub_disk_addr_t sector, unsigned offset, unsigned le= ngth, - void *data) -{ - grub_disk_addr_t *first_sector =3D data; - grub_util_info ("the first sector is <%" PRIuGRUB_UINT64_T ",%u,%u>", - sector, offset, length); - - if (offset !=3D 0 || length !=3D GRUB_DISK_SECTOR_SIZE) - grub_util_error ("%s", _("the first sector of the core file is not s= ector-aligned")); - - *first_sector =3D sector; -} - -struct blocklists -{ - struct grub_boot_blocklist *first_block, *block; -#ifdef GRUB_SETUP_BIOS - grub_uint16_t current_segment; -#endif - grub_uint16_t last_length; -}; - -/* Helper for setup. */ -static void -save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned leng= th, - void *data) -{ - struct blocklists *bl =3D data; - struct grub_boot_blocklist *prev =3D bl->block + 1; - - grub_util_info ("saving <%" PRIuGRUB_UINT64_T ",%u,%u>", - sector, offset, length); - - if (offset !=3D 0 || bl->last_length !=3D GRUB_DISK_SECTOR_SIZE) - grub_util_error ("%s", _("non-sector-aligned data is found in the co= re file")); - - if (bl->block !=3D bl->first_block - && (grub_target_to_host64 (prev->start) - + grub_target_to_host16 (prev->len)) =3D=3D sector) - { - grub_uint16_t t =3D grub_target_to_host16 (prev->len) + 1; - prev->len =3D grub_host_to_target16 (t); - } - else - { - bl->block->start =3D grub_host_to_target64 (sector); - bl->block->len =3D grub_host_to_target16 (1); -#ifdef GRUB_SETUP_BIOS - bl->block->segment =3D grub_host_to_target16 (bl->current_segment)= ; -#endif - - bl->block--; - if (bl->block->len) - grub_util_error ("%s", _("the sectors of the core file are too fragment= ed")); - } - - bl->last_length =3D length; -#ifdef GRUB_SETUP_BIOS - bl->current_segment +=3D GRUB_DISK_SECTOR_SIZE >> 4; -#endif -} - -#ifdef GRUB_SETUP_BIOS -/* Context for setup/identify_partmap. */ -struct identify_partmap_ctx -{ - grub_partition_map_t dest_partmap; - grub_partition_t container; - int multiple_partmaps; -}; - -/* Helper for setup. - Unlike root_dev, with dest_dev we're interested in the partition map = even - if dest_dev itself is a whole disk. */ -static int -identify_partmap (grub_disk_t disk __attribute__ ((unused)), - const grub_partition_t p, void *data) -{ - struct identify_partmap_ctx *ctx =3D data; - - if (p->parent !=3D ctx->container) - return 0; - /* NetBSD and OpenBSD subpartitions have metadata inside a partition, - so they are safe to ignore. - */ - if (grub_strcmp (p->partmap->name, "netbsd") =3D=3D 0 - || grub_strcmp (p->partmap->name, "openbsd") =3D=3D 0) - return 0; - if (ctx->dest_partmap =3D=3D NULL) - { - ctx->dest_partmap =3D p->partmap; - return 0; - } - if (ctx->dest_partmap =3D=3D p->partmap) - return 0; - ctx->multiple_partmaps =3D 1; - return 1; -} -#endif - -static void -setup (const char *dir, - const char *boot_file, const char *core_file, - const char *dest, int force, - int fs_probe, int allow_floppy) -{ - char *boot_path, *core_path, *core_path_dev, *core_path_dev_full; - char *boot_img, *core_img; - char *root =3D 0; - size_t boot_size, core_size; -#ifdef GRUB_SETUP_BIOS - grub_uint16_t core_sectors; -#endif - grub_device_t root_dev =3D 0, dest_dev, core_dev; - struct blocklists bl; - char *tmp_img; - grub_disk_addr_t first_sector =3D (grub_disk_addr_t)-1; - FILE *fp; - -#ifdef GRUB_SETUP_BIOS - bl.current_segment =3D - GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4); -#endif - bl.last_length =3D GRUB_DISK_SECTOR_SIZE; - - /* Read the boot image by the OS service. */ - boot_path =3D grub_util_get_path (dir, boot_file); - boot_size =3D grub_util_get_image_size (boot_path); - if (boot_size !=3D GRUB_DISK_SECTOR_SIZE) - grub_util_error (_("the size of `%s' is not %u"), - boot_path, GRUB_DISK_SECTOR_SIZE); - boot_img =3D grub_util_read_image (boot_path); - free (boot_path); - - core_path =3D grub_util_get_path (dir, core_file); - core_size =3D grub_util_get_image_size (core_path); -#ifdef GRUB_SETUP_BIOS - core_sectors =3D ((core_size + GRUB_DISK_SECTOR_SIZE - 1) - >> GRUB_DISK_SECTOR_BITS); -#endif - if (core_size < GRUB_DISK_SECTOR_SIZE) - grub_util_error (_("the size of `%s' is too small"), core_path); -#ifdef GRUB_SETUP_BIOS - if (core_size > 0xFFFF * GRUB_DISK_SECTOR_SIZE) - grub_util_error (_("the size of `%s' is too large"), core_path); -#endif - - core_img =3D grub_util_read_image (core_path); - - /* Have FIRST_BLOCK to point to the first blocklist. */ - bl.first_block =3D (struct grub_boot_blocklist *) (core_img - + GRUB_DISK_SECTOR_SIZE - - sizeof (*bl.block)); - grub_util_info ("root is `%s', dest is `%s'", root, dest); - - grub_util_info ("Opening dest"); - dest_dev =3D grub_device_open (dest); - if (! dest_dev) - grub_util_error ("%s", grub_errmsg); - - core_dev =3D dest_dev; - - { - char **root_devices =3D grub_guess_root_devices (dir); - char **cur; - int found =3D 0; - - for (cur =3D root_devices; *cur; cur++) - { - char *drive; - grub_device_t try_dev; - - drive =3D grub_util_get_grub_dev (*cur); - if (!drive) - continue; - try_dev =3D grub_device_open (drive); - if (! try_dev) - continue; - if (!found && try_dev->disk->id =3D=3D dest_dev->disk->id - && try_dev->disk->dev->id =3D=3D dest_dev->disk->dev->id) - { - if (root_dev) - grub_device_close (root_dev); - free (root); - root_dev =3D try_dev; - root =3D drive; - found =3D 1; - continue; - } - if (!root_dev) - { - root_dev =3D try_dev; - root =3D drive; - continue; - } - grub_device_close (try_dev);=09 - free (drive); - } - if (!root_dev) - { - grub_util_error ("guessing the root device failed, because of `%s'", - grub_errmsg); - } - grub_util_info ("guessed root_dev `%s' from " - "dir `%s'", root_dev->disk->name, dir); - } - - grub_util_info ("setting the root device to `%s'", root); - if (grub_env_set ("root", root) !=3D GRUB_ERR_NONE) - grub_util_error ("%s", grub_errmsg); - -#ifdef GRUB_SETUP_BIOS - /* Read the original sector from the disk. */ - tmp_img =3D xmalloc (GRUB_DISK_SECTOR_SIZE); - if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_i= mg)) - grub_util_error ("%s", grub_errmsg); -#endif - -#ifdef GRUB_SETUP_BIOS - { - grub_uint8_t *boot_drive_check; - boot_drive_check =3D (grub_uint8_t *) (boot_img - + GRUB_BOOT_MACHINE_DRIVE_CHECK); - /* Copy the possible DOS BPB. */ - memcpy (boot_img + GRUB_BOOT_MACHINE_BPB_START, - tmp_img + GRUB_BOOT_MACHINE_BPB_START, - GRUB_BOOT_MACHINE_BPB_END - GRUB_BOOT_MACHINE_BPB_START); - - /* If DEST_DRIVE is a hard disk, enable the workaround, which is - for buggy BIOSes which don't pass boot drive correctly. Instead, - they pass 0x00 or 0x01 even when booted from 0x80. */ - if (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk))= - { - /* Replace the jmp (2 bytes) with double nop's. */ - boot_drive_check[0] =3D 0x90; - boot_drive_check[1] =3D 0x90; - } - } -#endif - -#ifdef GRUB_SETUP_BIOS - { - struct identify_partmap_ctx ctx =3D { - .dest_partmap =3D NULL, - .container =3D dest_dev->disk->partition, - .multiple_partmaps =3D 0 - }; - int is_ldm; - grub_err_t err; - grub_disk_addr_t *sectors; - int i; - grub_fs_t fs; - unsigned int nsec, maxsec; - - grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx); - - if (ctx.container - && grub_strcmp (ctx.container->partmap->name, "msdos") =3D=3D 0 - && ctx.dest_partmap - && (ctx.container->msdostype =3D=3D GRUB_PC_PARTITION_TYPE_NETBSD - || ctx.container->msdostype =3D=3D GRUB_PC_PARTITION_TYPE_OPENBSD))= - { - grub_util_warn ("%s", _("Attempting to install GRUB to a disk with mult= iple partition labels or both partition label and filesystem. This is no= t supported yet.")); - goto unable_to_embed; - } - - fs =3D grub_fs_probe (dest_dev); - if (!fs) - grub_errno =3D GRUB_ERR_NONE; - - is_ldm =3D grub_util_is_ldm (dest_dev->disk); - - if (fs_probe) - { - if (!fs && !ctx.dest_partmap) - grub_util_error (_("unable to identify a filesystem in %s; safety che= ck can't be performed"), - dest_dev->disk->name); - if (fs && !fs->reserved_first_sector) - /* TRANSLATORS: Filesystem may reserve the space just GRUB isn't sure= about it. */ - grub_util_error (_("%s appears to contain a %s filesystem which isn't= known to " - "reserve space for DOS-style boot. Installing GRUB there could = " - "result in FILESYSTEM DESTRUCTION if valuable data is overwritte= n " - "by grub-setup (--skip-fs-probe disables this " - "check, use at your own risk)"), dest_dev->disk->name, fs->name)= ; - - if (ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") !=3D 0= - && strcmp (ctx.dest_partmap->name, "gpt") !=3D 0 - && strcmp (ctx.dest_partmap->name, "bsd") !=3D 0 - && strcmp (ctx.dest_partmap->name, "netbsd") !=3D 0 - && strcmp (ctx.dest_partmap->name, "openbsd") !=3D 0 - && strcmp (ctx.dest_partmap->name, "sunpc") !=3D 0) - /* TRANSLATORS: Partition map may reserve the space just GRUB isn't s= ure about it. */ - grub_util_error (_("%s appears to contain a %s partition map which is= n't known to " - "reserve space for DOS-style boot. Installing GRUB there could = " - "result in FILESYSTEM DESTRUCTION if valuable data is overwritte= n " - "by grub-setup (--skip-fs-probe disables this " - "check, use at your own risk)"), dest_dev->disk->name, ctx.dest_= partmap->name); - if (is_ldm && ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdo= s") !=3D 0 - && strcmp (ctx.dest_partmap->name, "gpt") !=3D 0) - grub_util_error (_("%s appears to contain a %s partition map and " - "LDM which isn't known to be a safe combination." - " Installing GRUB there could " - "result in FILESYSTEM DESTRUCTION if valuable data" - " is overwritten " - "by grub-setup (--skip-fs-probe disables this " - "check, use at your own risk)"), - dest_dev->disk->name, ctx.dest_partmap->name); - - } - - /* Copy the partition table. */ - if (ctx.dest_partmap || - (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk)= )) - memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, - tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, - GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC);= - - free (tmp_img); - =20 - if (! ctx.dest_partmap && ! fs && !is_ldm) - { - grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless = disk or to a partition. This is a BAD idea.")); - goto unable_to_embed; - } - if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && = fs)) - { - grub_util_warn ("%s", _("Attempting to install GRUB to a disk with mult= iple partition labels. This is not supported yet.")); - goto unable_to_embed; - } - - if (ctx.dest_partmap && !ctx.dest_partmap->embed) - { - grub_util_warn (_("Partition style `%s' doesn't support embedding"), - ctx.dest_partmap->name); - goto unable_to_embed; - } - - if (fs && !fs->embed) - { - grub_util_warn (_("File system `%s' doesn't support embedding"), - fs->name); - goto unable_to_embed; - } - - nsec =3D core_sectors; - - maxsec =3D 2 * core_sectors; - if (maxsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) - >> GRUB_DISK_SECTOR_BITS)) - maxsec =3D ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) - >> GRUB_DISK_SECTOR_BITS); - - if (is_ldm) - err =3D grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec, - GRUB_EMBED_PCBIOS, §ors); - else if (ctx.dest_partmap) - err =3D ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec, - GRUB_EMBED_PCBIOS, §ors); - else - err =3D fs->embed (dest_dev, &nsec, maxsec, - GRUB_EMBED_PCBIOS, §ors); - if (!err && nsec < core_sectors) - { - err =3D grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("Your embedding area is unusually small. " - "core.img won't fit in it.")); - } - =20 - if (err) - { - grub_util_warn ("%s", grub_errmsg); - grub_errno =3D GRUB_ERR_NONE; - goto unable_to_embed; - } - - assert (nsec <=3D maxsec); - - /* Clean out the blocklists. */ - bl.block =3D bl.first_block; - while (bl.block->len) - { - grub_memset (bl.block, 0, sizeof (bl.block)); - =20 - bl.block--; - - if ((char *) bl.block <=3D core_img) - grub_util_error ("%s", _("no terminator in the core image")); - } - - save_first_sector (sectors[0] + grub_partition_get_start (ctx.contai= ner), - 0, GRUB_DISK_SECTOR_SIZE, &first_sector); - - bl.block =3D bl.first_block; - for (i =3D 1; i < nsec; i++) - save_blocklists (sectors[i] + grub_partition_get_start (ctx.contai= ner), - 0, GRUB_DISK_SECTOR_SIZE, &bl); - - /* Make sure that the last blocklist is a terminator. */ - if (bl.block =3D=3D bl.first_block) - bl.block--; - bl.block->start =3D 0; - bl.block->len =3D 0; - bl.block->segment =3D 0; - - write_rootdev (root_dev, boot_img, first_sector); - - core_img =3D realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); - bl.first_block =3D (struct grub_boot_blocklist *) (core_img - + GRUB_DISK_SECTOR_SIZE - - sizeof (*bl.block)); - - grub_size_t no_rs_length; - grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE - + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY), - grub_host_to_target32 (nsec * GRUB_DISK_SECTOR_SIZE - core_size)); - no_rs_length =3D grub_target_to_host16=20 - (grub_get_unaligned16 (core_img - + GRUB_DISK_SECTOR_SIZE - + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH)); - - if (no_rs_length =3D=3D 0xffff) - grub_util_error ("%s", _("core.img version mismatch")); - - void *tmp =3D xmalloc (core_size); - grub_memcpy (tmp, core_img, core_size); - grub_reed_solomon_add_redundancy (core_img + no_rs_length + GRUB_DIS= K_SECTOR_SIZE, - core_size - no_rs_length - GRUB_DISK_SECTOR_SIZE, - nsec * GRUB_DISK_SECTOR_SIZE - - core_size); - assert (grub_memcmp (tmp, core_img, core_size) =3D=3D 0); - free (tmp); - - /* Write the core image onto the disk. */ - for (i =3D 0; i < nsec; i++) - grub_disk_write (dest_dev->disk, sectors[i], 0, - GRUB_DISK_SECTOR_SIZE, - core_img + i * GRUB_DISK_SECTOR_SIZE); - - grub_free (sectors); - - goto finish; - } - -unable_to_embed: -#endif - - if (dest_dev->disk->dev->id !=3D root_dev->disk->dev->id) - grub_util_error ("%s", _("embedding is not possible, but this is req= uired for " - "RAID and LVM install")); - - { - grub_fs_t fs; - fs =3D grub_fs_probe (root_dev); - if (!fs) - grub_util_error (_("can't determine filesystem on %s"), root); - - if (!fs->blocklist_install) - grub_util_error (_("filesystem `%s' doesn't support blocklists"), - fs->name); - } - -#ifdef GRUB_SETUP_BIOS - if (dest_dev->disk->id !=3D root_dev->disk->id - || dest_dev->disk->dev->id !=3D root_dev->disk->dev->id) - /* TRANSLATORS: cross-disk refers to /boot being on one disk - but MBR on another. */ - grub_util_error ("%s", _("embedding is not possible, but this is req= uired for " - "cross-disk install")); -#else - core_dev =3D root_dev; -#endif - - grub_util_warn ("%s", _("Embedding is not possible. GRUB can only be = installed in this " - "setup by using blocklists. However, blocklists are UNRELIABLE and= " - "their use is discouraged.")); - if (! force) - /* TRANSLATORS: Here GRUB refuses to continue with blocklist install= =2E */ - grub_util_error ("%s", _("will not proceed with blocklists")); - - /* The core image must be put on a filesystem unfortunately. */ - grub_util_info ("will leave the core image on the filesystem"); - - /* Make sure that GRUB reads the identical image as the OS. */ - tmp_img =3D xmalloc (core_size); - core_path_dev_full =3D grub_util_get_path (dir, core_file); - core_path_dev =3D grub_make_system_path_relative_to_its_root (core_pat= h_dev_full); - free (core_path_dev_full); - - grub_util_biosdisk_flush (root_dev->disk); - -#ifndef __linux__ - -#define MAX_TRIES 5 - { - int i; - for (i =3D 0; i < MAX_TRIES; i++) - { - grub_file_t file; - - grub_util_info ((i =3D=3D 0) ? _("attempting to read the core image `%s= ' from GRUB") - : _("attempting to read the core image `%s' from GRUB again"), - core_path_dev); - - grub_disk_cache_invalidate_all (); - - grub_file_filter_disable_compression (); - file =3D grub_file_open (core_path_dev); - if (file) - { - if (grub_file_size (file) !=3D core_size) - grub_util_info ("succeeded in opening the core image but the size= is different (%d !=3D %d)", - (int) grub_file_size (file), (int) core_size); - else if (grub_file_read (file, tmp_img, core_size) - !=3D (grub_ssize_t) core_size) - grub_util_info ("succeeded in opening the core image but cannot r= ead %d bytes", - (int) core_size); - else if (memcmp (core_img, tmp_img, core_size) !=3D 0) - { -#if 0 - FILE *dump; - FILE *dump2; - - dump =3D fopen ("dump.img", "wb"); - if (dump) - { - fwrite (tmp_img, 1, core_size, dump); - fclose (dump); - } - - dump2 =3D fopen ("dump2.img", "wb"); - if (dump2) - { - fwrite (core_img, 1, core_size, dump2); - fclose (dump2); - } - -#endif - grub_util_info ("succeeded in opening the core image but the data is d= ifferent"); - } - else - { - grub_file_close (file); - break; - } - - grub_file_close (file); - } - else - grub_util_info ("couldn't open the core image"); - - if (grub_errno) - grub_util_info ("error message =3D %s", grub_errmsg); - - grub_errno =3D GRUB_ERR_NONE; - grub_util_biosdisk_flush (root_dev->disk); - sleep (1); - } - - if (i =3D=3D MAX_TRIES) - grub_util_error (_("cannot read `%s' correctly"), core_path_dev); - } - -#endif - - /* Clean out the blocklists. */ - bl.block =3D bl.first_block; - while (bl.block->len) - { - bl.block->start =3D 0; - bl.block->len =3D 0; -#ifdef GRUB_SETUP_BIOS - bl.block->segment =3D 0; -#endif - - bl.block--; - - if ((char *) bl.block <=3D core_img) - grub_util_error ("%s", _("no terminator in the core image")); - } - - bl.block =3D bl.first_block; - -#ifdef __linux__ - { - grub_partition_t container =3D root_dev->disk->partition; - grub_uint64_t container_start =3D grub_partition_get_start (containe= r); - struct fiemap fie1; - int fd; - - /* Write the first two sectors of the core image onto the disk. */ - grub_util_info ("opening the core image `%s'", core_path); - fp =3D fopen (core_path, "rb"); - if (! fp) - grub_util_error (_("cannot open `%s': %s"), core_path, - strerror (errno)); - fd =3D fileno (fp); - - grub_memset (&fie1, 0, sizeof (fie1)); - fie1.fm_length =3D core_size; - fie1.fm_flags =3D FIEMAP_FLAG_SYNC; - - if (ioctl (fd, FS_IOC_FIEMAP, &fie1) < 0) - { - int nblocks, i, j; - int bsize; - int mul; - - grub_util_info ("FIEMAP failed. Reverting to FIBMAP"); - - if (ioctl (fd, FIGETBSZ, &bsize) < 0) - grub_util_error (_("can't retrieve blocklists: %s"), - strerror (errno)); - if (bsize & (GRUB_DISK_SECTOR_SIZE - 1)) - grub_util_error ("%s", _("blocksize is not divisible by 512")); - mul =3D bsize >> GRUB_DISK_SECTOR_BITS; - nblocks =3D (core_size + bsize - 1) / bsize; - if (mul =3D=3D 0 || nblocks =3D=3D 0) - grub_util_error ("%s", _("can't retrieve blocklists")); - for (i =3D 0; i < nblocks; i++) - { - unsigned blk =3D i; - if (ioctl (fd, FIBMAP, &blk) < 0) - grub_util_error (_("can't retrieve blocklists: %s"), - strerror (errno)); - =20 - for (j =3D 0; j < mul; j++) - { - int rest =3D core_size - ((i * mul + j) << GRUB_DISK_SECTOR_BITS); - if (rest <=3D 0) - break; - if (rest > GRUB_DISK_SECTOR_SIZE) - rest =3D GRUB_DISK_SECTOR_SIZE; - if (i =3D=3D 0 && j =3D=3D 0) - save_first_sector (((grub_uint64_t) blk) * mul - + container_start, - 0, rest, &first_sector); - else - save_blocklists (((grub_uint64_t) blk) * mul + j - + container_start, - 0, rest, &bl); - } - } - } - else - { - struct fiemap *fie2; - int i, j; - fie2 =3D xmalloc (sizeof (*fie2) - + fie1.fm_mapped_extents - * sizeof (fie1.fm_extents[1])); - memset (fie2, 0, sizeof (*fie2) - + fie1.fm_mapped_extents * sizeof (fie2->fm_extents[1])); - fie2->fm_length =3D core_size; - fie2->fm_flags =3D FIEMAP_FLAG_SYNC; - fie2->fm_extent_count =3D fie1.fm_mapped_extents; - if (ioctl (fd, FS_IOC_FIEMAP, fie2) < 0) - grub_util_error (_("can't retrieve blocklists: %s"), - strerror (errno)); - for (i =3D 0; i < fie2->fm_mapped_extents; i++) - { - for (j =3D 0; - j < ((fie2->fm_extents[i].fe_length - + GRUB_DISK_SECTOR_SIZE - 1) - >> GRUB_DISK_SECTOR_BITS); - j++) - { - size_t len =3D (fie2->fm_extents[i].fe_length - - j * GRUB_DISK_SECTOR_SIZE); - if (len > GRUB_DISK_SECTOR_SIZE) - len =3D GRUB_DISK_SECTOR_SIZE; - if (first_sector =3D=3D (grub_disk_addr_t)-1) - save_first_sector ((fie2->fm_extents[i].fe_physical - >> GRUB_DISK_SECTOR_BITS) - + j + container_start, - fie2->fm_extents[i].fe_physical - & (GRUB_DISK_SECTOR_SIZE - 1), len, - &first_sector); - else - save_blocklists ((fie2->fm_extents[i].fe_physical - >> GRUB_DISK_SECTOR_BITS) - + j + container_start, - fie2->fm_extents[i].fe_physical - & (GRUB_DISK_SECTOR_SIZE - 1), len, &bl); - - - } - } - if (first_sector =3D=3D (grub_disk_addr_t)-1) - grub_util_error ("%s", _("can't retrieve blocklists")); - } - fclose (fp); - } -#else - { - grub_file_t file; - /* Now read the core image to determine where the sectors are. */ - grub_file_filter_disable_compression (); - file =3D grub_file_open (core_path_dev); - if (! file) - grub_util_error ("%s", grub_errmsg); - - file->read_hook =3D save_first_sector; - file->read_hook_data =3D &first_sector; - if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE) - !=3D GRUB_DISK_SECTOR_SIZE) - grub_util_error ("%s", _("failed to read the first sector of the c= ore image")); - - bl.block =3D bl.first_block; - file->read_hook =3D save_blocklists; - file->read_hook_data =3D &bl; - if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE= ) - !=3D (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE) - grub_util_error ("%s", _("failed to read the rest sectors of the c= ore image")); - grub_file_close (file); - } -#endif - -#ifdef GRUB_SETUP_SPARC64 - { - char *boot_devpath; - boot_devpath =3D (char *) (boot_img - + GRUB_BOOT_AOUT_HEADER_SIZE - + GRUB_BOOT_MACHINE_BOOT_DEVPATH); - if (dest_dev->disk->id !=3D root_dev->disk->id - || dest_dev->disk->dev->id !=3D root_dev->disk->dev->id) - { - const char *dest_ofpath; - dest_ofpath - =3D grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (root_d= ev->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] =3D 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_util_info ("boot device path %s", boot_devpath); - } -#endif - - free (core_path_dev); - free (tmp_img); - - write_rootdev (root_dev, boot_img, first_sector); - - /* Write the first two sectors of the core image onto the disk. */ - grub_util_info ("opening the core image `%s'", core_path); - fp =3D fopen (core_path, "r+b"); - if (! fp) - grub_util_error (_("cannot open `%s': %s"), core_path, - strerror (errno)); - - grub_util_write_image (core_img, GRUB_DISK_SECTOR_SIZE * 2, fp, core_p= ath); - fflush (fp); - fsync (fileno (fp)); - fclose (fp); - grub_util_biosdisk_flush (root_dev->disk); - - grub_disk_cache_invalidate_all (); - - { - char *buf, *ptr =3D core_img; - size_t len =3D core_size; - grub_uint64_t blk; - grub_partition_t container =3D core_dev->disk->partition; - grub_err_t err; - - core_dev->disk->partition =3D 0; - - buf =3D xmalloc (core_size); - blk =3D first_sector; - err =3D grub_disk_read (core_dev->disk, blk, 0, GRUB_DISK_SECTOR_SIZ= E, buf); - if (err) - grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, - grub_errmsg); - if (grub_memcmp (buf, ptr, GRUB_DISK_SECTOR_SIZE) !=3D 0) - grub_util_error ("%s", _("blocklists are invalid")); - - ptr +=3D GRUB_DISK_SECTOR_SIZE; - len -=3D GRUB_DISK_SECTOR_SIZE; - - bl.block =3D bl.first_block; - while (bl.block->len) - { - size_t cur =3D grub_target_to_host16 (bl.block->len) << GRUB_DISK_SECTO= R_BITS; - blk =3D grub_target_to_host64 (bl.block->start); - - if (cur > len) - cur =3D len; - - err =3D grub_disk_read (core_dev->disk, blk, 0, cur, buf); - if (err) - grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, - grub_errmsg); - - if (grub_memcmp (buf, ptr, cur) !=3D 0) - grub_util_error ("%s", _("blocklists are invalid")); - - ptr +=3D cur; - len -=3D cur; - bl.block--; -=09 - if ((char *) bl.block <=3D core_img) - grub_util_error ("%s", _("no terminator in the core image")); - } - core_dev->disk->partition =3D container; - free (buf); - } - -#ifdef GRUB_SETUP_BIOS - finish: -#endif - - /* Write the boot image onto the disk. */ - if (grub_disk_write (dest_dev->disk, BOOT_SECTOR, - 0, GRUB_DISK_SECTOR_SIZE, boot_img)) - grub_util_error ("%s", grub_errmsg); - - grub_util_biosdisk_flush (root_dev->disk); - grub_util_biosdisk_flush (dest_dev->disk); - - free (core_path); - free (core_img); - free (boot_img); - grub_device_close (dest_dev); - grub_device_close (root_dev); -} - static struct argp_option options[] =3D { {"boot-image", 'b', N_("FILE"), 0, N_("use FILE as the boot image [default=3D%s]"), 0}, @@ -1002,10 +84,10 @@ switch (key) { case 'b': - return xasprintf (text, DEFAULT_BOOT_FILE); + return xasprintf (text, "boot.img"); =20 case 'c': - return xasprintf (text, DEFAULT_CORE_FILE); + return xasprintf (text, "core.img"); =20 case 'd': return xasprintf (text, DEFAULT_DIRECTORY); @@ -1199,12 +281,18 @@ grub_util_info ("Using `%s' as GRUB device", dest_dev); } =20 + char *boot_path; + + boot_path =3D grub_util_get_path (arguments.dir ? : DEFAULT_DIRECTORY,= + arguments.boot_file ? : "boot.img"); + /* Do the real work. */ - setup (arguments.dir ? : DEFAULT_DIRECTORY, - arguments.boot_file ? : DEFAULT_BOOT_FILE, - arguments.core_file ? : DEFAULT_CORE_FILE, - dest_dev, arguments.force, - arguments.fs_probe, arguments.allow_floppy); + GRUB_SETUP_FUNC (arguments.dir ? : DEFAULT_DIRECTORY, + boot_path, + arguments.core_file, + dest_dev, arguments.force, + arguments.fs_probe, arguments.allow_floppy); + free (boot_path); =20 /* Free resources. */ grub_fini_all (); =3D=3D=3D added file 'util/mkimage.c' --- util/mkimage.c 1970-01-01 00:00:00 +0000 +++ util/mkimage.c 2013-10-04 00:39:55 +0000 @@ -0,0 +1,1861 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Sof= tware 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "progname.h" + +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +#ifdef HAVE_LIBLZMA +#include +#endif + +#define TARGET_NO_FIELD 0xffffffff + +struct grub_install_image_target_desc +{ + const char *dirname; + const char *names[6]; + grub_size_t voidp_sizeof; + int bigendian; + enum { + IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, + IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_SPARC64_CDCORE, + IMAGE_I386_IEEE1275, + IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, + IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, + IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT + } id; + enum + { + PLATFORM_FLAGS_NONE =3D 0, + PLATFORM_FLAGS_DECOMPRESSORS =3D 2, + PLATFORM_FLAGS_MODULES_BEFORE_KERNEL =3D 4, + } flags; + unsigned total_module_size; + unsigned decompressor_compressed_size; + unsigned decompressor_uncompressed_size; + unsigned decompressor_uncompressed_addr; + unsigned link_align; + grub_uint16_t elf_target; + unsigned section_align; + signed vaddr_offset; + grub_uint64_t link_addr; + unsigned mod_gap, mod_align; + grub_compression_t default_compression; + grub_uint16_t pe_target; +}; + +#define EFI32_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) + +#define EFI64_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) + +struct grub_install_image_target_desc image_targets[] =3D + { + { + .dirname =3D "i386-coreboot", + .names =3D { "i386-coreboot", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_COREBOOT, + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target =3D EM_386, + .link_align =3D 4, + .mod_gap =3D GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align =3D GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, + { + .dirname =3D "i386-multiboot", + .names =3D { "i386-multiboot", NULL}, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_COREBOOT, + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target =3D EM_386, + .link_align =3D 4, + .mod_gap =3D GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align =3D GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, + { + .dirname =3D "i386-pc", + .names =3D { "i386-pc", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_I386_PC,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_I386_PC_COMPRE= SSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_I386_PC_UNCO= MPRESSED_SIZE, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_I386_PC_LINK_ADDR, + .default_compression =3D GRUB_COMPRESSION_LZMA + }, + { + .dirname =3D "i386-pc", + .names =3D { "i386-pc-pxe", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_I386_PC_PXE,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_I386_PC_COMPRE= SSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_I386_PC_UNCO= MPRESSED_SIZE, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_I386_PC_LINK_ADDR, + .default_compression =3D GRUB_COMPRESSION_LZMA + }, + { + .dirname =3D "i386-efi", + .names =3D { "i386-efi", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_EFI, + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset =3D EFI32_HEADER_SIZE, + .pe_target =3D GRUB_PE32_MACHINE_I386, + .elf_target =3D EM_386, + }, + { + .dirname =3D "i386-ieee1275", + .names =3D { "i386-ieee1275", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_I386_IEEE1275,=20 + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_I386_IEEE1275_LINK_ADDR, + .elf_target =3D EM_386, + .mod_gap =3D GRUB_KERNEL_I386_IEEE1275_MOD_GAP, + .mod_align =3D GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN, + .link_align =3D 4, + }, + { + .dirname =3D "i386-qemu", + .names =3D { "i386-qemu", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_QEMU,=20 + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_I386_QEMU_LINK_ADDR + }, + { + .dirname =3D "x86_64-efi", + .names =3D { "x86_64-efi", NULL }, + .voidp_sizeof =3D 8, + .bigendian =3D 0,=20 + .id =3D IMAGE_EFI,=20 + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset =3D EFI64_HEADER_SIZE, + .pe_target =3D GRUB_PE32_MACHINE_X86_64, + .elf_target =3D EM_X86_64, + }, + { + .dirname =3D "mipsel-loongson", + .names =3D { "mipsel-yeeloong-flash", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_YEELOONG_FLASH,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE= , + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, + .elf_target =3D EM_MIPS, + .link_align =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, + .default_compression =3D GRUB_COMPRESSION_NONE + }, + { + .dirname =3D "mipsel-loongson", + .names =3D { "mipsel-fuloong2f-flash", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_FULOONG2F_FLASH,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE= , + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, + .elf_target =3D EM_MIPS, + .link_align =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, + .default_compression =3D GRUB_COMPRESSION_NONE + }, + { + .dirname =3D "mipsel-loongson", + .names =3D { "mipsel-loongson-elf", "mipsel-yeeloong-elf", + "mipsel-fuloong2f-elf", "mipsel-fuloong2e-elf", + "mipsel-fuloong-elf", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_LOONGSON_ELF,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE= , + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, + .elf_target =3D EM_MIPS, + .link_align =3D GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, + .default_compression =3D GRUB_COMPRESSION_NONE + }, + { + .dirname =3D "powerpc-ieee1275", + .names =3D { "powerpc-ieee1275", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 1, + .id =3D IMAGE_PPC,=20 + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR, + .elf_target =3D EM_PPC, + .mod_gap =3D GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, + .mod_align =3D GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN, + .link_align =3D 4 + }, + { + .dirname =3D "sparc64-ieee1275", + .names =3D { "sparc64-ieee1275-raw", NULL }, + .voidp_sizeof =3D 8, + .bigendian =3D 1,=20 + .id =3D IMAGE_SPARC64_RAW, + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_S= IZE, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + }, + { + .dirname =3D "sparc64-ieee1275", + .names =3D { "sparc64-ieee1275-cdcore", NULL }, + .voidp_sizeof =3D 8, + .bigendian =3D 1,=20 + .id =3D IMAGE_SPARC64_CDCORE, + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_S= IZE, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + }, + { + .dirname =3D "sparc64-ieee1275", + .names =3D { "sparc64-ieee1275-aout", NULL }, + .voidp_sizeof =3D 8, + .bigendian =3D 1, + .id =3D IMAGE_SPARC64_AOUT, + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_S= IZE, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + }, + { + .dirname =3D "ia64-efi", + .names =3D {"ia64-efi", NULL}, + .voidp_sizeof =3D 8, + .bigendian =3D 0,=20 + .id =3D IMAGE_EFI,=20 + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset =3D EFI64_HEADER_SIZE, + .pe_target =3D GRUB_PE32_MACHINE_IA64, + .elf_target =3D EM_IA_64, + }, + { + .dirname =3D "mips-arc", + .names =3D {"mips-arc", NULL}, + .voidp_sizeof =3D 4, + .bigendian =3D 1, + .id =3D IMAGE_MIPS_ARC,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_MIPS_ARC_LINK_ADDR, + .elf_target =3D EM_MIPS, + .link_align =3D GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, + .default_compression =3D GRUB_COMPRESSION_NONE + }, + { + .dirname =3D "mipsel-arc", + .names =3D {"mipsel-arc", NULL}, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_MIPS_ARC,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR, + .elf_target =3D EM_MIPS, + .link_align =3D GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, + .default_compression =3D GRUB_COMPRESSION_NONE + }, + { + .dirname =3D "mipsel-qemu_mips", + .names =3D { "mipsel-qemu_mips-elf", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_LOONGSON_ELF,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZ= E, + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target =3D EM_MIPS, + .link_align =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression =3D GRUB_COMPRESSION_NONE + }, + { + .dirname =3D "mips-qemu_mips", + .names =3D { "mips-qemu_mips-flash", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 1, + .id =3D IMAGE_QEMU_MIPS_FLASH,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZ= E, + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target =3D EM_MIPS, + .link_align =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression =3D GRUB_COMPRESSION_NONE + }, + { + .dirname =3D "mipsel-qemu_mips", + .names =3D { "mipsel-qemu_mips-flash", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_QEMU_MIPS_FLASH,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZ= E, + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target =3D EM_MIPS, + .link_align =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression =3D GRUB_COMPRESSION_NONE + }, + { + .dirname =3D "mips-qemu_mips", + .names =3D { "mips-qemu_mips-elf", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 1, + .id =3D IMAGE_LOONGSON_ELF,=20 + .flags =3D PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size =3D GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZ= E, + .decompressor_compressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSON_= COMPRESSED_SIZE, + .decompressor_uncompressed_size =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr =3D GRUB_DECOMPRESSOR_MIPS_LOONGSO= N_UNCOMPRESSED_ADDR, + .section_align =3D 1, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target =3D EM_MIPS, + .link_align =3D GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression =3D GRUB_COMPRESSION_NONE + }, + { + .dirname =3D "arm-uboot", + .names =3D { "arm-uboot", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0, + .id =3D IMAGE_UBOOT,=20 + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN, + .vaddr_offset =3D 0, + .link_addr =3D GRUB_KERNEL_ARM_UBOOT_LINK_ADDR, + .elf_target =3D EM_ARM, + .mod_gap =3D GRUB_KERNEL_ARM_UBOOT_MOD_GAP, + .mod_align =3D GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN, + .link_align =3D 4 + }, + { + .dirname =3D "arm-efi", + .names =3D { "arm-efi", NULL }, + .voidp_sizeof =3D 4, + .bigendian =3D 0,=20 + .id =3D IMAGE_EFI,=20 + .flags =3D PLATFORM_FLAGS_NONE, + .total_module_size =3D TARGET_NO_FIELD, + .decompressor_compressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_size =3D TARGET_NO_FIELD, + .decompressor_uncompressed_addr =3D TARGET_NO_FIELD, + .section_align =3D GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset =3D ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_head= er) + + 4 * sizeof (struct grub_pe32_section_t= able), + GRUB_PE32_SECTION_ALIGNMENT), + .pe_target =3D GRUB_PE32_MACHINE_ARMTHUMB_MIXED, + .elf_target =3D EM_ARM, + }, + }; + +#define grub_target_to_host32(x) (grub_target_to_host32_real (image_targ= et, (x))) +#define grub_host_to_target32(x) (grub_host_to_target32_real (image_targ= et, (x))) +#define grub_target_to_host64(x) (grub_target_to_host64_real (image_targ= et, (x))) +#define grub_host_to_target64(x) (grub_host_to_target64_real (image_targ= et, (x))) +#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (imag= e_target, (x))) +#define grub_target_to_host16(x) (grub_target_to_host16_real (image_targ= et, (x))) +#define grub_host_to_target16(x) (grub_host_to_target16_real (image_targ= et, (x))) + +static inline grub_uint32_t +grub_target_to_host32_real (struct grub_install_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 grub_install_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_uint64_t +grub_host_to_target64_real (struct grub_install_image_target_desc *image= _target, grub_uint64_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be64 (in); + else + return grub_cpu_to_le64 (in); +} + +static inline grub_uint32_t +grub_host_to_target32_real (struct grub_install_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 grub_install_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 grub_install_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); +} + +static inline grub_uint64_t +grub_host_to_target_addr_real (struct grub_install_image_target_desc *im= age_target, grub_uint64_t in) +{ + if (image_target->voidp_sizeof =3D=3D 8) + return grub_host_to_target64_real (image_target, in); + else + return grub_host_to_target32_real (image_target, in); +} + +static inline grub_uint64_t +grub_target_to_host_real (struct grub_install_image_target_desc *image_t= arget, grub_uint64_t in) +{ + if (image_target->voidp_sizeof =3D=3D 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 + +/* These structures are defined according to the CHRP binding to IEEE127= 5, + "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; +}; + +#define grub_target_to_host(val) grub_target_to_host_real(image_target, = (val)) + +#include + +static void *SzAlloc(void *p, size_t size) { p =3D p; return xmalloc(siz= e); } +static void SzFree(void *p, void *address) { p =3D p; free(address); } +static ISzAlloc g_Alloc =3D { SzAlloc, SzFree }; + +static void +compress_kernel_lzma (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size) +{ + CLzmaEncProps props; + unsigned char out_props[5]; + size_t out_props_size =3D 5; + + LzmaEncProps_Init(&props); + props.dictSize =3D 1 << 16; + props.lc =3D 3; + props.lp =3D 0; + props.pb =3D 2; + props.numThreads =3D 1; + + *core_img =3D xmalloc (kernel_size); + + *core_size =3D kernel_size; + if (LzmaEncode ((unsigned char *) *core_img, core_size, + (unsigned char *) kernel_img, + kernel_size, + &props, out_props, &out_props_size, + 0, NULL, &g_Alloc, &g_Alloc) !=3D SZ_OK) + grub_util_error ("%s", _("cannot compress the kernel image")); +} + +#ifdef HAVE_LIBLZMA +static void +compress_kernel_xz (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size) +{ + lzma_stream strm =3D LZMA_STREAM_INIT; + lzma_ret xzret; + lzma_options_lzma lzopts =3D { + .dict_size =3D 1 << 16, + .preset_dict =3D NULL, + .preset_dict_size =3D 0, + .lc =3D 3, + .lp =3D 0, + .pb =3D 2, + .mode =3D LZMA_MODE_NORMAL, + .nice_len =3D 64, + .mf =3D LZMA_MF_BT4, + .depth =3D 0, + }; + lzma_filter fltrs[] =3D { + { .id =3D LZMA_FILTER_LZMA2, .options =3D &lzopts}, + { .id =3D LZMA_VLI_UNKNOWN, .options =3D NULL} + }; + + xzret =3D lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE); + if (xzret !=3D LZMA_OK) + grub_util_error ("%s", _("cannot compress the kernel image")); + + *core_img =3D xmalloc (kernel_size); + + *core_size =3D kernel_size; + strm.next_in =3D (unsigned char *) kernel_img; + strm.avail_in =3D kernel_size; + strm.next_out =3D (unsigned char *) *core_img; + strm.avail_out =3D *core_size; + + while (1) + { + xzret =3D lzma_code (&strm, LZMA_FINISH); + if (xzret =3D=3D LZMA_OK) + continue; + if (xzret =3D=3D LZMA_STREAM_END) + break; + grub_util_error ("%s", _("cannot compress the kernel image")); + } + + *core_size -=3D strm.avail_out; +} +#endif + +static void +compress_kernel (struct grub_install_image_target_desc *image_target, ch= ar *kernel_img, + size_t kernel_size, char **core_img, size_t *core_size, + grub_compression_t comp) +{ + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp =3D=3D GRUB_COMPRESSION_LZMA)) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size); + return; + } + +#ifdef HAVE_LIBLZMA + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp =3D=3D GRUB_COMPRESSION_XZ)) + { + compress_kernel_xz (kernel_img, kernel_size, core_img, + core_size); + return; + } +#endif + + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp !=3D GRUB_COMPRESSION_NONE)) + grub_util_error (_("unknown compression %d\n"), comp); + + *core_img =3D xmalloc (kernel_size); + memcpy (*core_img, kernel_img, kernel_size); + *core_size =3D kernel_size; +} + +struct fixup_block_list +{ + struct fixup_block_list *next; + int state; + struct grub_pe32_fixup_block b; +}; + +#pragma GCC diagnostic ignored "-Wcast-align" + +#define MKIMAGE_ELF32 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF32 + +#define MKIMAGE_ELF64 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF64 + +struct grub_install_image_target_desc * +grub_install_get_image_target (const char *arg) +{ + unsigned i, j; + for (i =3D 0; i < ARRAY_SIZE (image_targets); i++) + for (j =3D 0; image_targets[i].names[j] + && j < ARRAY_SIZE (image_targets[i].names); j++) + if (strcmp (arg, image_targets[i].names[j]) =3D=3D 0) + return &image_targets[i]; + return NULL; +} + +const char * +grub_util_get_target_dirname (struct grub_install_image_target_desc *t) +{ + return t->dirname; +} + + +char * +grub_install_get_image_targets_string (void) +{ + int format_len =3D 0; + char *formats; + char *ptr; + unsigned i; + for (i =3D 0; i < ARRAY_SIZE (image_targets); i++) + format_len +=3D strlen (image_targets[i].names[0]) + 2; + ptr =3D formats =3D xmalloc (format_len); + for (i =3D 0; i < ARRAY_SIZE (image_targets); i++) + { + strcpy (ptr, image_targets[i].names[0]); + ptr +=3D strlen (image_targets[i].names[0]); + *ptr++ =3D ','; + *ptr++ =3D ' '; + } + ptr[-2] =3D 0; + + return formats; +} + +void +grub_install_generate_image (const char *dir, const char *prefix, + FILE *out, const char *outname, char *mods[], + char *memdisk_path, char **pubkey_paths, size_t npubkeys, + char *config_path, struct grub_install_image_target_desc *image_= target, int note, + grub_compression_t comp) +{ + char *kernel_img, *core_img; + size_t kernel_size, total_module_size, core_size, exec_size; + size_t memdisk_size =3D 0, config_size =3D 0, config_size_pure =3D 0; + size_t prefix_size =3D 0; + char *kernel_path; + size_t offset; + struct grub_util_path_list *path_list, *p, *next; + grub_size_t bss_size; + grub_uint64_t start_address; + void *rel_section =3D 0; + grub_size_t reloc_size =3D 0, align; + size_t decompress_size =3D 0; + + if (comp =3D=3D GRUB_COMPRESSION_AUTO) + comp =3D image_target->default_compression; + + if (image_target->id =3D=3D IMAGE_I386_PC + || image_target->id =3D=3D IMAGE_I386_PC_PXE) + comp =3D GRUB_COMPRESSION_LZMA; + + path_list =3D grub_util_resolve_dependencies (dir, "moddep.lst", mods)= ; + + kernel_path =3D grub_util_get_path (dir, "kernel.img"); + + if (image_target->voidp_sizeof =3D=3D 8) + total_module_size =3D sizeof (struct grub_module_info64); + else + total_module_size =3D sizeof (struct grub_module_info32); + + { + size_t i; + for (i =3D 0; i < npubkeys; i++) + { + size_t curs; + curs =3D ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i])); + grub_util_info ("the size of public key %zd is 0x%llx", + i, (unsigned long long) curs); + total_module_size +=3D curs + sizeof (struct grub_module_header); + } + } + + if (memdisk_path) + { + memdisk_size =3D ALIGN_UP(grub_util_get_image_size (memdisk_path),= 512); + grub_util_info ("the size of memory disk is 0x%llx", + (unsigned long long) memdisk_size); + total_module_size +=3D memdisk_size + sizeof (struct grub_module_h= eader); + } + + if (config_path) + { + config_size_pure =3D grub_util_get_image_size (config_path) + 1; + config_size =3D ALIGN_ADDR (config_size_pure); + grub_util_info ("the size of config file is 0x%llx", + (unsigned long long) config_size); + total_module_size +=3D config_size + sizeof (struct grub_module_he= ader); + } + + if (prefix) + { + prefix_size =3D ALIGN_ADDR (strlen (prefix) + 1); + total_module_size +=3D prefix_size + sizeof (struct grub_module_he= ader); + } + + for (p =3D path_list; p; p =3D p->next) + total_module_size +=3D (ALIGN_ADDR (grub_util_get_image_size (p->nam= e)) + + sizeof (struct grub_module_header)); + + grub_util_info ("the total module size is 0x%llx", + (unsigned long long) total_module_size); + + if (image_target->voidp_sizeof =3D=3D 4) + kernel_img =3D load_image32 (kernel_path, &exec_size, &kernel_size, = &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, &align, image_target); + else + kernel_img =3D load_image64 (kernel_path, &exec_size, &kernel_size, = &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, &align, image_target); + + if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + && (image_target->total_module_size !=3D TARGET_NO_FIELD)) + *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) + =3D grub_host_to_target32 (total_module_size); + + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + memmove (kernel_img + total_module_size, kernel_img, kernel_size); + + if (image_target->voidp_sizeof =3D=3D 8) + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info64 *modinfo; + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + modinfo =3D (struct grub_module_info64 *) kernel_img; + else + modinfo =3D (struct grub_module_info64 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info64)); + modinfo->magic =3D grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset =3D grub_host_to_target_addr (sizeof (struct grub_= module_info64)); + modinfo->size =3D grub_host_to_target_addr (total_module_size); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + offset =3D sizeof (struct grub_module_info64); + else + offset =3D kernel_size + sizeof (struct grub_module_info64); + } + else + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info32 *modinfo; + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + modinfo =3D (struct grub_module_info32 *) kernel_img; + else + modinfo =3D (struct grub_module_info32 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info32)); + modinfo->magic =3D grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset =3D grub_host_to_target_addr (sizeof (struct grub_= module_info32)); + modinfo->size =3D grub_host_to_target_addr (total_module_size); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + offset =3D sizeof (struct grub_module_info32); + else + offset =3D kernel_size + sizeof (struct grub_module_info32); + } + + for (p =3D path_list; p; p =3D p->next) + { + struct grub_module_header *header; + size_t mod_size, orig_size; + + orig_size =3D grub_util_get_image_size (p->name); + mod_size =3D ALIGN_ADDR (orig_size); + + header =3D (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type =3D grub_host_to_target32 (OBJ_TYPE_ELF); + header->size =3D grub_host_to_target32 (mod_size + sizeof (*header= )); + offset +=3D sizeof (*header); + memset (kernel_img + offset + orig_size, 0, mod_size - orig_size);= + + grub_util_load_image (p->name, kernel_img + offset); + offset +=3D mod_size; + } + + { + size_t i; + for (i =3D 0; i < npubkeys; i++) + { + size_t curs; + struct grub_module_header *header; + + curs =3D grub_util_get_image_size (pubkey_paths[i]); + + header =3D (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type =3D grub_host_to_target32 (OBJ_TYPE_PUBKEY); + header->size =3D grub_host_to_target32 (curs + sizeof (*header)); + offset +=3D sizeof (*header); + + grub_util_load_image (pubkey_paths[i], kernel_img + offset); + offset +=3D ALIGN_ADDR (curs); + } + } + + if (memdisk_path) + { + struct grub_module_header *header; + + header =3D (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type =3D grub_host_to_target32 (OBJ_TYPE_MEMDISK); + header->size =3D grub_host_to_target32 (memdisk_size + sizeof (*he= ader)); + offset +=3D sizeof (*header); + + grub_util_load_image (memdisk_path, kernel_img + offset); + offset +=3D memdisk_size; + } + + if (config_path) + { + struct grub_module_header *header; + + header =3D (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type =3D grub_host_to_target32 (OBJ_TYPE_CONFIG); + header->size =3D grub_host_to_target32 (config_size + sizeof (*hea= der)); + offset +=3D sizeof (*header); + + grub_util_load_image (config_path, kernel_img + offset); + *(kernel_img + offset + config_size_pure - 1) =3D 0; + offset +=3D config_size; + } + + if (prefix) + { + struct grub_module_header *header; + + header =3D (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type =3D grub_host_to_target32 (OBJ_TYPE_PREFIX); + header->size =3D grub_host_to_target32 (prefix_size + sizeof (*hea= der)); + offset +=3D sizeof (*header); + + grub_memset (kernel_img + offset, 0, prefix_size); + grub_strcpy (kernel_img + offset, prefix); + offset +=3D prefix_size; + } + + grub_util_info ("kernel_img=3D%p, kernel_size=3D0x%llx", kernel_img, + (unsigned long long) kernel_size); + compress_kernel (image_target, kernel_img, kernel_size + total_module_= size, + &core_img, &core_size, comp); + free (kernel_img); + + grub_util_info ("the core size is 0x%llx", (unsigned long long) core_s= ize); + + if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)=20 + && image_target->total_module_size !=3D TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) + =3D grub_host_to_target32 (total_module_size); + + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + { + char *full_img; + size_t full_size; + char *decompress_path, *decompress_img; + const char *name; + + switch (comp) + { + case GRUB_COMPRESSION_XZ: + name =3D "xz_decompress.img"; + break; + case GRUB_COMPRESSION_LZMA: + name =3D "lzma_decompress.img"; + break; + case GRUB_COMPRESSION_NONE: + name =3D "none_decompress.img"; + break; + default: + grub_util_error (_("unknown compression %d\n"), comp); + } + =20 + decompress_path =3D grub_util_get_path (dir, name); + decompress_size =3D grub_util_get_image_size (decompress_path); + decompress_img =3D grub_util_read_image (decompress_path); + + if ((image_target->id =3D=3D IMAGE_I386_PC + || image_target->id =3D=3D IMAGE_I386_PC_PXE) + && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200) + grub_util_error ("%s", _("Decompressor is too big")); + + if (image_target->decompressor_compressed_size !=3D TARGET_NO_FIEL= D) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_compressed_size)) + =3D grub_host_to_target32 (core_size); + + if (image_target->decompressor_uncompressed_size !=3D TARGET_NO_FI= ELD) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_uncompressed_size)) + =3D grub_host_to_target32 (kernel_size + total_module_size); + + if (image_target->decompressor_uncompressed_addr !=3D TARGET_NO_FI= ELD) + { + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + *((grub_uint32_t *) (decompress_img + image_target->decompressor_un= compressed_addr)) + =3D grub_host_to_target_addr (image_target->link_addr - total_mod= ule_size); + else + *((grub_uint32_t *) (decompress_img + image_target->decompressor_un= compressed_addr)) + =3D grub_host_to_target_addr (image_target->link_addr); + } + full_size =3D core_size + decompress_size; + + full_img =3D xmalloc (full_size); + memset (full_img, 0, full_size);=20 + + memcpy (full_img, decompress_img, decompress_size); + + memcpy (full_img + decompress_size, core_img, core_size); + + memset (full_img + decompress_size + core_size, 0, + full_size - (decompress_size + core_size)); + + free (core_img); + core_img =3D full_img; + core_size =3D full_size; + } + + switch (image_target->id) + { + case IMAGE_I386_PC: + case IMAGE_I386_PC_PXE: + if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000 + || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS)) + || (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x6800= 0)) + grub_util_error (_("core image is too big (0x%x > 0x%x)"), + GRUB_KERNEL_I386_PC_LINK_ADDR + (unsigned) core_size, + 0x78000); + /* fallthrough */ + case IMAGE_COREBOOT: + case IMAGE_QEMU: + if (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000) + grub_util_error (_("kernel image is too big (0x%x > 0x%x)"), + (unsigned) kernel_size + (unsigned) bss_size + + GRUB_KERNEL_I386_PC_LINK_ADDR, + 0x68000); + break; + case IMAGE_LOONGSON_ELF: + case IMAGE_YEELOONG_FLASH: + case IMAGE_FULOONG2F_FLASH: + case IMAGE_EFI: + case IMAGE_MIPS_ARC: + case IMAGE_QEMU_MIPS_FLASH: + break; + case IMAGE_SPARC64_AOUT: + case IMAGE_SPARC64_RAW: + case IMAGE_SPARC64_CDCORE: + case IMAGE_I386_IEEE1275: + case IMAGE_PPC: + case IMAGE_UBOOT: + break; + } + + switch (image_target->id) + { + case IMAGE_I386_PC: + case IMAGE_I386_PC_PXE: + { + unsigned num; + char *boot_path, *boot_img; + size_t boot_size; + + num =3D ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BI= TS); + if (image_target->id =3D=3D IMAGE_I386_PC_PXE) + { + char *pxeboot_path, *pxeboot_img; + size_t pxeboot_size; + grub_uint32_t *ptr; + =20 + pxeboot_path =3D grub_util_get_path (dir, "pxeboot.img"); + pxeboot_size =3D grub_util_get_image_size (pxeboot_path); + pxeboot_img =3D grub_util_read_image (pxeboot_path); + =20 + grub_util_write_image (pxeboot_img, pxeboot_size, out, + outname); + free (pxeboot_img); + free (pxeboot_path); + + /* Remove Multiboot header to avoid confusing ipxe. */ + for (ptr =3D (grub_uint32_t *) core_img; + ptr < (grub_uint32_t *) (core_img + MULTIBOOT_SEARCH); ptr++) + if (*ptr =3D=3D grub_host_to_target32 (MULTIBOOT_HEADER_MAGIC) + && grub_target_to_host32 (ptr[0]) + + grub_target_to_host32 (ptr[1]) + + grub_target_to_host32 (ptr[2]) =3D=3D 0) + { + *ptr =3D 0; + break; + } + } + + boot_path =3D grub_util_get_path (dir, "diskboot.img"); + boot_size =3D grub_util_get_image_size (boot_path); + if (boot_size !=3D GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); + + boot_img =3D grub_util_read_image (boot_path); + + { + struct grub_pc_bios_boot_blocklist *block; + block =3D (struct grub_pc_bios_boot_blocklist *) (boot_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + block->len =3D grub_host_to_target16 (num); + + /* This is filled elsewhere. Verify it just in case. */ + assert (block->segment + =3D=3D grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG + + (GRUB_DISK_SECTOR_SIZE >> 4))); + } + + grub_util_write_image (boot_img, boot_size, out, outname); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_EFI: + { + 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; + struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] =3D GRUB_PE32_MSDOS_STUB; + int header_size; + int reloc_addr; + + if (image_target->voidp_sizeof =3D=3D 4) + header_size =3D EFI32_HEADER_SIZE; + else + header_size =3D EFI64_HEADER_SIZE; + + reloc_addr =3D ALIGN_UP (header_size + core_size, + image_target->section_align); + + pe_size =3D ALIGN_UP (reloc_addr + reloc_size, + image_target->section_align); + pe_img =3D xmalloc (reloc_addr + reloc_size); + memset (pe_img, 0, header_size); + memcpy ((char *) pe_img + header_size, core_img, core_size); + memcpy ((char *) pe_img + reloc_addr, rel_section, reloc_size); + header =3D pe_img; + + /* The magic. */ + 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 =3D (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_S= IZE + + GRUB_PE32_SIGNATURE_SIZE); + c->machine =3D grub_host_to_target16 (image_target->pe_target); + + c->num_sections =3D grub_host_to_target16 (4); + c->time =3D grub_host_to_target32 (time (0)); + c->characteristics =3D grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAG= E + | GRUB_PE32_LINE_NUMS_STRIPPED + | ((image_target->voidp_sizeof =3D=3D 4) + ? GRUB_PE32_32BIT_MACHINE + : 0) + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + if (image_target->voidp_sizeof =3D=3D 4) + { + struct grub_pe32_optional_header *o; + + c->optional_header_size =3D grub_host_to_target16 (sizeof (struct g= rub_pe32_optional_header)); + + o =3D (struct grub_pe32_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o->magic =3D grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size =3D grub_host_to_target32 (exec_size); + o->data_size =3D grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); + o->bss_size =3D grub_cpu_to_le32 (bss_size); + o->entry_addr =3D grub_cpu_to_le32 (start_address); + o->code_base =3D grub_cpu_to_le32 (header_size); + + o->data_base =3D grub_host_to_target32 (header_size + exec_size); + + o->image_base =3D 0; + o->section_alignment =3D grub_host_to_target32 (image_target->secti= on_align); + o->file_alignment =3D grub_host_to_target32 (image_target->section_= align); + o->image_size =3D grub_host_to_target32 (pe_size); + o->header_size =3D grub_host_to_target32 (header_size); + o->subsystem =3D grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APP= LICATION); + + /* Do these really matter? */ + o->stack_reserve_size =3D grub_host_to_target32 (0x10000); + o->stack_commit_size =3D grub_host_to_target32 (0x10000); + o->heap_reserve_size =3D grub_host_to_target32 (0x10000); + o->heap_commit_size =3D grub_host_to_target32 (0x10000); + =20 + o->num_data_directories =3D grub_host_to_target32 (GRUB_PE32_NUM_DA= TA_DIRECTORIES); + + o->base_relocation_table.rva =3D grub_host_to_target32 (reloc_addr)= ; + o->base_relocation_table.size =3D grub_host_to_target32 (reloc_size= ); + sections =3D o + 1; + } + else + { + struct grub_pe64_optional_header *o; + + c->optional_header_size =3D grub_host_to_target16 (sizeof (struct g= rub_pe64_optional_header)); + + o =3D (struct grub_pe64_optional_header *)=20 + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o->magic =3D grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); + o->code_size =3D grub_host_to_target32 (exec_size); + o->data_size =3D grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); + o->bss_size =3D grub_cpu_to_le32 (bss_size); + o->entry_addr =3D grub_cpu_to_le32 (start_address); + o->code_base =3D grub_cpu_to_le32 (header_size); + o->image_base =3D 0; + o->section_alignment =3D grub_host_to_target32 (image_target->secti= on_align); + o->file_alignment =3D grub_host_to_target32 (image_target->section_= align); + o->image_size =3D grub_host_to_target32 (pe_size); + o->header_size =3D grub_host_to_target32 (header_size); + o->subsystem =3D grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APP= LICATION); + + /* Do these really matter? */ + o->stack_reserve_size =3D grub_host_to_target64 (0x10000); + o->stack_commit_size =3D grub_host_to_target64 (0x10000); + o->heap_reserve_size =3D grub_host_to_target64 (0x10000); + o->heap_commit_size =3D grub_host_to_target64 (0x10000); + =20 + o->num_data_directories + =3D grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva =3D grub_host_to_target32 (reloc_addr)= ; + o->base_relocation_table.size =3D grub_host_to_target32 (reloc_size= ); + sections =3D o + 1; + } + /* The sections. */ + text_section =3D sections; + strcpy (text_section->name, ".text"); + text_section->virtual_size =3D grub_cpu_to_le32 (exec_size); + text_section->virtual_address =3D grub_cpu_to_le32 (header_size); + text_section->raw_data_size =3D grub_cpu_to_le32 (exec_size); + text_section->raw_data_offset =3D grub_cpu_to_le32 (header_size); + text_section->characteristics =3D grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_C= ODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ); + + data_section =3D text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size =3D grub_cpu_to_le32 (kernel_size - exec_siz= e); + data_section->virtual_address =3D grub_cpu_to_le32 (header_size + exec_= size); + data_section->raw_data_size =3D grub_cpu_to_le32 (kernel_size - exec_si= ze); + data_section->raw_data_offset =3D grub_cpu_to_le32 (header_size + exec_= size); + data_section->characteristics + =3D grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + +#if 0 + bss_section =3D data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size =3D grub_cpu_to_le32 (bss_size); + bss_section->virtual_address =3D grub_cpu_to_le32 (header_size + kernel= _size); + bss_section->raw_data_size =3D 0; + bss_section->raw_data_offset =3D 0; + bss_section->characteristics + =3D 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 + =20 + mods_section =3D data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size =3D grub_cpu_to_le32 (reloc_addr - kernel_si= ze - header_size); + mods_section->virtual_address =3D grub_cpu_to_le32 (header_size + kerne= l_size + bss_size); + mods_section->raw_data_size =3D grub_cpu_to_le32 (reloc_addr - kernel_s= ize - header_size); + mods_section->raw_data_offset =3D grub_cpu_to_le32 (header_size + kerne= l_size); + mods_section->characteristics + =3D grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + + reloc_section =3D mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size =3D grub_cpu_to_le32 (reloc_size); + reloc_section->virtual_address =3D grub_cpu_to_le32 (reloc_addr + bss_s= ize); + reloc_section->raw_data_size =3D grub_cpu_to_le32 (reloc_size); + reloc_section->raw_data_offset =3D grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + =3D 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 =3D pe_img; + core_size =3D pe_size; + } + break; + case IMAGE_QEMU: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; + + boot_path =3D grub_util_get_path (dir, "boot.img"); + boot_size =3D grub_util_get_image_size (boot_path); + boot_img =3D grub_util_read_image (boot_path); + + /* Rom sizes must be 64k-aligned. */ + rom_size =3D ALIGN_UP (core_size + boot_size, 64 * 1024); + + rom_img =3D xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + =3D grub_host_to_target32 ((grub_uint32_t) -rom_size); + + memcpy (rom_img, core_img, core_size); + + *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR)) + =3D grub_host_to_target32 ((grub_uint32_t) -rom_size); + + memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); + + free (core_img); + core_img =3D rom_img; + core_size =3D rom_size; + + 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 =3D core_size + sizeof (*aout_head); + aout_img =3D xmalloc (aout_size); + aout_head =3D aout_img; + grub_memset (aout_head, 0, sizeof (*aout_head)); + aout_head->a_midmag =3D grub_host_to_target32 ((AOUT_MID_SUN << 16) + | AOUT32_OMAGIC); + aout_head->a_text =3D grub_host_to_target32 (core_size); + aout_head->a_entry + =3D grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS);= + memcpy ((char *) aout_img + sizeof (*aout_head), core_img, core_size); + + free (core_img); + core_img =3D aout_img; + core_size =3D aout_size; + } + break; + case IMAGE_SPARC64_RAW: + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; + + num =3D ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BI= TS); + num <<=3D GRUB_DISK_SECTOR_BITS; + + boot_path =3D grub_util_get_path (dir, "diskboot.img"); + boot_size =3D grub_util_get_image_size (boot_path); + if (boot_size !=3D GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); + + boot_img =3D grub_util_read_image (boot_path); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8)) + =3D grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out, outname); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_CDCORE: + break; + case IMAGE_YEELOONG_FLASH: + case IMAGE_FULOONG2F_FLASH: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; + grub_uint8_t context[GRUB_MD_SHA512->contextsize]; + /* fwstart.img is the only part which can't be tested by using *-e= lf + target. Check it against the checksum. */ + const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] =3D=20 + { + 0x5f, 0x67, 0x46, 0x57, 0x31, 0x30, 0xc5, 0x0a, + 0xe9, 0x98, 0x18, 0xc9, 0xf3, 0xca, 0x45, 0xa5, + 0x75, 0x64, 0x6b, 0xbb, 0x24, 0xcd, 0xb4, 0xbc, + 0xf2, 0x3e, 0x23, 0xf9, 0xc2, 0x6a, 0x8c, 0xde, + 0x3b, 0x94, 0x9c, 0xcc, 0xa5, 0xa7, 0x58, 0xb1, + 0xbe, 0x8b, 0x3d, 0x73, 0x98, 0x18, 0x7e, 0x68, + 0x5e, 0x5f, 0x23, 0x7d, 0x7a, 0xe8, 0x51, 0xf7, + 0x1a, 0xaf, 0x2f, 0x54, 0x11, 0x2e, 0x5c, 0x25 + }; + const grub_uint8_t fuloong2f_fwstart_good_hash[512 / 8] =3D=20 + {=20 + 0x76, 0x9b, 0xad, 0x6e, 0xa2, 0x39, 0x47, 0x62, + 0x1f, 0xc9, 0x3a, 0x6d, 0x05, 0x5c, 0x43, 0x5c, + 0x29, 0x4a, 0x7e, 0x08, 0x2a, 0x31, 0x8f, 0x5d, + 0x02, 0x84, 0xa0, 0x85, 0xf2, 0xd1, 0xb9, 0x53, + 0xa2, 0xbc, 0xf2, 0xe1, 0x39, 0x1e, 0x51, 0xb5, + 0xaf, 0xec, 0x9e, 0xf2, 0xf1, 0xf3, 0x0a, 0x2f, + 0xe6, 0xf1, 0x08, 0x89, 0xbe, 0xbc, 0x73, 0xab, + 0x46, 0x50, 0xd6, 0x21, 0xce, 0x8e, 0x24, 0xa7 + }; + const grub_uint8_t *fwstart_good_hash; + =20 + if (image_target->id =3D=3D IMAGE_FULOONG2F_FLASH) + { + fwstart_good_hash =3D fuloong2f_fwstart_good_hash; + boot_path =3D grub_util_get_path (dir, "fwstart_fuloong2f.img"); + } + else + { + fwstart_good_hash =3D yeeloong_fwstart_good_hash; + boot_path =3D grub_util_get_path (dir, "fwstart.img"); + } + + boot_size =3D grub_util_get_image_size (boot_path); + boot_img =3D grub_util_read_image (boot_path); + + grub_memset (context, 0, sizeof (context)); + GRUB_MD_SHA512->init (context); + GRUB_MD_SHA512->write (context, boot_img, boot_size); + GRUB_MD_SHA512->final (context); + if (grub_memcmp (GRUB_MD_SHA512->read (context), fwstart_good_hash= , + GRUB_MD_SHA512->mdlen) !=3D 0) + /* TRANSLATORS: fwstart.img may still be good, just it wasn't checked. = */ + grub_util_warn ("%s", + _("fwstart.img doesn't match the known good version. " + "proceed at your own risk")); + + if (core_size + boot_size > 512 * 1024) + grub_util_error ("%s", _("firmware image is too big")); + rom_size =3D 512 * 1024; + + rom_img =3D xmalloc (rom_size); + memset (rom_img, 0, rom_size);=20 + + memcpy (rom_img, boot_img, boot_size); + + memcpy (rom_img + boot_size, core_img, core_size); + + memset (rom_img + boot_size + core_size, 0, + rom_size - (boot_size + core_size)); + + free (core_img); + core_img =3D rom_img; + core_size =3D rom_size; + } + break; + case IMAGE_QEMU_MIPS_FLASH: + { + char *rom_img; + size_t rom_size; + + if (core_size > 512 * 1024) + grub_util_error ("%s", _("firmware image is too big")); + rom_size =3D 512 * 1024; + + rom_img =3D xmalloc (rom_size); + memset (rom_img, 0, rom_size);=20 + + memcpy (rom_img, core_img, core_size); + + memset (rom_img + core_size, 0, + rom_size - core_size); + + free (core_img); + core_img =3D rom_img; + core_size =3D rom_size; + } + break; + + case IMAGE_UBOOT: + { + struct grub_uboot_image_header *hdr; + GRUB_PROPERLY_ALIGNED_ARRAY (crc32_context, GRUB_MD_CRC32->context= size); + + hdr =3D xmalloc (core_size + sizeof (struct grub_uboot_image_heade= r)); + memcpy (hdr + 1, core_img, core_size); + + memset (hdr, 0, sizeof (*hdr)); + hdr->ih_magic =3D grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAG= IC); + hdr->ih_time =3D grub_cpu_to_be32 (time (0)); + hdr->ih_size =3D grub_cpu_to_be32 (core_size); + hdr->ih_load =3D grub_cpu_to_be32 (image_target->link_addr); + hdr->ih_ep =3D grub_cpu_to_be32 (image_target->link_addr); + hdr->ih_type =3D GRUB_UBOOT_IH_TYPE_KERNEL; + hdr->ih_os =3D GRUB_UBOOT_IH_OS_LINUX; + hdr->ih_arch =3D GRUB_UBOOT_IH_ARCH_ARM; + hdr->ih_comp =3D GRUB_UBOOT_IH_COMP_NONE; + + GRUB_MD_CRC32->init(crc32_context); + GRUB_MD_CRC32->write(crc32_context, hdr + 1, core_size); + GRUB_MD_CRC32->final(crc32_context); + hdr->ih_dcrc =3D grub_get_unaligned32 (GRUB_MD_CRC32->read (crc32_= context)); + + GRUB_MD_CRC32->init(crc32_context); + GRUB_MD_CRC32->write(crc32_context, hdr, sizeof (*hdr)); + GRUB_MD_CRC32->final(crc32_context); + hdr->ih_hcrc =3D grub_get_unaligned32 (GRUB_MD_CRC32->read (crc32_= context)); + + free (core_img); + core_img =3D (char *) hdr; + core_size +=3D sizeof (struct grub_uboot_image_header); + } + break; + + case IMAGE_MIPS_ARC: + { + char *ecoff_img; + struct ecoff_header { + grub_uint16_t magic; + grub_uint16_t nsec; + grub_uint32_t time; + grub_uint32_t syms; + grub_uint32_t nsyms; + grub_uint16_t opt; + grub_uint16_t flags; + grub_uint16_t magic2; + grub_uint16_t version; + grub_uint32_t textsize; + grub_uint32_t datasize; + grub_uint32_t bsssize; + grub_uint32_t entry; + grub_uint32_t text_start; + grub_uint32_t data_start; + grub_uint32_t bss_start; + grub_uint32_t gprmask; + grub_uint32_t cprmask[4]; + grub_uint32_t gp_value; + }; + struct ecoff_section + { + char name[8]; + grub_uint32_t paddr; + grub_uint32_t vaddr; + grub_uint32_t size; + grub_uint32_t file_offset; + grub_uint32_t reloc; + grub_uint32_t gp; + grub_uint16_t nreloc; + grub_uint16_t ngp; + grub_uint32_t flags; + }; + struct ecoff_header *head; + struct ecoff_section *section; + grub_uint32_t target_addr; + size_t program_size; + + program_size =3D ALIGN_ADDR (core_size); + if (comp =3D=3D GRUB_COMPRESSION_NONE) + target_addr =3D (image_target->link_addr - decompress_size); + else + target_addr =3D ALIGN_UP (image_target->link_addr + + kernel_size + total_module_size, 32); + + ecoff_img =3D xmalloc (program_size + sizeof (*head) + sizeof (*section= )); + grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*sec= tion)); + head =3D (void *) ecoff_img; + section =3D (void *) (head + 1); + head->magic =3D image_target->bigendian ? grub_host_to_target16 (0x160)= + : grub_host_to_target16 (0x166); + head->nsec =3D grub_host_to_target16 (1); + head->time =3D grub_host_to_target32 (0); + head->opt =3D grub_host_to_target16 (0x38); + head->flags =3D image_target->bigendian + ? grub_host_to_target16 (0x207) + : grub_host_to_target16 (0x103); + head->magic2 =3D grub_host_to_target16 (0x107); + head->textsize =3D grub_host_to_target32 (program_size); + head->entry =3D grub_host_to_target32 (target_addr); + head->text_start =3D grub_host_to_target32 (target_addr); + head->data_start =3D grub_host_to_target32 (target_addr + program_size)= ; + grub_memcpy (section->name, ".text", sizeof (".text") - 1);=20 + section->vaddr =3D grub_host_to_target32 (target_addr); + section->size =3D grub_host_to_target32 (program_size); + section->file_offset =3D grub_host_to_target32 (sizeof (*head) + sizeof= (*section)); + if (!image_target->bigendian) + { + section->paddr =3D grub_host_to_target32 (0xaa60); + section->flags =3D grub_host_to_target32 (0x20); + } + memcpy (section + 1, core_img, core_size); + free (core_img); + core_img =3D ecoff_img; + core_size =3D program_size + sizeof (*head) + sizeof (*section); + } + break; + case IMAGE_LOONGSON_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 =3D 0; + int phnum =3D 1; +=09 + if (image_target->id !=3D IMAGE_LOONGSON_ELF) + phnum +=3D 2; + + if (note) + { + phnum++; + footer_size +=3D sizeof (struct grub_ieee1275_note); + } + header_size =3D ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); + + program_size =3D ALIGN_ADDR (core_size); + + elf_img =3D 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 =3D (void *) elf_img; + phdr =3D (void *) (elf_img + sizeof (*ehdr)); + memcpy (ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] =3D ELFCLASS32; + if (!image_target->bigendian) + ehdr->e_ident[EI_DATA] =3D ELFDATA2LSB; + else + ehdr->e_ident[EI_DATA] =3D ELFDATA2MSB; + ehdr->e_ident[EI_VERSION] =3D EV_CURRENT; + ehdr->e_ident[EI_OSABI] =3D ELFOSABI_NONE; + ehdr->e_type =3D grub_host_to_target16 (ET_EXEC); + ehdr->e_machine =3D grub_host_to_target16 (image_target->elf_target); + ehdr->e_version =3D grub_host_to_target32 (EV_CURRENT); + + ehdr->e_phoff =3D grub_host_to_target32 ((char *) phdr - (char *) ehdr)= ; + ehdr->e_phentsize =3D grub_host_to_target16 (sizeof (*phdr)); + ehdr->e_phnum =3D grub_host_to_target16 (phnum); + + /* No section headers. */ + ehdr->e_shoff =3D grub_host_to_target32 (0); + if (image_target->id =3D=3D IMAGE_LOONGSON_ELF) + ehdr->e_shentsize =3D grub_host_to_target16 (0); + else + ehdr->e_shentsize =3D grub_host_to_target16 (sizeof (Elf32_Shdr)); + ehdr->e_shnum =3D grub_host_to_target16 (0); + ehdr->e_shstrndx =3D grub_host_to_target16 (0); + + ehdr->e_ehsize =3D grub_host_to_target16 (sizeof (*ehdr)); + + phdr->p_type =3D grub_host_to_target32 (PT_LOAD); + phdr->p_offset =3D grub_host_to_target32 (header_size); + phdr->p_flags =3D grub_host_to_target32 (PF_R | PF_W | PF_X); + + if (image_target->id =3D=3D IMAGE_LOONGSON_ELF) + { + if (comp =3D=3D GRUB_COMPRESSION_NONE) + target_addr =3D (image_target->link_addr - decompress_size); + else + target_addr =3D ALIGN_UP (image_target->link_addr + + kernel_size + total_module_size, 32); + } + else + target_addr =3D image_target->link_addr; + ehdr->e_entry =3D grub_host_to_target32 (target_addr); + phdr->p_vaddr =3D grub_host_to_target32 (target_addr); + phdr->p_paddr =3D grub_host_to_target32 (target_addr); + phdr->p_align =3D grub_host_to_target32 (align > image_target->link_ali= gn ? align : image_target->link_align); + if (image_target->id =3D=3D IMAGE_LOONGSON_ELF) + ehdr->e_flags =3D grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER=20 + | EF_MIPS_PIC | EF_MIPS_CPIC); + else + ehdr->e_flags =3D 0; + if (image_target->id =3D=3D IMAGE_LOONGSON_ELF) + { + phdr->p_filesz =3D grub_host_to_target32 (core_size); + phdr->p_memsz =3D grub_host_to_target32 (core_size); + } + else + { + grub_uint32_t target_addr_mods; + phdr->p_filesz =3D grub_host_to_target32 (kernel_size); + phdr->p_memsz =3D grub_host_to_target32 (kernel_size + bss_size); + + phdr++; + phdr->p_type =3D grub_host_to_target32 (PT_GNU_STACK); + phdr->p_offset =3D grub_host_to_target32 (header_size + kernel_size= ); + phdr->p_paddr =3D phdr->p_vaddr =3D phdr->p_filesz =3D phdr->p_mems= z =3D 0; + phdr->p_flags =3D grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_align =3D grub_host_to_target32 (image_target->link_align);= + + phdr++; + phdr->p_type =3D grub_host_to_target32 (PT_LOAD); + phdr->p_offset =3D grub_host_to_target32 (header_size + kernel_size= ); + phdr->p_flags =3D grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_filesz =3D phdr->p_memsz + =3D grub_host_to_target32 (core_size - kernel_size); + + if (image_target->id =3D=3D IMAGE_COREBOOT) + target_addr_mods =3D GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR; + else + target_addr_mods =3D ALIGN_UP (target_addr + kernel_size + bss_si= ze + + image_target->mod_gap, + image_target->mod_align); + phdr->p_vaddr =3D grub_host_to_target32 (target_addr_mods); + phdr->p_paddr =3D grub_host_to_target32 (target_addr_mods); + phdr->p_align =3D grub_host_to_target32 (image_target->link_align);= + } + + if (note) + { + int note_size =3D sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note_ptr =3D (struct grub_ieee1275_note = *)=20 + (elf_img + program_size + header_size); + + grub_util_info ("adding CHRP NOTE segment"); + + note_ptr->header.namesz =3D grub_host_to_target32 (sizeof (GRUB_IEE= E1275_NOTE_NAME)); + note_ptr->header.descsz =3D grub_host_to_target32 (note_size); + note_ptr->header.type =3D grub_host_to_target32 (GRUB_IEEE1275_NOTE= _TYPE); + strcpy (note_ptr->header.name, GRUB_IEEE1275_NOTE_NAME); + note_ptr->descriptor.real_mode =3D grub_host_to_target32 (0xfffffff= f); + note_ptr->descriptor.real_base =3D grub_host_to_target32 (0x00c0000= 0); + note_ptr->descriptor.real_size =3D grub_host_to_target32 (0xfffffff= f); + note_ptr->descriptor.virt_base =3D grub_host_to_target32 (0xfffffff= f); + note_ptr->descriptor.virt_size =3D grub_host_to_target32 (0xfffffff= f); + note_ptr->descriptor.load_base =3D grub_host_to_target32 (0x0000400= 0); + + phdr++; + phdr->p_type =3D grub_host_to_target32 (PT_NOTE); + phdr->p_flags =3D grub_host_to_target32 (PF_R); + phdr->p_align =3D grub_host_to_target32 (image_target->voidp_sizeof= ); + phdr->p_vaddr =3D 0; + phdr->p_paddr =3D 0; + phdr->p_filesz =3D grub_host_to_target32 (note_size); + phdr->p_memsz =3D 0; + phdr->p_offset =3D grub_host_to_target32 (header_size + program_siz= e); + } + + free (core_img); + core_img =3D elf_img; + core_size =3D program_size + header_size + footer_size; + } + break; + } + + grub_util_write_image (core_img, core_size, out, outname); + free (core_img); + free (kernel_path); + + while (path_list) + { + next =3D path_list->next; + free ((void *) path_list->name); + free (path_list); + path_list =3D next; + } +} + +=0C =3D=3D=3D added file 'util/setup.c' --- util/setup.c 1970-01-01 00:00:00 +0000 +++ util/setup.c 2013-10-04 02:06:06 +0000 @@ -0,0 +1,987 @@ +/* grub-setup.c - make GRUB usable */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009= ,2010,2011 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 +#ifdef GRUB_SETUP_SPARC64 +#include +#include +#include +#else +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "progname.h" +#include +#include +#include +#include + +#ifdef __linux__ +#include +#include +#include +#endif + +#include + +/* On SPARC this program fills in various fields inside of the 'boot' an= d 'core' + * image files. + * + * The 'boot' image needs to know the OBP path name of the root + * device. It also needs to know the initial block number of + * 'core' (which is 'diskboot' concatenated with 'kernel' and + * all the modules, this is created by grub-mkimage). This resulting + * 'boot' image is 512 bytes in size and is placed in the second block + * of a partition. + * + * The initial 'diskboot' block acts as a loader for the actual GRUB + * kernel. It contains the loading code and then a block list. + * + * The block list of 'core' starts at the end of the 'diskboot' image + * and works it's way backwards towards the end of the code of 'diskboot= '. + * + * We patch up the images with the necessary values and write out the + * result. + */ + +#define DEFAULT_CORE_FILE "core.img" +#define DEFAULT_BOOT_FILE "boot.img" + +#ifdef GRUB_SETUP_SPARC64 +#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) +#elif defined (GRUB_SETUP_BIOS) +#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) +#else +#error Complete this +#endif + +static void +write_rootdev (grub_device_t root_dev, + char *boot_img, grub_uint64_t first_sector) +{ +#ifdef GRUB_SETUP_BIOS + { + grub_uint8_t *boot_drive; + void *kernel_sector; + boot_drive =3D (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_D= RIVE); + kernel_sector =3D (boot_img + GRUB_BOOT_MACHINE_KERNEL_SECTOR); + + /* FIXME: can this be skipped? */ + *boot_drive =3D 0xFF; + + grub_set_unaligned64 (kernel_sector, grub_cpu_to_le64 (first_sector)= ); + } +#endif +#ifdef GRUB_SETUP_SPARC64 + { + void *kernel_byte; + kernel_byte =3D (boot_img + GRUB_BOOT_AOUT_HEADER_SIZE + + GRUB_BOOT_MACHINE_KERNEL_BYTE); + grub_set_unaligned64 (kernel_byte, + grub_cpu_to_be64 (first_sector << GRUB_DISK_SECTOR_BITS)); + } +#endif +} + +#ifdef GRUB_SETUP_SPARC64 +#define BOOT_SECTOR 1 +#else +#define BOOT_SECTOR 0 +#endif + +/* Helper for setup. */ +static void +save_first_sector (grub_disk_addr_t sector, unsigned offset, unsigned le= ngth, + void *data) +{ + grub_disk_addr_t *first_sector =3D data; + grub_util_info ("the first sector is <%" PRIuGRUB_UINT64_T ",%u,%u>", + sector, offset, length); + + if (offset !=3D 0 || length !=3D GRUB_DISK_SECTOR_SIZE) + grub_util_error ("%s", _("the first sector of the core file is not s= ector-aligned")); + + *first_sector =3D sector; +} + +struct blocklists +{ + struct grub_boot_blocklist *first_block, *block; +#ifdef GRUB_SETUP_BIOS + grub_uint16_t current_segment; +#endif + grub_uint16_t last_length; +}; + +/* Helper for setup. */ +static void +save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned leng= th, + void *data) +{ + struct blocklists *bl =3D data; + struct grub_boot_blocklist *prev =3D bl->block + 1; + + grub_util_info ("saving <%" PRIuGRUB_UINT64_T ",%u,%u>", + sector, offset, length); + + if (offset !=3D 0 || bl->last_length !=3D GRUB_DISK_SECTOR_SIZE) + grub_util_error ("%s", _("non-sector-aligned data is found in the co= re file")); + + if (bl->block !=3D bl->first_block + && (grub_target_to_host64 (prev->start) + + grub_target_to_host16 (prev->len)) =3D=3D sector) + { + grub_uint16_t t =3D grub_target_to_host16 (prev->len) + 1; + prev->len =3D grub_host_to_target16 (t); + } + else + { + bl->block->start =3D grub_host_to_target64 (sector); + bl->block->len =3D grub_host_to_target16 (1); +#ifdef GRUB_SETUP_BIOS + bl->block->segment =3D grub_host_to_target16 (bl->current_segment)= ; +#endif + + bl->block--; + if (bl->block->len) + grub_util_error ("%s", _("the sectors of the core file are too fragment= ed")); + } + + bl->last_length =3D length; +#ifdef GRUB_SETUP_BIOS + bl->current_segment +=3D GRUB_DISK_SECTOR_SIZE >> 4; +#endif +} + +#ifdef GRUB_SETUP_BIOS +/* Context for setup/identify_partmap. */ +struct identify_partmap_ctx +{ + grub_partition_map_t dest_partmap; + grub_partition_t container; + int multiple_partmaps; +}; + +/* Helper for setup. + Unlike root_dev, with dest_dev we're interested in the partition map = even + if dest_dev itself is a whole disk. */ +static int +identify_partmap (grub_disk_t disk __attribute__ ((unused)), + const grub_partition_t p, void *data) +{ + struct identify_partmap_ctx *ctx =3D data; + + if (p->parent !=3D ctx->container) + return 0; + /* NetBSD and OpenBSD subpartitions have metadata inside a partition, + so they are safe to ignore. + */ + if (grub_strcmp (p->partmap->name, "netbsd") =3D=3D 0 + || grub_strcmp (p->partmap->name, "openbsd") =3D=3D 0) + return 0; + if (ctx->dest_partmap =3D=3D NULL) + { + ctx->dest_partmap =3D p->partmap; + return 0; + } + if (ctx->dest_partmap =3D=3D p->partmap) + return 0; + ctx->multiple_partmaps =3D 1; + return 1; +} +#endif + +#ifdef GRUB_SETUP_BIOS +#define SETUP grub_bios_setup +#elif GRUB_SETUP_SPARC64 +#define SETUP grub_sparc_setup +#else +#error "Shouldn't happen" +#endif + +void +SETUP (const char *dir, + const char *boot_file, const char *core_file, + const char *dest, int force, + int fs_probe, int allow_floppy) +{ + char *core_path, *core_path_dev, *core_path_dev_full; + char *boot_img, *core_img, *boot_path; + char *root =3D 0; + size_t boot_size, core_size; +#ifdef GRUB_SETUP_BIOS + grub_uint16_t core_sectors; +#endif + grub_device_t root_dev =3D 0, dest_dev, core_dev; + struct blocklists bl; + char *tmp_img; + grub_disk_addr_t first_sector =3D (grub_disk_addr_t)-1; + FILE *fp; + + if (!core_file) + core_file =3D DEFAULT_CORE_FILE; + if (!boot_file) + boot_file =3D DEFAULT_BOOT_FILE; + +#ifdef GRUB_SETUP_BIOS + bl.current_segment =3D + GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4); +#endif + bl.last_length =3D GRUB_DISK_SECTOR_SIZE; + + /* Read the boot image by the OS service. */ + boot_path =3D grub_util_get_path (dir, boot_file); + boot_size =3D grub_util_get_image_size (boot_path); + if (boot_size !=3D GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is not %u"), + boot_path, GRUB_DISK_SECTOR_SIZE); + boot_img =3D grub_util_read_image (boot_path); + + core_path =3D grub_util_get_path (dir, core_file); + core_size =3D grub_util_get_image_size (core_path); +#ifdef GRUB_SETUP_BIOS + core_sectors =3D ((core_size + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS); +#endif + if (core_size < GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is too small"), core_path); +#ifdef GRUB_SETUP_BIOS + if (core_size > 0xFFFF * GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is too large"), core_path); +#endif + + core_img =3D grub_util_read_image (core_path); + + /* Have FIRST_BLOCK to point to the first blocklist. */ + bl.first_block =3D (struct grub_boot_blocklist *) (core_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*bl.block)); + grub_util_info ("root is `%s', dest is `%s'", root, dest); + + grub_util_info ("Opening dest"); + dest_dev =3D grub_device_open (dest); + if (! dest_dev) + grub_util_error ("%s", grub_errmsg); + + core_dev =3D dest_dev; + + { + char **root_devices =3D grub_guess_root_devices (dir); + char **cur; + int found =3D 0; + + for (cur =3D root_devices; *cur; cur++) + { + char *drive; + grub_device_t try_dev; + + drive =3D grub_util_get_grub_dev (*cur); + if (!drive) + continue; + try_dev =3D grub_device_open (drive); + if (! try_dev) + continue; + if (!found && try_dev->disk->id =3D=3D dest_dev->disk->id + && try_dev->disk->dev->id =3D=3D dest_dev->disk->dev->id) + { + if (root_dev) + grub_device_close (root_dev); + free (root); + root_dev =3D try_dev; + root =3D drive; + found =3D 1; + continue; + } + if (!root_dev) + { + root_dev =3D try_dev; + root =3D drive; + continue; + } + grub_device_close (try_dev);=09 + free (drive); + } + if (!root_dev) + { + grub_util_error ("guessing the root device failed, because of `%s'", + grub_errmsg); + } + grub_util_info ("guessed root_dev `%s' from " + "dir `%s'", root_dev->disk->name, dir); + } + + grub_util_info ("setting the root device to `%s'", root); + if (grub_env_set ("root", root) !=3D GRUB_ERR_NONE) + grub_util_error ("%s", grub_errmsg); + +#ifdef GRUB_SETUP_BIOS + /* Read the original sector from the disk. */ + tmp_img =3D xmalloc (GRUB_DISK_SECTOR_SIZE); + if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_i= mg)) + grub_util_error ("%s", grub_errmsg); +#endif + +#ifdef GRUB_SETUP_BIOS + { + grub_uint8_t *boot_drive_check; + boot_drive_check =3D (grub_uint8_t *) (boot_img + + GRUB_BOOT_MACHINE_DRIVE_CHECK); + /* Copy the possible DOS BPB. */ + memcpy (boot_img + GRUB_BOOT_MACHINE_BPB_START, + tmp_img + GRUB_BOOT_MACHINE_BPB_START, + GRUB_BOOT_MACHINE_BPB_END - GRUB_BOOT_MACHINE_BPB_START); + + /* If DEST_DRIVE is a hard disk, enable the workaround, which is + for buggy BIOSes which don't pass boot drive correctly. Instead, + they pass 0x00 or 0x01 even when booted from 0x80. */ + if (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk))= + { + /* Replace the jmp (2 bytes) with double nop's. */ + boot_drive_check[0] =3D 0x90; + boot_drive_check[1] =3D 0x90; + } + } +#endif + +#ifdef GRUB_SETUP_BIOS + { + struct identify_partmap_ctx ctx =3D { + .dest_partmap =3D NULL, + .container =3D dest_dev->disk->partition, + .multiple_partmaps =3D 0 + }; + int is_ldm; + grub_err_t err; + grub_disk_addr_t *sectors; + int i; + grub_fs_t fs; + unsigned int nsec, maxsec; + + grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx); + + if (ctx.container + && grub_strcmp (ctx.container->partmap->name, "msdos") =3D=3D 0 + && ctx.dest_partmap + && (ctx.container->msdostype =3D=3D GRUB_PC_PARTITION_TYPE_NETBSD + || ctx.container->msdostype =3D=3D GRUB_PC_PARTITION_TYPE_OPENBSD))= + { + grub_util_warn ("%s", _("Attempting to install GRUB to a disk with mult= iple partition labels or both partition label and filesystem. This is no= t supported yet.")); + goto unable_to_embed; + } + + fs =3D grub_fs_probe (dest_dev); + if (!fs) + grub_errno =3D GRUB_ERR_NONE; + + is_ldm =3D grub_util_is_ldm (dest_dev->disk); + + if (fs_probe) + { + if (!fs && !ctx.dest_partmap) + grub_util_error (_("unable to identify a filesystem in %s; safety che= ck can't be performed"), + dest_dev->disk->name); + if (fs && !fs->reserved_first_sector) + /* TRANSLATORS: Filesystem may reserve the space just GRUB isn't sure= about it. */ + grub_util_error (_("%s appears to contain a %s filesystem which isn't= known to " + "reserve space for DOS-style boot. Installing GRUB there could = " + "result in FILESYSTEM DESTRUCTION if valuable data is overwritte= n " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), dest_dev->disk->name, fs->name)= ; + + if (ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") !=3D 0= + && strcmp (ctx.dest_partmap->name, "gpt") !=3D 0 + && strcmp (ctx.dest_partmap->name, "bsd") !=3D 0 + && strcmp (ctx.dest_partmap->name, "netbsd") !=3D 0 + && strcmp (ctx.dest_partmap->name, "openbsd") !=3D 0 + && strcmp (ctx.dest_partmap->name, "sunpc") !=3D 0) + /* TRANSLATORS: Partition map may reserve the space just GRUB isn't s= ure about it. */ + grub_util_error (_("%s appears to contain a %s partition map which is= n't known to " + "reserve space for DOS-style boot. Installing GRUB there could = " + "result in FILESYSTEM DESTRUCTION if valuable data is overwritte= n " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), dest_dev->disk->name, ctx.dest_= partmap->name); + if (is_ldm && ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdo= s") !=3D 0 + && strcmp (ctx.dest_partmap->name, "gpt") !=3D 0) + grub_util_error (_("%s appears to contain a %s partition map and " + "LDM which isn't known to be a safe combination." + " Installing GRUB there could " + "result in FILESYSTEM DESTRUCTION if valuable data" + " is overwritten " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), + dest_dev->disk->name, ctx.dest_partmap->name); + + } + + /* Copy the partition table. */ + if (ctx.dest_partmap || + (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk)= )) + memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC);= + + free (tmp_img); + =20 + if (! ctx.dest_partmap && ! fs && !is_ldm) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless = disk or to a partition. This is a BAD idea.")); + goto unable_to_embed; + } + if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && = fs)) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a disk with mult= iple partition labels. This is not supported yet.")); + goto unable_to_embed; + } + + if (ctx.dest_partmap && !ctx.dest_partmap->embed) + { + grub_util_warn (_("Partition style `%s' doesn't support embedding"), + ctx.dest_partmap->name); + goto unable_to_embed; + } + + if (fs && !fs->embed) + { + grub_util_warn (_("File system `%s' doesn't support embedding"), + fs->name); + goto unable_to_embed; + } + + nsec =3D core_sectors; + + maxsec =3D 2 * core_sectors; + if (maxsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) + >> GRUB_DISK_SECTOR_BITS)) + maxsec =3D ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) + >> GRUB_DISK_SECTOR_BITS); + + if (is_ldm) + err =3D grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + else if (ctx.dest_partmap) + err =3D ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + else + err =3D fs->embed (dest_dev, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + if (!err && nsec < core_sectors) + { + err =3D grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("Your embedding area is unusually small. " + "core.img won't fit in it.")); + } + =20 + if (err) + { + grub_util_warn ("%s", grub_errmsg); + grub_errno =3D GRUB_ERR_NONE; + goto unable_to_embed; + } + + assert (nsec <=3D maxsec); + + /* Clean out the blocklists. */ + bl.block =3D bl.first_block; + while (bl.block->len) + { + grub_memset (bl.block, 0, sizeof (bl.block)); + =20 + bl.block--; + + if ((char *) bl.block <=3D core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + + save_first_sector (sectors[0] + grub_partition_get_start (ctx.contai= ner), + 0, GRUB_DISK_SECTOR_SIZE, &first_sector); + + bl.block =3D bl.first_block; + for (i =3D 1; i < nsec; i++) + save_blocklists (sectors[i] + grub_partition_get_start (ctx.contai= ner), + 0, GRUB_DISK_SECTOR_SIZE, &bl); + + /* Make sure that the last blocklist is a terminator. */ + if (bl.block =3D=3D bl.first_block) + bl.block--; + bl.block->start =3D 0; + bl.block->len =3D 0; + bl.block->segment =3D 0; + + write_rootdev (root_dev, boot_img, first_sector); + + core_img =3D realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); + bl.first_block =3D (struct grub_boot_blocklist *) (core_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*bl.block)); + + grub_size_t no_rs_length; + grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY), + grub_host_to_target32 (nsec * GRUB_DISK_SECTOR_SIZE - core_size)); + no_rs_length =3D grub_target_to_host16=20 + (grub_get_unaligned16 (core_img + + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH)); + + if (no_rs_length =3D=3D 0xffff) + grub_util_error ("%s", _("core.img version mismatch")); + + void *tmp =3D xmalloc (core_size); + grub_memcpy (tmp, core_img, core_size); + grub_reed_solomon_add_redundancy (core_img + no_rs_length + GRUB_DIS= K_SECTOR_SIZE, + core_size - no_rs_length - GRUB_DISK_SECTOR_SIZE, + nsec * GRUB_DISK_SECTOR_SIZE + - core_size); + assert (grub_memcmp (tmp, core_img, core_size) =3D=3D 0); + free (tmp); + + /* Write the core image onto the disk. */ + for (i =3D 0; i < nsec; i++) + grub_disk_write (dest_dev->disk, sectors[i], 0, + GRUB_DISK_SECTOR_SIZE, + core_img + i * GRUB_DISK_SECTOR_SIZE); + + grub_free (sectors); + + goto finish; + } + +unable_to_embed: +#endif + + if (dest_dev->disk->dev->id !=3D root_dev->disk->dev->id) + grub_util_error ("%s", _("embedding is not possible, but this is req= uired for " + "RAID and LVM install")); + + { + grub_fs_t fs; + fs =3D grub_fs_probe (root_dev); + if (!fs) + grub_util_error (_("can't determine filesystem on %s"), root); + + if (!fs->blocklist_install) + grub_util_error (_("filesystem `%s' doesn't support blocklists"), + fs->name); + } + +#ifdef GRUB_SETUP_BIOS + if (dest_dev->disk->id !=3D root_dev->disk->id + || dest_dev->disk->dev->id !=3D root_dev->disk->dev->id) + /* TRANSLATORS: cross-disk refers to /boot being on one disk + but MBR on another. */ + grub_util_error ("%s", _("embedding is not possible, but this is req= uired for " + "cross-disk install")); +#else + core_dev =3D root_dev; +#endif + + grub_util_warn ("%s", _("Embedding is not possible. GRUB can only be = installed in this " + "setup by using blocklists. However, blocklists are UNRELIABLE and= " + "their use is discouraged.")); + if (! force) + /* TRANSLATORS: Here GRUB refuses to continue with blocklist install= =2E */ + grub_util_error ("%s", _("will not proceed with blocklists")); + + /* The core image must be put on a filesystem unfortunately. */ + grub_util_info ("will leave the core image on the filesystem"); + + /* Make sure that GRUB reads the identical image as the OS. */ + tmp_img =3D xmalloc (core_size); + core_path_dev_full =3D grub_util_get_path (dir, core_file); + core_path_dev =3D grub_make_system_path_relative_to_its_root (core_pat= h_dev_full); + free (core_path_dev_full); + + grub_util_biosdisk_flush (root_dev->disk); + +#ifndef __linux__ + +#define MAX_TRIES 5 + { + int i; + for (i =3D 0; i < MAX_TRIES; i++) + { + grub_file_t file; + + grub_util_info ((i =3D=3D 0) ? _("attempting to read the core image `%s= ' from GRUB") + : _("attempting to read the core image `%s' from GRUB again"), + core_path_dev); + + grub_disk_cache_invalidate_all (); + + grub_file_filter_disable_compression (); + file =3D grub_file_open (core_path_dev); + if (file) + { + if (grub_file_size (file) !=3D core_size) + grub_util_info ("succeeded in opening the core image but the size= is different (%d !=3D %d)", + (int) grub_file_size (file), (int) core_size); + else if (grub_file_read (file, tmp_img, core_size) + !=3D (grub_ssize_t) core_size) + grub_util_info ("succeeded in opening the core image but cannot r= ead %d bytes", + (int) core_size); + else if (memcmp (core_img, tmp_img, core_size) !=3D 0) + { +#if 0 + FILE *dump; + FILE *dump2; + + dump =3D fopen ("dump.img", "wb"); + if (dump) + { + fwrite (tmp_img, 1, core_size, dump); + fclose (dump); + } + + dump2 =3D fopen ("dump2.img", "wb"); + if (dump2) + { + fwrite (core_img, 1, core_size, dump2); + fclose (dump2); + } + +#endif + grub_util_info ("succeeded in opening the core image but the data is d= ifferent"); + } + else + { + grub_file_close (file); + break; + } + + grub_file_close (file); + } + else + grub_util_info ("couldn't open the core image"); + + if (grub_errno) + grub_util_info ("error message =3D %s", grub_errmsg); + + grub_errno =3D GRUB_ERR_NONE; + grub_util_biosdisk_flush (root_dev->disk); + sleep (1); + } + + if (i =3D=3D MAX_TRIES) + grub_util_error (_("cannot read `%s' correctly"), core_path_dev); + } + +#endif + + /* Clean out the blocklists. */ + bl.block =3D bl.first_block; + while (bl.block->len) + { + bl.block->start =3D 0; + bl.block->len =3D 0; +#ifdef GRUB_SETUP_BIOS + bl.block->segment =3D 0; +#endif + + bl.block--; + + if ((char *) bl.block <=3D core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + + bl.block =3D bl.first_block; + +#ifdef __linux__ + { + grub_partition_t container =3D root_dev->disk->partition; + grub_uint64_t container_start =3D grub_partition_get_start (containe= r); + struct fiemap fie1; + int fd; + + /* Write the first two sectors of the core image onto the disk. */ + grub_util_info ("opening the core image `%s'", core_path); + fp =3D fopen (core_path, "rb"); + if (! fp) + grub_util_error (_("cannot open `%s': %s"), core_path, + strerror (errno)); + fd =3D fileno (fp); + + grub_memset (&fie1, 0, sizeof (fie1)); + fie1.fm_length =3D core_size; + fie1.fm_flags =3D FIEMAP_FLAG_SYNC; + + if (ioctl (fd, FS_IOC_FIEMAP, &fie1) < 0) + { + int nblocks, i, j; + int bsize; + int mul; + + grub_util_info ("FIEMAP failed. Reverting to FIBMAP"); + + if (ioctl (fd, FIGETBSZ, &bsize) < 0) + grub_util_error (_("can't retrieve blocklists: %s"), + strerror (errno)); + if (bsize & (GRUB_DISK_SECTOR_SIZE - 1)) + grub_util_error ("%s", _("blocksize is not divisible by 512")); + mul =3D bsize >> GRUB_DISK_SECTOR_BITS; + nblocks =3D (core_size + bsize - 1) / bsize; + if (mul =3D=3D 0 || nblocks =3D=3D 0) + grub_util_error ("%s", _("can't retrieve blocklists")); + for (i =3D 0; i < nblocks; i++) + { + unsigned blk =3D i; + if (ioctl (fd, FIBMAP, &blk) < 0) + grub_util_error (_("can't retrieve blocklists: %s"), + strerror (errno)); + =20 + for (j =3D 0; j < mul; j++) + { + int rest =3D core_size - ((i * mul + j) << GRUB_DISK_SECTOR_BITS); + if (rest <=3D 0) + break; + if (rest > GRUB_DISK_SECTOR_SIZE) + rest =3D GRUB_DISK_SECTOR_SIZE; + if (i =3D=3D 0 && j =3D=3D 0) + save_first_sector (((grub_uint64_t) blk) * mul + + container_start, + 0, rest, &first_sector); + else + save_blocklists (((grub_uint64_t) blk) * mul + j + + container_start, + 0, rest, &bl); + } + } + } + else + { + struct fiemap *fie2; + int i, j; + fie2 =3D xmalloc (sizeof (*fie2) + + fie1.fm_mapped_extents + * sizeof (fie1.fm_extents[1])); + memset (fie2, 0, sizeof (*fie2) + + fie1.fm_mapped_extents * sizeof (fie2->fm_extents[1])); + fie2->fm_length =3D core_size; + fie2->fm_flags =3D FIEMAP_FLAG_SYNC; + fie2->fm_extent_count =3D fie1.fm_mapped_extents; + if (ioctl (fd, FS_IOC_FIEMAP, fie2) < 0) + grub_util_error (_("can't retrieve blocklists: %s"), + strerror (errno)); + for (i =3D 0; i < fie2->fm_mapped_extents; i++) + { + for (j =3D 0; + j < ((fie2->fm_extents[i].fe_length + + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS); + j++) + { + size_t len =3D (fie2->fm_extents[i].fe_length + - j * GRUB_DISK_SECTOR_SIZE); + if (len > GRUB_DISK_SECTOR_SIZE) + len =3D GRUB_DISK_SECTOR_SIZE; + if (first_sector =3D=3D (grub_disk_addr_t)-1) + save_first_sector ((fie2->fm_extents[i].fe_physical + >> GRUB_DISK_SECTOR_BITS) + + j + container_start, + fie2->fm_extents[i].fe_physical + & (GRUB_DISK_SECTOR_SIZE - 1), len, + &first_sector); + else + save_blocklists ((fie2->fm_extents[i].fe_physical + >> GRUB_DISK_SECTOR_BITS) + + j + container_start, + fie2->fm_extents[i].fe_physical + & (GRUB_DISK_SECTOR_SIZE - 1), len, &bl); + + + } + } + if (first_sector =3D=3D (grub_disk_addr_t)-1) + grub_util_error ("%s", _("can't retrieve blocklists")); + } + fclose (fp); + } +#else + { + grub_file_t file; + /* Now read the core image to determine where the sectors are. */ + grub_file_filter_disable_compression (); + file =3D grub_file_open (core_path_dev); + if (! file) + grub_util_error ("%s", grub_errmsg); + + file->read_hook =3D save_first_sector; + file->read_hook_data =3D &first_sector; + if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE) + !=3D GRUB_DISK_SECTOR_SIZE) + grub_util_error ("%s", _("failed to read the first sector of the c= ore image")); + + bl.block =3D bl.first_block; + file->read_hook =3D save_blocklists; + file->read_hook_data =3D &bl; + if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE= ) + !=3D (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE) + grub_util_error ("%s", _("failed to read the rest sectors of the c= ore image")); + grub_file_close (file); + } +#endif + +#ifdef GRUB_SETUP_SPARC64 + { + char *boot_devpath; + boot_devpath =3D (char *) (boot_img + + GRUB_BOOT_AOUT_HEADER_SIZE + + GRUB_BOOT_MACHINE_BOOT_DEVPATH); + if (dest_dev->disk->id !=3D root_dev->disk->id + || dest_dev->disk->dev->id !=3D root_dev->disk->dev->id) + { + const char *dest_ofpath; + dest_ofpath + =3D grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (root_d= ev->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] =3D 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_util_info ("boot device path %s", boot_devpath); + } +#endif + + free (core_path_dev); + free (tmp_img); + + write_rootdev (root_dev, boot_img, first_sector); + + /* Write the first two sectors of the core image onto the disk. */ + grub_util_info ("opening the core image `%s'", core_path); + fp =3D fopen (core_path, "r+b"); + if (! fp) + grub_util_error (_("cannot open `%s': %s"), core_path, + strerror (errno)); + + grub_util_write_image (core_img, GRUB_DISK_SECTOR_SIZE * 2, fp, core_p= ath); + fflush (fp); + fsync (fileno (fp)); + fclose (fp); + grub_util_biosdisk_flush (root_dev->disk); + + grub_disk_cache_invalidate_all (); + + { + char *buf, *ptr =3D core_img; + size_t len =3D core_size; + grub_uint64_t blk; + grub_partition_t container =3D core_dev->disk->partition; + grub_err_t err; + + core_dev->disk->partition =3D 0; + + buf =3D xmalloc (core_size); + blk =3D first_sector; + err =3D grub_disk_read (core_dev->disk, blk, 0, GRUB_DISK_SECTOR_SIZ= E, buf); + if (err) + grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, + grub_errmsg); + if (grub_memcmp (buf, ptr, GRUB_DISK_SECTOR_SIZE) !=3D 0) + grub_util_error ("%s", _("blocklists are invalid")); + + ptr +=3D GRUB_DISK_SECTOR_SIZE; + len -=3D GRUB_DISK_SECTOR_SIZE; + + bl.block =3D bl.first_block; + while (bl.block->len) + { + size_t cur =3D grub_target_to_host16 (bl.block->len) << GRUB_DISK_SECTO= R_BITS; + blk =3D grub_target_to_host64 (bl.block->start); + + if (cur > len) + cur =3D len; + + err =3D grub_disk_read (core_dev->disk, blk, 0, cur, buf); + if (err) + grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, + grub_errmsg); + + if (grub_memcmp (buf, ptr, cur) !=3D 0) + grub_util_error ("%s", _("blocklists are invalid")); + + ptr +=3D cur; + len -=3D cur; + bl.block--; +=09 + if ((char *) bl.block <=3D core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + core_dev->disk->partition =3D container; + free (buf); + } + +#ifdef GRUB_SETUP_BIOS + finish: +#endif + + /* Write the boot image onto the disk. */ + if (grub_disk_write (dest_dev->disk, BOOT_SECTOR, + 0, GRUB_DISK_SECTOR_SIZE, boot_img)) + grub_util_error ("%s", grub_errmsg); + + grub_util_biosdisk_flush (root_dev->disk); + grub_util_biosdisk_flush (dest_dev->disk); + + free (core_path); + free (core_img); + free (boot_img); + grub_device_close (dest_dev); + grub_device_close (root_dev); +} =3D=3D=3D added file 'util/setup_bios.c' --- util/setup_bios.c 1970-01-01 00:00:00 +0000 +++ util/setup_bios.c 2013-10-04 00:39:55 +0000 @@ -0,0 +1,2 @@ +#define GRUB_SETUP_BIOS 1 +#include "setup.c" =3D=3D=3D added file 'util/setup_sparc.c' --- util/setup_sparc.c 1970-01-01 00:00:00 +0000 +++ util/setup_sparc.c 2013-10-04 00:39:55 +0000 @@ -0,0 +1,2 @@ +#define GRUB_SETUP_SPARC64 1 +#include "setup.c" --------------050304090405030404060303-- ------enig2JSGICUDLKHXJILLBWCEK Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) Comment: Using GnuPG with Icedove - http://www.enigmail.net/ iF4EAREKAAYFAlJReZcACgkQNak7dOguQgmu1wD/fNwlNlAq6mKrRkkENXyhsIXg NEfhxBYo9xGOWQpQCAEBAKW5s08Sn+hR3cDnRYfUJLDjrLCZ8eJM1sBPdv7Dvked =vwaM -----END PGP SIGNATURE----- ------enig2JSGICUDLKHXJILLBWCEK--