merge merge-mkimage into rescue-efi
This commit is contained in:
commit
19ba92760a
89 changed files with 4039 additions and 2886 deletions
|
@ -1,462 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <grub/elf.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/util/misc.h>
|
||||
#include <grub/util/resolve.h>
|
||||
#include <grub/kernel.h>
|
||||
#include <grub/cpu/kernel.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
#include "progname.h"
|
||||
|
||||
#define GRUB_IEEE1275_NOTE_NAME "PowerPC"
|
||||
#define GRUB_IEEE1275_NOTE_TYPE 0x1275
|
||||
|
||||
/* These structures are defined according to the CHRP binding to IEEE1275,
|
||||
"Client Program Format" section. */
|
||||
|
||||
struct grub_ieee1275_note_hdr
|
||||
{
|
||||
grub_uint32_t namesz;
|
||||
grub_uint32_t descsz;
|
||||
grub_uint32_t type;
|
||||
char name[sizeof (GRUB_IEEE1275_NOTE_NAME)];
|
||||
};
|
||||
|
||||
struct grub_ieee1275_note_desc
|
||||
{
|
||||
grub_uint32_t real_mode;
|
||||
grub_uint32_t real_base;
|
||||
grub_uint32_t real_size;
|
||||
grub_uint32_t virt_base;
|
||||
grub_uint32_t virt_size;
|
||||
grub_uint32_t load_base;
|
||||
};
|
||||
|
||||
struct grub_ieee1275_note
|
||||
{
|
||||
struct grub_ieee1275_note_hdr header;
|
||||
struct grub_ieee1275_note_desc descriptor;
|
||||
};
|
||||
|
||||
void
|
||||
load_note (Elf32_Phdr *phdr, FILE *out)
|
||||
{
|
||||
struct grub_ieee1275_note note;
|
||||
int note_size = sizeof (struct grub_ieee1275_note);
|
||||
|
||||
grub_util_info ("adding CHRP NOTE segment");
|
||||
|
||||
note.header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME));
|
||||
note.header.descsz = grub_host_to_target32 (note_size);
|
||||
note.header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE);
|
||||
strcpy (note.header.name, GRUB_IEEE1275_NOTE_NAME);
|
||||
note.descriptor.real_mode = grub_host_to_target32 (0xffffffff);
|
||||
note.descriptor.real_base = grub_host_to_target32 (0x00c00000);
|
||||
note.descriptor.real_size = grub_host_to_target32 (0xffffffff);
|
||||
note.descriptor.virt_base = grub_host_to_target32 (0xffffffff);
|
||||
note.descriptor.virt_size = grub_host_to_target32 (0xffffffff);
|
||||
note.descriptor.load_base = grub_host_to_target32 (0x00004000);
|
||||
|
||||
/* Write the note data to the new segment. */
|
||||
grub_util_write_image_at (¬e, note_size,
|
||||
grub_target_to_host32 (phdr->p_offset), out);
|
||||
|
||||
/* Fill in the rest of the segment header. */
|
||||
phdr->p_type = grub_host_to_target32 (PT_NOTE);
|
||||
phdr->p_flags = grub_host_to_target32 (PF_R);
|
||||
phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG);
|
||||
phdr->p_vaddr = 0;
|
||||
phdr->p_paddr = 0;
|
||||
phdr->p_filesz = grub_host_to_target32 (note_size);
|
||||
phdr->p_memsz = 0;
|
||||
}
|
||||
|
||||
void
|
||||
load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir,
|
||||
char *mods[], FILE *out, char *memdisk_path, char *config_path)
|
||||
{
|
||||
char *module_img;
|
||||
struct grub_util_path_list *path_list;
|
||||
struct grub_util_path_list *p;
|
||||
struct grub_module_info *modinfo;
|
||||
size_t offset;
|
||||
size_t total_module_size;
|
||||
size_t memdisk_size = 0;
|
||||
size_t config_size = 0;
|
||||
|
||||
path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
|
||||
|
||||
offset = sizeof (struct grub_module_info);
|
||||
total_module_size = sizeof (struct grub_module_info);
|
||||
|
||||
if (memdisk_path)
|
||||
{
|
||||
memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
|
||||
grub_util_info ("the size of memory disk is 0x%x", memdisk_size);
|
||||
total_module_size += memdisk_size + sizeof (struct grub_module_header);
|
||||
}
|
||||
|
||||
if (config_path)
|
||||
{
|
||||
config_size = ALIGN_UP(grub_util_get_image_size (config_path), 512);
|
||||
grub_util_info ("the size of memory disk is 0x%x", config_size);
|
||||
total_module_size += config_size + sizeof (struct grub_module_header);
|
||||
}
|
||||
|
||||
for (p = path_list; p; p = p->next)
|
||||
{
|
||||
total_module_size += (grub_util_get_image_size (p->name)
|
||||
+ sizeof (struct grub_module_header));
|
||||
}
|
||||
|
||||
grub_util_info ("the total module size is 0x%x", total_module_size);
|
||||
|
||||
module_img = xmalloc (total_module_size);
|
||||
modinfo = (struct grub_module_info *) module_img;
|
||||
modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
|
||||
modinfo->offset = grub_host_to_target32 (sizeof (struct grub_module_info));
|
||||
modinfo->size = grub_host_to_target32 (total_module_size);
|
||||
|
||||
/* Load all the modules, with headers, into module_img. */
|
||||
for (p = path_list; p; p = p->next)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
size_t mod_size;
|
||||
|
||||
grub_util_info ("adding module %s", p->name);
|
||||
|
||||
mod_size = grub_util_get_image_size (p->name);
|
||||
|
||||
header = (struct grub_module_header *) (module_img + offset);
|
||||
header->type = OBJ_TYPE_ELF;
|
||||
header->size = grub_host_to_target32 (mod_size + sizeof (*header));
|
||||
|
||||
grub_util_load_image (p->name, module_img + offset + sizeof (*header));
|
||||
|
||||
offset += sizeof (*header) + mod_size;
|
||||
}
|
||||
|
||||
if (memdisk_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
|
||||
header = (struct grub_module_header *) (module_img + offset);
|
||||
header->type = OBJ_TYPE_MEMDISK;
|
||||
header->size = grub_host_to_target32 (memdisk_size + sizeof (*header));
|
||||
offset += sizeof (*header);
|
||||
|
||||
grub_util_load_image (memdisk_path, module_img + offset);
|
||||
offset += memdisk_size;
|
||||
}
|
||||
|
||||
if (config_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
|
||||
header = (struct grub_module_header *) (module_img + offset);
|
||||
header->type = OBJ_TYPE_CONFIG;
|
||||
header->size = grub_host_to_target32 (config_size + sizeof (*header));
|
||||
offset += sizeof (*header);
|
||||
|
||||
grub_util_load_image (config_path, module_img + offset);
|
||||
offset += config_size;
|
||||
}
|
||||
|
||||
|
||||
/* Write the module data to the new segment. */
|
||||
grub_util_write_image_at (module_img, total_module_size,
|
||||
grub_host_to_target32 (phdr->p_offset), out);
|
||||
|
||||
/* Fill in the rest of the segment header. */
|
||||
phdr->p_type = grub_host_to_target32 (PT_LOAD);
|
||||
phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
|
||||
phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG);
|
||||
phdr->p_vaddr = grub_host_to_target32 (modbase);
|
||||
phdr->p_paddr = grub_host_to_target32 (modbase);
|
||||
phdr->p_filesz = grub_host_to_target32 (total_module_size);
|
||||
phdr->p_memsz = grub_host_to_target32 (total_module_size);
|
||||
}
|
||||
|
||||
void
|
||||
add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path, char *config_path)
|
||||
{
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr *phdrs = NULL;
|
||||
Elf32_Phdr *phdr;
|
||||
FILE *in;
|
||||
char *kernel_path;
|
||||
grub_addr_t grub_end = 0;
|
||||
off_t offset, first_segment;
|
||||
int i, phdr_size;
|
||||
|
||||
/* Read ELF header. */
|
||||
kernel_path = grub_util_get_path (dir, "kernel.img");
|
||||
in = fopen (kernel_path, "rb");
|
||||
if (! in)
|
||||
grub_util_error ("cannot open %s", kernel_path);
|
||||
|
||||
grub_util_read_at (&ehdr, sizeof (ehdr), 0, in);
|
||||
|
||||
offset = ALIGN_UP (sizeof (ehdr), GRUB_TARGET_SIZEOF_LONG);
|
||||
ehdr.e_phoff = grub_host_to_target32 (offset);
|
||||
|
||||
phdr_size = (grub_target_to_host16 (ehdr.e_phentsize) *
|
||||
grub_target_to_host16 (ehdr.e_phnum));
|
||||
|
||||
if (mods[0] != NULL)
|
||||
phdr_size += grub_target_to_host16 (ehdr.e_phentsize);
|
||||
|
||||
if (chrp)
|
||||
phdr_size += grub_target_to_host16 (ehdr.e_phentsize);
|
||||
|
||||
phdrs = xmalloc (phdr_size);
|
||||
offset += ALIGN_UP (phdr_size, GRUB_TARGET_SIZEOF_LONG);
|
||||
|
||||
first_segment = offset;
|
||||
|
||||
/* Copy all existing segments. */
|
||||
for (i = 0; i < grub_target_to_host16 (ehdr.e_phnum); i++)
|
||||
{
|
||||
char *segment_img;
|
||||
grub_size_t segment_end;
|
||||
|
||||
phdr = phdrs + i;
|
||||
|
||||
/* Read segment header. */
|
||||
grub_util_read_at (phdr, sizeof (Elf32_Phdr),
|
||||
(grub_target_to_host32 (ehdr.e_phoff)
|
||||
+ (i * grub_target_to_host16 (ehdr.e_phentsize))),
|
||||
in);
|
||||
grub_util_info ("copying segment %d, type %d", i,
|
||||
grub_target_to_host32 (phdr->p_type));
|
||||
|
||||
/* Locate _end. */
|
||||
segment_end = grub_target_to_host32 (phdr->p_paddr)
|
||||
+ grub_target_to_host32 (phdr->p_memsz);
|
||||
grub_util_info ("segment %u end 0x%lx", i, segment_end);
|
||||
if (segment_end > grub_end)
|
||||
grub_end = segment_end;
|
||||
|
||||
/* Read segment data and write it to new file. */
|
||||
segment_img = xmalloc (grub_target_to_host32 (phdr->p_filesz));
|
||||
|
||||
grub_util_read_at (segment_img, grub_target_to_host32 (phdr->p_filesz),
|
||||
grub_target_to_host32 (phdr->p_offset), in);
|
||||
|
||||
phdr->p_offset = grub_host_to_target32 (offset);
|
||||
grub_util_write_image_at (segment_img, grub_target_to_host32 (phdr->p_filesz),
|
||||
offset, out);
|
||||
offset += ALIGN_UP (grub_target_to_host32 (phdr->p_filesz),
|
||||
GRUB_TARGET_SIZEOF_LONG);
|
||||
|
||||
free (segment_img);
|
||||
}
|
||||
|
||||
if (mods[0] != NULL)
|
||||
{
|
||||
grub_addr_t modbase;
|
||||
|
||||
/* Place modules just after grub segment. */
|
||||
modbase = ALIGN_UP(grub_end + GRUB_MOD_GAP, GRUB_MOD_ALIGN);
|
||||
|
||||
/* Construct new segment header for modules. */
|
||||
phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum);
|
||||
ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1);
|
||||
|
||||
/* Fill in p_offset so the callees know where to write. */
|
||||
phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out),
|
||||
GRUB_TARGET_SIZEOF_LONG));
|
||||
|
||||
load_modules (modbase, phdr, dir, mods, out, memdisk_path, config_path);
|
||||
}
|
||||
|
||||
if (chrp)
|
||||
{
|
||||
/* Construct new segment header for the CHRP note. */
|
||||
phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum);
|
||||
ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1);
|
||||
|
||||
/* Fill in p_offset so the callees know where to write. */
|
||||
phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out),
|
||||
GRUB_TARGET_SIZEOF_LONG));
|
||||
|
||||
load_note (phdr, out);
|
||||
}
|
||||
|
||||
/* Don't bother preserving the section headers. */
|
||||
ehdr.e_shoff = 0;
|
||||
ehdr.e_shnum = 0;
|
||||
ehdr.e_shstrndx = 0;
|
||||
|
||||
/* Write entire segment table to the file. */
|
||||
grub_util_write_image_at (phdrs, phdr_size, grub_target_to_host32 (ehdr.e_phoff), out);
|
||||
|
||||
/* Write ELF header. */
|
||||
grub_util_write_image_at (&ehdr, sizeof (ehdr), 0, out);
|
||||
|
||||
if (prefix)
|
||||
{
|
||||
if (GRUB_KERNEL_CPU_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_CPU_DATA_END)
|
||||
grub_util_error ("prefix too long");
|
||||
grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_CPU_PREFIX, out);
|
||||
}
|
||||
|
||||
free (phdrs);
|
||||
free (kernel_path);
|
||||
}
|
||||
|
||||
static struct option options[] =
|
||||
{
|
||||
{"directory", required_argument, 0, 'd'},
|
||||
{"prefix", required_argument, 0, 'p'},
|
||||
{"memdisk", required_argument, 0, 'm'},
|
||||
{"config", required_argument, 0, 'c'},
|
||||
{"output", required_argument, 0, 'o'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"note", no_argument, 0, 'n'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
if (status)
|
||||
fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
|
||||
else
|
||||
printf ("\
|
||||
Usage: %s -o FILE [OPTION]... [MODULES]\n\
|
||||
\n\
|
||||
Make a bootable image of GRUB.\n\
|
||||
\n\
|
||||
-d, --directory=DIR use images and modules under DIR [default=%s]\n\
|
||||
-p, --prefix=DIR set grub_prefix directory\n\
|
||||
-m, --memdisk=FILE embed FILE as a memdisk image\n\
|
||||
-c, --config=FILE embed FILE as boot config\n\
|
||||
-o, --output=FILE output a generated image to FILE\n\
|
||||
-h, --help display this message and exit\n\
|
||||
-n, --note add NOTE segment for CHRP Open Firmware\n\
|
||||
-V, --version print version information and exit\n\
|
||||
-v, --verbose print verbose messages\n\
|
||||
\n\
|
||||
Report bugs to <%s>.\n\
|
||||
", program_name, GRUB_LIBDIR, PACKAGE_BUGREPORT);
|
||||
|
||||
exit (status);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
FILE *fp;
|
||||
char *output = NULL;
|
||||
char *dir = NULL;
|
||||
char *prefix = NULL;
|
||||
char *memdisk = NULL;
|
||||
char *config = NULL;
|
||||
int chrp = 0;
|
||||
|
||||
set_program_name (argv[0]);
|
||||
|
||||
grub_util_init_nls ();
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c = getopt_long (argc, argv, "d:p:m:c:o:hVvn", options, 0);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'd':
|
||||
if (dir)
|
||||
free (dir);
|
||||
dir = xstrdup (optarg);
|
||||
break;
|
||||
case 'p':
|
||||
if (prefix)
|
||||
free (prefix);
|
||||
prefix = xstrdup (optarg);
|
||||
break;
|
||||
case 'm':
|
||||
if (memdisk)
|
||||
free (memdisk);
|
||||
memdisk = xstrdup (optarg);
|
||||
|
||||
if (prefix)
|
||||
free (prefix);
|
||||
prefix = xstrdup ("(memdisk)/boot/grub");
|
||||
|
||||
break;
|
||||
case 'c':
|
||||
if (config)
|
||||
free (config);
|
||||
config = xstrdup (optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage (0);
|
||||
break;
|
||||
case 'n':
|
||||
chrp = 1;
|
||||
break;
|
||||
case 'o':
|
||||
if (output)
|
||||
free (output);
|
||||
output = xstrdup (optarg);
|
||||
break;
|
||||
case 'V':
|
||||
printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
return 0;
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
default:
|
||||
usage (1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!output)
|
||||
usage (1);
|
||||
|
||||
fp = fopen (output, "wb");
|
||||
if (! fp)
|
||||
grub_util_error ("cannot open %s", output);
|
||||
|
||||
add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk,
|
||||
config);
|
||||
|
||||
fclose (fp);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -35,11 +35,7 @@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${t
|
|||
localedir=@datadir@/locale
|
||||
|
||||
grub_setup=${sbindir}/`echo grub-setup | sed ${transform}`
|
||||
if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then
|
||||
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
|
||||
else
|
||||
grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}`
|
||||
fi
|
||||
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
|
||||
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
|
||||
grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
|
||||
grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}`
|
||||
|
@ -346,16 +342,23 @@ else
|
|||
prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1
|
||||
fi
|
||||
|
||||
case "${target_cpu}-${platform}"
|
||||
i386-pc) mkimage_target=i386-pc ;;
|
||||
sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;;
|
||||
mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;;
|
||||
*) mkimage_target=i386-coreboot;
|
||||
esac
|
||||
|
||||
if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then
|
||||
$grub_mkimage ${config_opt} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
|
||||
$grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
|
||||
|
||||
# Now perform the installation.
|
||||
$grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \
|
||||
${install_device} || exit 1
|
||||
elif [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then
|
||||
$grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O elf --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
|
||||
$grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O ${mkimage_target} --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
|
||||
else
|
||||
$grub_mkimage ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
|
||||
$grub_mkimage -O ${mkimage_target} ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
|
||||
fi
|
||||
|
||||
echo "Installation finished. No error reported."
|
||||
|
|
|
@ -24,10 +24,10 @@ sbindir=@sbindir@
|
|||
libdir=@libdir@
|
||||
sysconfdir=@sysconfdir@
|
||||
package_version=@PACKAGE_VERSION@
|
||||
host_os=@host_os@
|
||||
datarootdir=@datarootdir@
|
||||
datadir=@datadir@
|
||||
pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"`
|
||||
grub_prefix=`echo /boot/grub | sed ${transform}`
|
||||
grub_cfg=""
|
||||
grub_mkconfig_dir=${sysconfdir}/grub.d
|
||||
|
||||
|
@ -75,6 +75,18 @@ done
|
|||
|
||||
. ${libdir}/grub/grub-mkconfig_lib
|
||||
|
||||
case "$host_os" in
|
||||
netbsd* | openbsd*)
|
||||
# Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub
|
||||
# instead of /boot/grub.
|
||||
grub_prefix=`echo /grub | sed ${transform}`
|
||||
;;
|
||||
*)
|
||||
# Use /boot/grub by default.
|
||||
grub_prefix=`echo /boot/grub | sed ${transform}`
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "x$EUID" = "x" ] ; then
|
||||
EUID=`id -u`
|
||||
fi
|
||||
|
@ -141,13 +153,13 @@ if [ "x${GRUB_TERMINAL}" != "x" ] ; then
|
|||
fi
|
||||
|
||||
termoutdefault=0
|
||||
if [ "x${GRUB_TERMINAL_OUTPUT}" == x ]; then
|
||||
if [ "x${GRUB_TERMINAL_OUTPUT}" = "x" ]; then
|
||||
GRUB_TERMINAL_OUTPUT=gfxterm;
|
||||
termoutdefault=1;
|
||||
fi
|
||||
|
||||
for x in ${GRUB_TERMINAL_OUTPUT}; do
|
||||
if [ x${x} == xgfxterm ]; then
|
||||
if [ "x${x}" = "xgfxterm" ]; then
|
||||
# If this platform supports gfxterm, try to use it.
|
||||
if ! test -e ${grub_prefix}/gfxterm.mod ; then
|
||||
if [ "x$termoutdefault" != "x1" ]; then
|
||||
|
@ -227,11 +239,14 @@ export GRUB_DEFAULT \
|
|||
GRUB_DISTRIBUTOR \
|
||||
GRUB_CMDLINE_LINUX \
|
||||
GRUB_CMDLINE_LINUX_DEFAULT \
|
||||
GRUB_CMDLINE_NETBSD \
|
||||
GRUB_CMDLINE_NETBSD_DEFAULT \
|
||||
GRUB_TERMINAL_INPUT \
|
||||
GRUB_TERMINAL_OUTPUT \
|
||||
GRUB_SERIAL_COMMAND \
|
||||
GRUB_DISABLE_LINUX_UUID \
|
||||
GRUB_DISABLE_LINUX_RECOVERY \
|
||||
GRUB_DISABLE_NETBSD_RECOVERY \
|
||||
GRUB_GFXMODE \
|
||||
GRUB_BACKGROUND \
|
||||
GRUB_THEME \
|
||||
|
|
|
@ -31,6 +31,12 @@ if test "x$grub_mkrelpath" = x; then
|
|||
grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}`
|
||||
fi
|
||||
|
||||
if $(which gettext >/dev/null 2>/dev/null) ; then
|
||||
gettext="gettext"
|
||||
else
|
||||
gettext="echo"
|
||||
fi
|
||||
|
||||
grub_warn ()
|
||||
{
|
||||
echo "Warning: $@" >&2
|
||||
|
@ -188,3 +194,7 @@ version_find_latest ()
|
|||
done
|
||||
echo "$a"
|
||||
}
|
||||
|
||||
gettext_quoted () {
|
||||
$gettext "$@" | sed "s/'/'\\\\''/g"
|
||||
}
|
||||
|
|
1340
util/grub-mkimage.c
Normal file
1340
util/grub-mkimage.c
Normal file
File diff suppressed because it is too large
Load diff
756
util/grub-mkimagexx.c
Normal file
756
util/grub-mkimagexx.c
Normal file
|
@ -0,0 +1,756 @@
|
|||
/* grub-mkimage.c - make a bootable image */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#undef ELF_R_SYM
|
||||
#undef ELF_R_TYPE
|
||||
|
||||
#if defined(MKIMAGE_ELF32)
|
||||
# define SUFFIX(x) x ## 32
|
||||
# define ELFCLASSXX ELFCLASS32
|
||||
# define Elf_Ehdr Elf32_Ehdr
|
||||
# define Elf_Phdr Elf32_Phdr
|
||||
# define Elf_Addr Elf32_Addr
|
||||
# define Elf_Sym Elf32_Sym
|
||||
# define Elf_Off Elf32_Off
|
||||
# define Elf_Shdr Elf32_Shdr
|
||||
# define Elf_Rela Elf32_Rela
|
||||
# define Elf_Rel Elf32_Rel
|
||||
# define ELF_R_SYM(val) ELF32_R_SYM(val)
|
||||
# define ELF_R_TYPE(val) ELF32_R_TYPE(val)
|
||||
#elif defined(MKIMAGE_ELF64)
|
||||
# define SUFFIX(x) x ## 64
|
||||
# define ELFCLASSXX ELFCLASS64
|
||||
# define Elf_Ehdr Elf64_Ehdr
|
||||
# define Elf_Phdr Elf64_Phdr
|
||||
# define Elf_Addr Elf64_Addr
|
||||
# define Elf_Sym Elf64_Sym
|
||||
# define Elf_Off Elf64_Off
|
||||
# define Elf_Shdr Elf64_Shdr
|
||||
# define Elf_Rela Elf64_Rela
|
||||
# define Elf_Rel Elf64_Rel
|
||||
# define ELF_R_SYM(val) ELF64_R_SYM(val)
|
||||
# define ELF_R_TYPE(val) ELF64_R_TYPE(val)
|
||||
#else
|
||||
#error "I'm confused"
|
||||
#endif
|
||||
|
||||
/* Relocate symbols; note that this function overwrites the symbol table.
|
||||
Return the address of a start symbol. */
|
||||
static Elf_Addr
|
||||
SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||
Elf_Shdr *symtab_section, Elf_Addr *section_addresses,
|
||||
Elf_Half section_entsize, Elf_Half num_sections,
|
||||
struct image_target_desc *image_target)
|
||||
{
|
||||
Elf_Word symtab_size, sym_size, num_syms;
|
||||
Elf_Off symtab_offset;
|
||||
Elf_Addr start_address = 0;
|
||||
Elf_Sym *sym;
|
||||
Elf_Word i;
|
||||
Elf_Shdr *strtab_section;
|
||||
const char *strtab;
|
||||
|
||||
strtab_section
|
||||
= (Elf_Shdr *) ((char *) sections
|
||||
+ (grub_target_to_host32 (symtab_section->sh_link)
|
||||
* section_entsize));
|
||||
strtab = (char *) e + grub_target_to_host (strtab_section->sh_offset);
|
||||
|
||||
symtab_size = grub_target_to_host (symtab_section->sh_size);
|
||||
sym_size = grub_target_to_host (symtab_section->sh_entsize);
|
||||
symtab_offset = grub_target_to_host (symtab_section->sh_offset);
|
||||
num_syms = symtab_size / sym_size;
|
||||
|
||||
for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
|
||||
i < num_syms;
|
||||
i++, sym = (Elf_Sym *) ((char *) sym + sym_size))
|
||||
{
|
||||
Elf_Section index;
|
||||
const char *name;
|
||||
|
||||
name = strtab + grub_target_to_host32 (sym->st_name);
|
||||
|
||||
index = grub_target_to_host16 (sym->st_shndx);
|
||||
if (index == STN_ABS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if ((index == STN_UNDEF))
|
||||
{
|
||||
if (sym->st_name)
|
||||
grub_util_error ("undefined symbol %s", name);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else if (index >= num_sections)
|
||||
grub_util_error ("section %d does not exist", index);
|
||||
|
||||
sym->st_value = (grub_target_to_host32 (sym->st_value)
|
||||
+ section_addresses[index]);
|
||||
grub_util_info ("locating %s at 0x%x", name, sym->st_value);
|
||||
|
||||
if (! start_address)
|
||||
if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0)
|
||||
start_address = sym->st_value;
|
||||
}
|
||||
|
||||
return start_address;
|
||||
}
|
||||
|
||||
/* Return the address of a symbol at the index I in the section S. */
|
||||
static Elf_Addr
|
||||
SUFFIX (get_symbol_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i,
|
||||
struct image_target_desc *image_target)
|
||||
{
|
||||
Elf_Sym *sym;
|
||||
|
||||
sym = (Elf_Sym *) ((char *) e
|
||||
+ grub_target_to_host32 (s->sh_offset)
|
||||
+ i * grub_target_to_host32 (s->sh_entsize));
|
||||
return sym->st_value;
|
||||
}
|
||||
|
||||
/* Return the address of a modified value. */
|
||||
static Elf_Addr *
|
||||
SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset,
|
||||
struct image_target_desc *image_target)
|
||||
{
|
||||
return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset);
|
||||
}
|
||||
|
||||
/* Deal with relocation information. This function relocates addresses
|
||||
within the virtual address space starting from 0. So only relative
|
||||
addresses can be fully resolved. Absolute addresses must be relocated
|
||||
again by a PE32 relocator when loaded. */
|
||||
static void
|
||||
SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||
Elf_Addr *section_addresses,
|
||||
Elf_Half section_entsize, Elf_Half num_sections,
|
||||
const char *strtab, struct image_target_desc *image_target)
|
||||
{
|
||||
Elf_Half i;
|
||||
Elf_Shdr *s;
|
||||
|
||||
for (i = 0, s = sections;
|
||||
i < num_sections;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
||||
if ((s->sh_type == grub_host_to_target32 (SHT_REL)) ||
|
||||
(s->sh_type == grub_host_to_target32 (SHT_RELA)))
|
||||
{
|
||||
Elf_Rela *r;
|
||||
Elf_Word rtab_size, r_size, num_rs;
|
||||
Elf_Off rtab_offset;
|
||||
Elf_Shdr *symtab_section;
|
||||
Elf_Word target_section_index;
|
||||
Elf_Addr target_section_addr;
|
||||
Elf_Shdr *target_section;
|
||||
Elf_Word j;
|
||||
|
||||
symtab_section = (Elf_Shdr *) ((char *) sections
|
||||
+ (grub_target_to_host32 (s->sh_link)
|
||||
* section_entsize));
|
||||
target_section_index = grub_target_to_host32 (s->sh_info);
|
||||
target_section_addr = section_addresses[target_section_index];
|
||||
target_section = (Elf_Shdr *) ((char *) sections
|
||||
+ (target_section_index
|
||||
* section_entsize));
|
||||
|
||||
grub_util_info ("dealing with the relocation section %s for %s",
|
||||
strtab + grub_target_to_host32 (s->sh_name),
|
||||
strtab + grub_target_to_host32 (target_section->sh_name));
|
||||
|
||||
rtab_size = grub_target_to_host32 (s->sh_size);
|
||||
r_size = grub_target_to_host32 (s->sh_entsize);
|
||||
rtab_offset = grub_target_to_host32 (s->sh_offset);
|
||||
num_rs = rtab_size / r_size;
|
||||
|
||||
for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset);
|
||||
j < num_rs;
|
||||
j++, r = (Elf_Rela *) ((char *) r + r_size))
|
||||
{
|
||||
Elf_Addr info;
|
||||
Elf_Addr offset;
|
||||
Elf_Addr sym_addr;
|
||||
Elf_Addr *target;
|
||||
Elf_Addr addend;
|
||||
|
||||
offset = grub_target_to_host (r->r_offset);
|
||||
target = SUFFIX (get_target_address) (e, target_section,
|
||||
offset, image_target);
|
||||
info = grub_target_to_host (r->r_info);
|
||||
sym_addr = SUFFIX (get_symbol_address) (e, symtab_section,
|
||||
ELF_R_SYM (info), image_target);
|
||||
|
||||
addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
|
||||
r->r_addend : 0;
|
||||
|
||||
if (image_target->voidp_sizeof == 4)
|
||||
switch (ELF_R_TYPE (info))
|
||||
{
|
||||
case R_386_NONE:
|
||||
break;
|
||||
|
||||
case R_386_32:
|
||||
/* This is absolute. */
|
||||
*target = grub_host_to_target32 (grub_target_to_host32 (*target)
|
||||
+ addend + sym_addr);
|
||||
grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x",
|
||||
*target, offset);
|
||||
break;
|
||||
|
||||
case R_386_PC32:
|
||||
/* This is relative. */
|
||||
*target = grub_host_to_target32 (grub_target_to_host32 (*target)
|
||||
+ addend + sym_addr
|
||||
- target_section_addr - offset
|
||||
- image_target->vaddr_offset);
|
||||
grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x",
|
||||
*target, offset);
|
||||
break;
|
||||
default:
|
||||
grub_util_error ("unknown relocation type %d",
|
||||
ELF_R_TYPE (info));
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (ELF_R_TYPE (info))
|
||||
{
|
||||
|
||||
case R_X86_64_NONE:
|
||||
break;
|
||||
|
||||
case R_X86_64_64:
|
||||
*target = grub_host_to_target64 (grub_target_to_host64 (*target)
|
||||
+ addend + sym_addr);
|
||||
grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx",
|
||||
*target, offset);
|
||||
break;
|
||||
|
||||
case R_X86_64_PC32:
|
||||
{
|
||||
grub_uint32_t *t32 = (grub_uint32_t *) target;
|
||||
*t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
|
||||
+ addend + sym_addr
|
||||
- target_section_addr - offset
|
||||
- image_target->vaddr_offset);
|
||||
grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx",
|
||||
*t32, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
case R_X86_64_32:
|
||||
case R_X86_64_32S:
|
||||
{
|
||||
grub_uint32_t *t32 = (grub_uint32_t *) target;
|
||||
*t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
|
||||
+ addend + sym_addr);
|
||||
grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx",
|
||||
*t32, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
grub_util_error ("unknown relocation type %d",
|
||||
ELF_R_TYPE (info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a PE32's fixup entry for a relocation. Return the resulting address
|
||||
after having written to the file OUT. */
|
||||
static Elf_Addr
|
||||
SUFFIX (add_fixup_entry) (struct fixup_block_list **cblock, grub_uint16_t type,
|
||||
Elf_Addr addr, int flush, Elf_Addr current_address,
|
||||
struct image_target_desc *image_target)
|
||||
{
|
||||
struct grub_pe32_fixup_block *b;
|
||||
|
||||
b = &((*cblock)->b);
|
||||
|
||||
/* First, check if it is necessary to write out the current block. */
|
||||
if ((*cblock)->state)
|
||||
{
|
||||
if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr)
|
||||
{
|
||||
grub_uint32_t size;
|
||||
|
||||
if (flush)
|
||||
{
|
||||
/* Add as much padding as necessary to align the address
|
||||
with a section boundary. */
|
||||
Elf_Addr next_address;
|
||||
unsigned padding_size;
|
||||
size_t index;
|
||||
|
||||
next_address = current_address + b->block_size;
|
||||
padding_size = ((ALIGN_UP (next_address, image_target->section_align)
|
||||
- next_address)
|
||||
>> 1);
|
||||
index = ((b->block_size - sizeof (*b)) >> 1);
|
||||
grub_util_info ("adding %d padding fixup entries", padding_size);
|
||||
while (padding_size--)
|
||||
{
|
||||
b->entries[index++] = 0;
|
||||
b->block_size += 2;
|
||||
}
|
||||
}
|
||||
else if (b->block_size & (8 - 1))
|
||||
{
|
||||
/* If not aligned with a 32-bit boundary, add
|
||||
a padding entry. */
|
||||
size_t index;
|
||||
|
||||
grub_util_info ("adding a padding fixup entry");
|
||||
index = ((b->block_size - sizeof (*b)) >> 1);
|
||||
b->entries[index] = 0;
|
||||
b->block_size += 2;
|
||||
}
|
||||
|
||||
/* Flush it. */
|
||||
grub_util_info ("writing %d bytes of a fixup block starting at 0x%x",
|
||||
b->block_size, b->page_rva);
|
||||
size = b->block_size;
|
||||
current_address += size;
|
||||
b->page_rva = grub_host_to_target32 (b->page_rva);
|
||||
b->block_size = grub_host_to_target32 (b->block_size);
|
||||
(*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000);
|
||||
memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000);
|
||||
*cblock = (*cblock)->next;
|
||||
}
|
||||
}
|
||||
|
||||
b = &((*cblock)->b);
|
||||
|
||||
if (! flush)
|
||||
{
|
||||
grub_uint16_t entry;
|
||||
size_t index;
|
||||
|
||||
/* If not allocated yet, allocate a block with enough entries. */
|
||||
if (! (*cblock)->state)
|
||||
{
|
||||
(*cblock)->state = 1;
|
||||
|
||||
/* The spec does not mention the requirement of a Page RVA.
|
||||
Here, align the address with a 4K boundary for safety. */
|
||||
b->page_rva = (addr & ~(0x1000 - 1));
|
||||
b->block_size = sizeof (*b);
|
||||
}
|
||||
|
||||
/* Sanity check. */
|
||||
if (b->block_size >= sizeof (*b) + 2 * 0x1000)
|
||||
grub_util_error ("too many fixup entries");
|
||||
|
||||
/* Add a new entry. */
|
||||
index = ((b->block_size - sizeof (*b)) >> 1);
|
||||
entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva);
|
||||
b->entries[index] = grub_host_to_target16 (entry);
|
||||
b->block_size += 2;
|
||||
}
|
||||
|
||||
return current_address;
|
||||
}
|
||||
|
||||
/* Make a .reloc section. */
|
||||
static Elf_Addr
|
||||
SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out,
|
||||
Elf_Addr *section_addresses, Elf_Shdr *sections,
|
||||
Elf_Half section_entsize, Elf_Half num_sections,
|
||||
const char *strtab, struct image_target_desc *image_target)
|
||||
{
|
||||
Elf_Half i;
|
||||
Elf_Shdr *s;
|
||||
struct fixup_block_list *lst, *lst0;
|
||||
Elf_Addr current_address = 0;
|
||||
|
||||
lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000);
|
||||
memset (lst, 0, sizeof (*lst) + 2 * 0x1000);
|
||||
|
||||
for (i = 0, s = sections;
|
||||
i < num_sections;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
||||
if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) ||
|
||||
(s->sh_type == grub_cpu_to_le32 (SHT_RELA)))
|
||||
{
|
||||
Elf_Rel *r;
|
||||
Elf_Word rtab_size, r_size, num_rs;
|
||||
Elf_Off rtab_offset;
|
||||
Elf_Addr section_address;
|
||||
Elf_Word j;
|
||||
|
||||
grub_util_info ("translating the relocation section %s",
|
||||
strtab + grub_le_to_cpu32 (s->sh_name));
|
||||
|
||||
rtab_size = grub_le_to_cpu32 (s->sh_size);
|
||||
r_size = grub_le_to_cpu32 (s->sh_entsize);
|
||||
rtab_offset = grub_le_to_cpu32 (s->sh_offset);
|
||||
num_rs = rtab_size / r_size;
|
||||
|
||||
section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)];
|
||||
|
||||
for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset);
|
||||
j < num_rs;
|
||||
j++, r = (Elf_Rel *) ((char *) r + r_size))
|
||||
{
|
||||
Elf_Addr info;
|
||||
Elf_Addr offset;
|
||||
|
||||
offset = grub_le_to_cpu32 (r->r_offset);
|
||||
info = grub_le_to_cpu32 (r->r_info);
|
||||
|
||||
/* Necessary to relocate only absolute addresses. */
|
||||
if (image_target->voidp_sizeof == 4)
|
||||
{
|
||||
if (ELF_R_TYPE (info) == R_386_32)
|
||||
{
|
||||
Elf_Addr addr;
|
||||
|
||||
addr = section_address + offset;
|
||||
grub_util_info ("adding a relocation entry for 0x%x", addr);
|
||||
current_address
|
||||
= SUFFIX (add_fixup_entry) (&lst,
|
||||
GRUB_PE32_REL_BASED_HIGHLOW,
|
||||
addr, 0, current_address,
|
||||
image_target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ELF_R_TYPE (info) == R_X86_64_32) ||
|
||||
(ELF_R_TYPE (info) == R_X86_64_32S))
|
||||
{
|
||||
grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)");
|
||||
}
|
||||
else if (ELF_R_TYPE (info) == R_X86_64_64)
|
||||
{
|
||||
Elf_Addr addr;
|
||||
|
||||
addr = section_address + offset;
|
||||
grub_util_info ("adding a relocation entry for 0x%llx", addr);
|
||||
current_address
|
||||
= SUFFIX (add_fixup_entry) (&lst,
|
||||
GRUB_PE32_REL_BASED_DIR64,
|
||||
addr,
|
||||
0, current_address,
|
||||
image_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_address = SUFFIX (add_fixup_entry) (&lst, 0, 0, 1, current_address, image_target);
|
||||
|
||||
{
|
||||
grub_uint8_t *ptr;
|
||||
ptr = *out = xmalloc (current_address);
|
||||
for (lst = lst0; lst; lst = lst->next)
|
||||
if (lst->state)
|
||||
{
|
||||
memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size));
|
||||
ptr += grub_target_to_host32 (lst->b.block_size);
|
||||
}
|
||||
if (current_address + *out != ptr)
|
||||
{
|
||||
grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out,
|
||||
current_address);
|
||||
}
|
||||
}
|
||||
|
||||
return current_address;
|
||||
}
|
||||
|
||||
/* Determine if this section is a text section. Return false if this
|
||||
section is not allocated. */
|
||||
static int
|
||||
SUFFIX (is_text_section) (Elf_Shdr *s, struct image_target_desc *image_target)
|
||||
{
|
||||
if (image_target->id != IMAGE_EFI
|
||||
&& grub_target_to_host32 (s->sh_type) != SHT_PROGBITS)
|
||||
return 0;
|
||||
return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC))
|
||||
== (SHF_EXECINSTR | SHF_ALLOC));
|
||||
}
|
||||
|
||||
/* Determine if this section is a data section. This assumes that
|
||||
BSS is also a data section, since the converter initializes BSS
|
||||
when producing PE32 to avoid a bug in EFI implementations. */
|
||||
static int
|
||||
SUFFIX (is_data_section) (Elf_Shdr *s, struct image_target_desc *image_target)
|
||||
{
|
||||
if (image_target->id != IMAGE_EFI
|
||||
&& grub_target_to_host32 (s->sh_type) != SHT_PROGBITS)
|
||||
return 0;
|
||||
return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC))
|
||||
== SHF_ALLOC);
|
||||
}
|
||||
|
||||
/* Return if the ELF header is valid. */
|
||||
static int
|
||||
SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target)
|
||||
{
|
||||
if (size < sizeof (*e)
|
||||
|| e->e_ident[EI_MAG0] != ELFMAG0
|
||||
|| e->e_ident[EI_MAG1] != ELFMAG1
|
||||
|| e->e_ident[EI_MAG2] != ELFMAG2
|
||||
|| e->e_ident[EI_MAG3] != ELFMAG3
|
||||
|| e->e_ident[EI_VERSION] != EV_CURRENT
|
||||
|| e->e_ident[EI_CLASS] != ELFCLASSXX
|
||||
|| e->e_version != grub_host_to_target32 (EV_CURRENT))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Locate section addresses by merging code sections and data sections
|
||||
into .text and .data, respectively. Return the array of section
|
||||
addresses. */
|
||||
static Elf_Addr *
|
||||
SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize,
|
||||
Elf_Half num_sections, const char *strtab,
|
||||
grub_size_t *exec_size, grub_size_t *kernel_sz,
|
||||
grub_size_t *all_align,
|
||||
struct image_target_desc *image_target)
|
||||
{
|
||||
int i;
|
||||
Elf_Addr current_address;
|
||||
Elf_Addr *section_addresses;
|
||||
Elf_Shdr *s;
|
||||
|
||||
*all_align = 1;
|
||||
|
||||
section_addresses = xmalloc (sizeof (*section_addresses) * num_sections);
|
||||
memset (section_addresses, 0, sizeof (*section_addresses) * num_sections);
|
||||
|
||||
current_address = 0;
|
||||
|
||||
for (i = 0, s = sections;
|
||||
i < num_sections;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
||||
if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC)
|
||||
&& grub_host_to_target32 (s->sh_addralign) > *all_align)
|
||||
*all_align = grub_host_to_target32 (s->sh_addralign);
|
||||
|
||||
|
||||
/* .text */
|
||||
for (i = 0, s = sections;
|
||||
i < num_sections;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
||||
if (SUFFIX (is_text_section) (s, image_target))
|
||||
{
|
||||
Elf_Word align = grub_host_to_target32 (s->sh_addralign);
|
||||
const char *name = strtab + grub_host_to_target32 (s->sh_name);
|
||||
if (align)
|
||||
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
|
||||
align) - image_target->vaddr_offset;
|
||||
grub_util_info ("locating the section %s at 0x%x",
|
||||
name, current_address);
|
||||
section_addresses[i] = current_address;
|
||||
current_address += grub_host_to_target_addr (s->sh_size);
|
||||
}
|
||||
|
||||
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
|
||||
image_target->section_align)
|
||||
- image_target->vaddr_offset;
|
||||
*exec_size = current_address;
|
||||
|
||||
/* .data */
|
||||
for (i = 0, s = sections;
|
||||
i < num_sections;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
||||
if (SUFFIX (is_data_section) (s, image_target))
|
||||
{
|
||||
Elf_Word align = grub_host_to_target32 (s->sh_addralign);
|
||||
const char *name = strtab + grub_host_to_target32 (s->sh_name);
|
||||
|
||||
if (align)
|
||||
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
|
||||
align)
|
||||
- image_target->vaddr_offset;
|
||||
|
||||
grub_util_info ("locating the section %s at 0x%x",
|
||||
name, current_address);
|
||||
section_addresses[i] = current_address;
|
||||
current_address += grub_host_to_target_addr (s->sh_size);
|
||||
}
|
||||
|
||||
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
|
||||
image_target->section_align) - image_target->vaddr_offset;
|
||||
*kernel_sz = current_address;
|
||||
return section_addresses;
|
||||
}
|
||||
|
||||
static char *
|
||||
SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size,
|
||||
grub_size_t *kernel_sz, grub_size_t *bss_size,
|
||||
grub_size_t total_module_size, grub_uint64_t *start,
|
||||
void **reloc_section, grub_size_t *reloc_size,
|
||||
grub_size_t *align,
|
||||
struct image_target_desc *image_target)
|
||||
{
|
||||
char *kernel_img, *out_img;
|
||||
const char *strtab;
|
||||
Elf_Ehdr *e;
|
||||
Elf_Shdr *sections;
|
||||
Elf_Addr *section_addresses;
|
||||
Elf_Addr *section_vaddresses;
|
||||
int i;
|
||||
Elf_Shdr *s;
|
||||
Elf_Half num_sections;
|
||||
Elf_Off section_offset;
|
||||
Elf_Half section_entsize;
|
||||
grub_size_t kernel_size;
|
||||
Elf_Shdr *symtab_section;
|
||||
|
||||
*start = 0;
|
||||
|
||||
kernel_size = grub_util_get_image_size (kernel_path);
|
||||
kernel_img = xmalloc (kernel_size);
|
||||
grub_util_load_image (kernel_path, kernel_img);
|
||||
|
||||
e = (Elf_Ehdr *) kernel_img;
|
||||
if (! SUFFIX (check_elf_header) (e, kernel_size, image_target))
|
||||
grub_util_error ("invalid ELF header");
|
||||
|
||||
section_offset = grub_target_to_host (e->e_shoff);
|
||||
section_entsize = grub_target_to_host16 (e->e_shentsize);
|
||||
num_sections = grub_target_to_host16 (e->e_shnum);
|
||||
|
||||
if (kernel_size < section_offset + section_entsize * num_sections)
|
||||
grub_util_error ("invalid ELF format");
|
||||
|
||||
sections = (Elf_Shdr *) (kernel_img + section_offset);
|
||||
|
||||
/* Relocate sections then symbols in the virtual address space. */
|
||||
s = (Elf_Shdr *) ((char *) sections
|
||||
+ grub_host_to_target16 (e->e_shstrndx) * section_entsize);
|
||||
strtab = (char *) e + grub_host_to_target32 (s->sh_offset);
|
||||
|
||||
section_addresses = SUFFIX (locate_sections) (sections, section_entsize,
|
||||
num_sections, strtab,
|
||||
exec_size, kernel_sz, align,
|
||||
image_target);
|
||||
|
||||
section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections);
|
||||
|
||||
for (i = 0; i < num_sections; i++)
|
||||
section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset;
|
||||
|
||||
if (image_target->id != IMAGE_EFI)
|
||||
{
|
||||
Elf_Addr current_address = *kernel_sz;
|
||||
|
||||
for (i = 0, s = sections;
|
||||
i < num_sections;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
||||
if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
|
||||
{
|
||||
Elf_Word align = grub_host_to_target32 (s->sh_addralign);
|
||||
const char *name = strtab + grub_host_to_target32 (s->sh_name);
|
||||
|
||||
if (align)
|
||||
current_address = ALIGN_UP (current_address
|
||||
+ image_target->vaddr_offset, align)
|
||||
- image_target->vaddr_offset;
|
||||
|
||||
grub_util_info ("locating the section %s at 0x%x",
|
||||
name, current_address);
|
||||
section_vaddresses[i] = current_address
|
||||
+ image_target->vaddr_offset;
|
||||
current_address += grub_host_to_target_addr (s->sh_size);
|
||||
}
|
||||
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
|
||||
image_target->section_align)
|
||||
- image_target->vaddr_offset;
|
||||
*bss_size = current_address - *kernel_sz;
|
||||
}
|
||||
else
|
||||
*bss_size = 0;
|
||||
|
||||
if (image_target->id == IMAGE_EFI)
|
||||
{
|
||||
symtab_section = NULL;
|
||||
for (i = 0, s = sections;
|
||||
i < num_sections;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
||||
if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB))
|
||||
{
|
||||
symtab_section = s;
|
||||
break;
|
||||
}
|
||||
|
||||
if (! symtab_section)
|
||||
grub_util_error ("no symbol table");
|
||||
|
||||
*start = SUFFIX (relocate_symbols) (e, sections, symtab_section,
|
||||
section_vaddresses, section_entsize,
|
||||
num_sections, image_target);
|
||||
if (*start == 0)
|
||||
grub_util_error ("start symbol is not defined");
|
||||
|
||||
/* Resolve addresses in the virtual address space. */
|
||||
SUFFIX (relocate_addresses) (e, sections, section_addresses, section_entsize,
|
||||
num_sections, strtab, image_target);
|
||||
|
||||
*reloc_size = SUFFIX (make_reloc_section) (e, reloc_section,
|
||||
section_vaddresses, sections,
|
||||
section_entsize, num_sections,
|
||||
strtab, image_target);
|
||||
}
|
||||
else
|
||||
{
|
||||
*reloc_size = 0;
|
||||
*reloc_section = NULL;
|
||||
}
|
||||
|
||||
out_img = xmalloc (*kernel_sz + total_module_size);
|
||||
|
||||
for (i = 0, s = sections;
|
||||
i < num_sections;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
||||
if (SUFFIX (is_data_section) (s, image_target)
|
||||
|| SUFFIX (is_text_section) (s, image_target))
|
||||
{
|
||||
if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
|
||||
memset (out_img + section_addresses[i], 0,
|
||||
grub_host_to_target_addr (s->sh_size));
|
||||
else
|
||||
memcpy (out_img + section_addresses[i],
|
||||
kernel_img + grub_host_to_target_addr (s->sh_offset),
|
||||
grub_host_to_target_addr (s->sh_size));
|
||||
}
|
||||
free (kernel_img);
|
||||
|
||||
return out_img;
|
||||
}
|
||||
|
||||
|
||||
#undef SUFFIX
|
||||
#undef ELFCLASSXX
|
||||
#undef Elf_Ehdr
|
||||
#undef Elf_Phdr
|
||||
#undef Elf_Shdr
|
||||
#undef Elf_Addr
|
||||
#undef Elf_Sym
|
||||
#undef Elf_Off
|
||||
#undef Elf_Rela
|
||||
#undef Elf_Rel
|
||||
#undef ELF_R_TYPE
|
||||
#undef ELF_R_SYM
|
|
@ -1,648 +0,0 @@
|
|||
/* grub-mkimage.c - make a bootable image */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/machine/boot.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/elf.h>
|
||||
#include <grub/aout.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/kernel.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/util/misc.h>
|
||||
#include <grub/util/resolve.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#include <getopt.h>
|
||||
|
||||
#include "progname.h"
|
||||
|
||||
#define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P))
|
||||
|
||||
#ifdef ENABLE_LZMA
|
||||
#include <grub/lib/LzmaEnc.h>
|
||||
|
||||
static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); }
|
||||
static void SzFree(void *p, void *address) { p = p; free(address); }
|
||||
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
|
||||
static void
|
||||
compress_kernel (char *kernel_img, size_t kernel_size,
|
||||
char **core_img, size_t *core_size)
|
||||
{
|
||||
CLzmaEncProps props;
|
||||
unsigned char out_props[5];
|
||||
size_t out_props_size = 5;
|
||||
|
||||
LzmaEncProps_Init(&props);
|
||||
props.dictSize = 1 << 16;
|
||||
props.lc = 3;
|
||||
props.lp = 0;
|
||||
props.pb = 2;
|
||||
props.numThreads = 1;
|
||||
|
||||
if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE)
|
||||
grub_util_error (_("the core image is too small"));
|
||||
|
||||
*core_img = xmalloc (kernel_size);
|
||||
memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE);
|
||||
|
||||
*core_size = kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE;
|
||||
if (LzmaEncode((unsigned char *) *core_img + GRUB_KERNEL_MACHINE_RAW_SIZE,
|
||||
core_size,
|
||||
(unsigned char *) kernel_img + GRUB_KERNEL_MACHINE_RAW_SIZE,
|
||||
kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE,
|
||||
&props, out_props, &out_props_size,
|
||||
0, NULL, &g_Alloc, &g_Alloc) != SZ_OK)
|
||||
grub_util_error (_("cannot compress the kernel image"));
|
||||
|
||||
*core_size += GRUB_KERNEL_MACHINE_RAW_SIZE;
|
||||
}
|
||||
|
||||
#else /* No lzma compression */
|
||||
|
||||
static void
|
||||
compress_kernel (char *kernel_img, size_t kernel_size,
|
||||
char **core_img, size_t *core_size)
|
||||
{
|
||||
*core_img = xmalloc (kernel_size);
|
||||
memcpy (*core_img, kernel_img, kernel_size);
|
||||
*core_size = kernel_size;
|
||||
}
|
||||
|
||||
#endif /* No lzma compression */
|
||||
|
||||
static void
|
||||
generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
|
||||
char *memdisk_path, char *font_path, char *config_path,
|
||||
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
|
||||
grub_platform_image_format_t format
|
||||
#else
|
||||
int dummy __attribute__ ((unused))
|
||||
#endif
|
||||
|
||||
)
|
||||
{
|
||||
char *kernel_img, *core_img;
|
||||
size_t kernel_size, total_module_size, core_size;
|
||||
size_t memdisk_size = 0, font_size = 0, config_size = 0, config_size_pure = 0;
|
||||
char *kernel_path;
|
||||
size_t offset;
|
||||
struct grub_util_path_list *path_list, *p, *next;
|
||||
struct grub_module_info *modinfo;
|
||||
|
||||
path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
|
||||
|
||||
kernel_path = grub_util_get_path (dir, "kernel.img");
|
||||
kernel_size = grub_util_get_image_size (kernel_path);
|
||||
|
||||
total_module_size = sizeof (struct grub_module_info);
|
||||
|
||||
if (memdisk_path)
|
||||
{
|
||||
memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
|
||||
grub_util_info ("the size of memory disk is 0x%x", memdisk_size);
|
||||
total_module_size += memdisk_size + sizeof (struct grub_module_header);
|
||||
}
|
||||
|
||||
if (font_path)
|
||||
{
|
||||
font_size = ALIGN_ADDR (grub_util_get_image_size (font_path));
|
||||
total_module_size += font_size + sizeof (struct grub_module_header);
|
||||
}
|
||||
|
||||
if (config_path)
|
||||
{
|
||||
config_size_pure = grub_util_get_image_size (config_path) + 1;
|
||||
config_size = ALIGN_ADDR (config_size_pure);
|
||||
grub_util_info ("the size of config file is 0x%x", config_size);
|
||||
total_module_size += config_size + sizeof (struct grub_module_header);
|
||||
}
|
||||
|
||||
for (p = path_list; p; p = p->next)
|
||||
total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name))
|
||||
+ sizeof (struct grub_module_header));
|
||||
|
||||
grub_util_info ("the total module size is 0x%x", total_module_size);
|
||||
|
||||
kernel_img = xmalloc (kernel_size + total_module_size);
|
||||
grub_util_load_image (kernel_path, kernel_img);
|
||||
|
||||
if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END)
|
||||
grub_util_error (_("prefix is too long"));
|
||||
strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix);
|
||||
|
||||
/* Fill in the grub_module_info structure. */
|
||||
modinfo = (struct grub_module_info *) (kernel_img + kernel_size);
|
||||
memset (modinfo, 0, sizeof (struct grub_module_info));
|
||||
modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
|
||||
modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info));
|
||||
modinfo->size = grub_host_to_target_addr (total_module_size);
|
||||
|
||||
offset = kernel_size + sizeof (struct grub_module_info);
|
||||
for (p = path_list; p; p = p->next)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
size_t mod_size, orig_size;
|
||||
|
||||
orig_size = grub_util_get_image_size (p->name);
|
||||
mod_size = ALIGN_ADDR (orig_size);
|
||||
|
||||
header = (struct grub_module_header *) (kernel_img + offset);
|
||||
memset (header, 0, sizeof (struct grub_module_header));
|
||||
header->type = grub_host_to_target32 (OBJ_TYPE_ELF);
|
||||
header->size = grub_host_to_target32 (mod_size + sizeof (*header));
|
||||
offset += sizeof (*header);
|
||||
memset (kernel_img + offset + orig_size, 0, mod_size - orig_size);
|
||||
|
||||
grub_util_load_image (p->name, kernel_img + offset);
|
||||
offset += mod_size;
|
||||
}
|
||||
|
||||
if (memdisk_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
|
||||
header = (struct grub_module_header *) (kernel_img + offset);
|
||||
memset (header, 0, sizeof (struct grub_module_header));
|
||||
header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK);
|
||||
header->size = grub_host_to_target32 (memdisk_size + sizeof (*header));
|
||||
offset += sizeof (*header);
|
||||
|
||||
grub_util_load_image (memdisk_path, kernel_img + offset);
|
||||
offset += memdisk_size;
|
||||
}
|
||||
|
||||
if (font_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
|
||||
header = (struct grub_module_header *) (kernel_img + offset);
|
||||
memset (header, 0, sizeof (struct grub_module_header));
|
||||
header->type = grub_host_to_target32 (OBJ_TYPE_FONT);
|
||||
header->size = grub_host_to_target32 (font_size + sizeof (*header));
|
||||
offset += sizeof (*header);
|
||||
|
||||
grub_util_load_image (font_path, kernel_img + offset);
|
||||
offset += font_size;
|
||||
}
|
||||
|
||||
if (config_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
|
||||
header = (struct grub_module_header *) (kernel_img + offset);
|
||||
memset (header, 0, sizeof (struct grub_module_header));
|
||||
header->type = grub_host_to_target32 (OBJ_TYPE_CONFIG);
|
||||
header->size = grub_host_to_target32 (config_size + sizeof (*header));
|
||||
offset += sizeof (*header);
|
||||
|
||||
grub_util_load_image (config_path, kernel_img + offset);
|
||||
*(kernel_img + offset + config_size_pure - 1) = 0;
|
||||
offset += config_size;
|
||||
}
|
||||
|
||||
grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
|
||||
compress_kernel (kernel_img, kernel_size + total_module_size,
|
||||
&core_img, &core_size);
|
||||
|
||||
grub_util_info ("the core size is 0x%x", core_size);
|
||||
|
||||
#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
|
||||
*((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE))
|
||||
= grub_host_to_target32 (total_module_size);
|
||||
#endif
|
||||
*((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE))
|
||||
= grub_host_to_target32 (kernel_size);
|
||||
#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
|
||||
*((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE))
|
||||
= grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
|
||||
#endif
|
||||
|
||||
#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
|
||||
/* If we included a drive in our prefix, let GRUB know it doesn't have to
|
||||
prepend the drive told by BIOS. */
|
||||
if (prefix[0] == '(')
|
||||
{
|
||||
*((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART))
|
||||
= grub_host_to_target32 (-2);
|
||||
*((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART))
|
||||
= grub_host_to_target32 (-2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER)
|
||||
grub_util_error (_("core image is too big (%p > %p)"),
|
||||
GRUB_KERNEL_MACHINE_LINK_ADDR + core_size,
|
||||
GRUB_MEMORY_MACHINE_UPPER);
|
||||
#endif
|
||||
|
||||
#if defined(GRUB_MACHINE_PCBIOS)
|
||||
{
|
||||
unsigned num;
|
||||
char *boot_path, *boot_img;
|
||||
size_t boot_size;
|
||||
num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
|
||||
if (num > 0xffff)
|
||||
grub_util_error (_("the core image is too big"));
|
||||
|
||||
boot_path = grub_util_get_path (dir, "diskboot.img");
|
||||
boot_size = grub_util_get_image_size (boot_path);
|
||||
if (boot_size != GRUB_DISK_SECTOR_SIZE)
|
||||
grub_util_error (_("diskboot.img size must be %u bytes"),
|
||||
GRUB_DISK_SECTOR_SIZE);
|
||||
|
||||
boot_img = grub_util_read_image (boot_path);
|
||||
|
||||
{
|
||||
struct grub_boot_blocklist *block;
|
||||
block = (struct grub_boot_blocklist *) (boot_img
|
||||
+ GRUB_DISK_SECTOR_SIZE
|
||||
- sizeof (*block));
|
||||
block->len = grub_host_to_target16 (num);
|
||||
|
||||
/* This is filled elsewhere. Verify it just in case. */
|
||||
assert (block->segment
|
||||
== grub_host_to_target16 (GRUB_BOOT_MACHINE_KERNEL_SEG
|
||||
+ (GRUB_DISK_SECTOR_SIZE >> 4)));
|
||||
}
|
||||
|
||||
grub_util_write_image (boot_img, boot_size, out);
|
||||
free (boot_img);
|
||||
free (boot_path);
|
||||
}
|
||||
#elif defined(GRUB_MACHINE_QEMU)
|
||||
{
|
||||
char *rom_img;
|
||||
size_t rom_size;
|
||||
char *boot_path, *boot_img;
|
||||
size_t boot_size;
|
||||
|
||||
boot_path = grub_util_get_path (dir, "boot.img");
|
||||
boot_size = grub_util_get_image_size (boot_path);
|
||||
boot_img = grub_util_read_image (boot_path);
|
||||
|
||||
/* Rom sizes must be 64k-aligned. */
|
||||
rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024);
|
||||
|
||||
rom_img = xmalloc (rom_size);
|
||||
memset (rom_img, 0, rom_size);
|
||||
|
||||
*((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR))
|
||||
= grub_host_to_target32 ((grub_uint32_t) -rom_size);
|
||||
|
||||
memcpy (rom_img, core_img, core_size);
|
||||
|
||||
*((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR))
|
||||
= grub_host_to_target32 ((grub_uint32_t) -rom_size);
|
||||
|
||||
memcpy (rom_img + rom_size - boot_size, boot_img, boot_size);
|
||||
|
||||
free (core_img);
|
||||
core_img = rom_img;
|
||||
core_size = rom_size;
|
||||
|
||||
free (boot_img);
|
||||
free (boot_path);
|
||||
}
|
||||
#elif defined (GRUB_MACHINE_SPARC64)
|
||||
if (format == GRUB_PLATFORM_IMAGE_AOUT)
|
||||
{
|
||||
void *aout_img;
|
||||
size_t aout_size;
|
||||
struct grub_aout32_header *aout_head;
|
||||
|
||||
aout_size = core_size + sizeof (*aout_head);
|
||||
aout_img = xmalloc (aout_size);
|
||||
aout_head = aout_img;
|
||||
aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16)
|
||||
| AOUT32_OMAGIC);
|
||||
aout_head->a_text = grub_host_to_target32 (core_size);
|
||||
aout_head->a_entry
|
||||
= grub_host_to_target32 (GRUB_BOOT_MACHINE_IMAGE_ADDRESS);
|
||||
memcpy (aout_img + sizeof (*aout_head), core_img, core_size);
|
||||
|
||||
free (core_img);
|
||||
core_img = aout_img;
|
||||
core_size = aout_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int num;
|
||||
char *boot_path, *boot_img;
|
||||
size_t boot_size;
|
||||
|
||||
num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
|
||||
num <<= GRUB_DISK_SECTOR_BITS;
|
||||
|
||||
boot_path = grub_util_get_path (dir, "diskboot.img");
|
||||
boot_size = grub_util_get_image_size (boot_path);
|
||||
if (boot_size != GRUB_DISK_SECTOR_SIZE)
|
||||
grub_util_error ("diskboot.img is not one sector size");
|
||||
|
||||
boot_img = grub_util_read_image (boot_path);
|
||||
|
||||
*((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE
|
||||
- GRUB_BOOT_MACHINE_LIST_SIZE + 8))
|
||||
= grub_host_to_target32 (num);
|
||||
|
||||
grub_util_write_image (boot_img, boot_size, out);
|
||||
free (boot_img);
|
||||
free (boot_path);
|
||||
}
|
||||
#elif defined(GRUB_MACHINE_MIPS)
|
||||
if (format == GRUB_PLATFORM_IMAGE_ELF)
|
||||
{
|
||||
char *elf_img;
|
||||
size_t program_size;
|
||||
Elf32_Ehdr *ehdr;
|
||||
Elf32_Phdr *phdr;
|
||||
grub_uint32_t target_addr;
|
||||
|
||||
program_size = ALIGN_ADDR (core_size);
|
||||
|
||||
elf_img = xmalloc (program_size + sizeof (*ehdr) + sizeof (*phdr));
|
||||
memset (elf_img, 0, program_size + sizeof (*ehdr) + sizeof (*phdr));
|
||||
memcpy (elf_img + sizeof (*ehdr) + sizeof (*phdr), core_img, core_size);
|
||||
ehdr = (void *) elf_img;
|
||||
phdr = (void *) (elf_img + sizeof (*ehdr));
|
||||
memcpy (ehdr->e_ident, ELFMAG, SELFMAG);
|
||||
ehdr->e_ident[EI_CLASS] = ELFCLASS32;
|
||||
#ifdef GRUB_CPU_MIPSEL
|
||||
ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
|
||||
#else
|
||||
ehdr->e_ident[EI_DATA] = ELFDATA2MSB;
|
||||
#endif
|
||||
ehdr->e_ident[EI_VERSION] = EV_CURRENT;
|
||||
ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
|
||||
ehdr->e_type = grub_host_to_target16 (ET_EXEC);
|
||||
ehdr->e_machine = grub_host_to_target16 (EM_MIPS);
|
||||
ehdr->e_version = grub_host_to_target32 (EV_CURRENT);
|
||||
|
||||
ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr);
|
||||
ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr));
|
||||
ehdr->e_phnum = grub_host_to_target16 (1);
|
||||
|
||||
/* No section headers. */
|
||||
ehdr->e_shoff = grub_host_to_target32 (0);
|
||||
ehdr->e_shentsize = grub_host_to_target16 (0);
|
||||
ehdr->e_shnum = grub_host_to_target16 (0);
|
||||
ehdr->e_shstrndx = grub_host_to_target16 (0);
|
||||
|
||||
ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr));
|
||||
|
||||
phdr->p_type = grub_host_to_target32 (PT_LOAD);
|
||||
phdr->p_offset = grub_host_to_target32 (sizeof (*ehdr) + sizeof (*phdr));
|
||||
phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
|
||||
|
||||
target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR
|
||||
+ kernel_size + total_module_size, 32);
|
||||
ehdr->e_entry = grub_host_to_target32 (target_addr);
|
||||
phdr->p_vaddr = grub_host_to_target32 (target_addr);
|
||||
phdr->p_paddr = grub_host_to_target32 (target_addr);
|
||||
phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN);
|
||||
ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER
|
||||
| EF_MIPS_PIC | EF_MIPS_CPIC);
|
||||
phdr->p_filesz = grub_host_to_target32 (core_size);
|
||||
phdr->p_memsz = grub_host_to_target32 (core_size);
|
||||
|
||||
free (core_img);
|
||||
core_img = elf_img;
|
||||
core_size = program_size + sizeof (*ehdr) + sizeof (*phdr);
|
||||
}
|
||||
#endif
|
||||
|
||||
grub_util_write_image (core_img, core_size, out);
|
||||
free (kernel_img);
|
||||
free (core_img);
|
||||
free (kernel_path);
|
||||
|
||||
while (path_list)
|
||||
{
|
||||
next = path_list->next;
|
||||
free ((void *) path_list->name);
|
||||
free (path_list);
|
||||
path_list = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct option options[] =
|
||||
{
|
||||
{"directory", required_argument, 0, 'd'},
|
||||
{"prefix", required_argument, 0, 'p'},
|
||||
{"memdisk", required_argument, 0, 'm'},
|
||||
{"font", required_argument, 0, 'f'},
|
||||
{"config", required_argument, 0, 'c'},
|
||||
{"output", required_argument, 0, 'o'},
|
||||
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
|
||||
{"format", required_argument, 0, 'O'},
|
||||
#endif
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
if (status)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name);
|
||||
else
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... [MODULES]\n\
|
||||
\n\
|
||||
Make a bootable image of GRUB.\n\
|
||||
\n\
|
||||
-d, --directory=DIR use images and modules under DIR [default=%s]\n\
|
||||
-p, --prefix=DIR set grub_prefix directory [default=%s]\n\
|
||||
-m, --memdisk=FILE embed FILE as a memdisk image\n\
|
||||
-f, --font=FILE embed FILE as a boot font\n\
|
||||
-c, --config=FILE embed FILE as boot config\n\
|
||||
-o, --output=FILE output a generated image to FILE [default=stdout]\n"
|
||||
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
|
||||
"\
|
||||
-O, --format=FORMAT generate an image in format [default=%s]\n\
|
||||
available formats: %s\n"
|
||||
#endif
|
||||
"\
|
||||
-h, --help display this message and exit\n\
|
||||
-V, --version print version information and exit\n\
|
||||
-v, --verbose print verbose messages\n\
|
||||
\n\
|
||||
Report bugs to <%s>.\n\
|
||||
"),
|
||||
program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY,
|
||||
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
|
||||
GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT, GRUB_PLATFORM_IMAGE_FORMATS,
|
||||
#endif
|
||||
PACKAGE_BUGREPORT);
|
||||
|
||||
exit (status);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
char *output = NULL;
|
||||
char *dir = NULL;
|
||||
char *prefix = NULL;
|
||||
char *memdisk = NULL;
|
||||
char *font = NULL;
|
||||
char *config = NULL;
|
||||
FILE *fp = stdout;
|
||||
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
|
||||
grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT;
|
||||
#endif
|
||||
|
||||
set_program_name (argv[0]);
|
||||
|
||||
grub_util_init_nls ();
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVv", options, 0);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
else
|
||||
switch (c)
|
||||
{
|
||||
case 'o':
|
||||
if (output)
|
||||
free (output);
|
||||
|
||||
output = xstrdup (optarg);
|
||||
break;
|
||||
|
||||
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
|
||||
case 'O':
|
||||
#ifdef GRUB_PLATFORM_IMAGE_RAW
|
||||
if (strcmp (optarg, "raw") == 0)
|
||||
format = GRUB_PLATFORM_IMAGE_RAW;
|
||||
else
|
||||
#endif
|
||||
#ifdef GRUB_PLATFORM_IMAGE_ELF
|
||||
if (strcmp (optarg, "elf") == 0)
|
||||
format = GRUB_PLATFORM_IMAGE_ELF;
|
||||
else
|
||||
#endif
|
||||
#ifdef GRUB_PLATFORM_IMAGE_AOUT
|
||||
if (strcmp (optarg, "aout") == 0)
|
||||
format = GRUB_PLATFORM_IMAGE_AOUT;
|
||||
else
|
||||
#endif
|
||||
usage (1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'd':
|
||||
if (dir)
|
||||
free (dir);
|
||||
|
||||
dir = xstrdup (optarg);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (memdisk)
|
||||
free (memdisk);
|
||||
|
||||
memdisk = xstrdup (optarg);
|
||||
|
||||
if (prefix)
|
||||
free (prefix);
|
||||
|
||||
prefix = xstrdup ("(memdisk)/boot/grub");
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (font)
|
||||
free (font);
|
||||
|
||||
font = xstrdup (optarg);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (config)
|
||||
free (config);
|
||||
|
||||
config = xstrdup (optarg);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage (0);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (prefix)
|
||||
free (prefix);
|
||||
|
||||
prefix = xstrdup (optarg);
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
return 0;
|
||||
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage (1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (output)
|
||||
{
|
||||
fp = fopen (output, "wb");
|
||||
if (! fp)
|
||||
grub_util_error (_("cannot open %s"), output);
|
||||
free (output);
|
||||
}
|
||||
|
||||
generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp,
|
||||
argv + optind, memdisk, font, config,
|
||||
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
|
||||
format
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
|
||||
fclose (fp);
|
||||
|
||||
if (dir)
|
||||
free (dir);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -172,7 +172,7 @@ EOF
|
|||
|
||||
tar -C ${memdisk_dir} -cf ${memdisk_img} boot
|
||||
rm -rf ${memdisk_dir}
|
||||
grub-mkelfimage -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \
|
||||
grub-mkimage -O i386-coreboot -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \
|
||||
memdisk tar search iso9660 configfile sh \
|
||||
ata at_keyboard
|
||||
rm -f ${memdisk_img}
|
||||
|
@ -183,7 +183,7 @@ fi
|
|||
if test -e "${pc_dir}" ; then
|
||||
echo "Enabling BIOS support ..."
|
||||
core_img=`mktemp "$MKTEMP_TEMPLATE"`
|
||||
grub-mkimage -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \
|
||||
grub-mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \
|
||||
iso9660 biosdisk
|
||||
cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img
|
||||
|
||||
|
@ -213,7 +213,7 @@ fi
|
|||
# build bootx64.efi
|
||||
if test -e "${efi64_dir}" ; then
|
||||
echo "Enabling EFI64 support ..."
|
||||
grub-mkimage -d "${efi64_dir}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \
|
||||
grub-mkimage -O x86_64-efi -d "${efi64_dir}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \
|
||||
search iso9660 configfile sh
|
||||
|
||||
modules="$(cat "${efi64_dir}"/partmap.lst) ${modules}"
|
||||
|
|
|
@ -76,13 +76,13 @@ menuentry "${OS}" ${CLASS} {
|
|||
EOF
|
||||
prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
|
||||
cat << EOF
|
||||
echo $(gettext "Loading GNU Mach ...")
|
||||
echo '$(gettext_quoted "Loading GNU Mach ...")'
|
||||
multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/}
|
||||
EOF
|
||||
save_default_entry | sed -e "s/^/\t/"
|
||||
prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/"
|
||||
cat << EOF
|
||||
echo $(gettext "Loading the Hurd ...")
|
||||
echo '$(gettext_quoted "Loading the Hurd ...")'
|
||||
module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\
|
||||
--multiboot-command-line='\${kernel-command-line}' \\
|
||||
--host-priv-port='\${host-port}' \\
|
||||
|
@ -98,13 +98,13 @@ menuentry "${OS} (recovery mode)" {
|
|||
EOF
|
||||
prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
|
||||
cat << EOF
|
||||
echo $(gettext "Loading GNU Mach ...")
|
||||
echo '$(gettext_quoted "Loading GNU Mach ...")'
|
||||
multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s
|
||||
EOF
|
||||
save_default_entry | sed -e "s/^/\t/"
|
||||
prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/"
|
||||
cat << EOF
|
||||
echo $(gettext "Loading the Hurd ...")
|
||||
echo '$(gettext_quoted "Loading the Hurd ...")'
|
||||
module /hurd/${hurd_fs}.static ${hurd_fs} \\
|
||||
--multiboot-command-line='\${kernel-command-line}' \\
|
||||
--host-priv-port='\${host-port}' \\
|
||||
|
|
|
@ -23,7 +23,7 @@ libdir=@libdir@
|
|||
. ${libdir}/grub/grub-mkconfig_lib
|
||||
|
||||
export TEXTDOMAIN=@PACKAGE@
|
||||
export TEXTDOMAINDIR=@LOCALEDIR@
|
||||
export TEXTDOMAINDIR=@localedir@
|
||||
|
||||
CLASS="--class os"
|
||||
|
||||
|
@ -44,15 +44,15 @@ kfreebsd_entry ()
|
|||
version="$2"
|
||||
recovery="$3" # not used yet
|
||||
args="$4" # not used yet
|
||||
title="$(gettext "%s, with kFreeBSD %s")"
|
||||
printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}"
|
||||
title="$(gettext_quoted "%s, with kFreeBSD %s")"
|
||||
printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}"
|
||||
save_default_entry | sed -e "s/^/\t/"
|
||||
if [ -z "${prepare_boot_cache}" ]; then
|
||||
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")"
|
||||
fi
|
||||
printf '%s\n' "${prepare_boot_cache}"
|
||||
cat << EOF
|
||||
echo $(printf "$(gettext "Loading kernel of FreeBSD %s ...")" ${version})
|
||||
echo '$(printf "$(gettext_quoted "Loading kernel of FreeBSD %s ...")" ${version})'
|
||||
kfreebsd ${rel_dirname}/${basename}
|
||||
EOF
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ libdir=@libdir@
|
|||
. ${libdir}/grub/grub-mkconfig_lib
|
||||
|
||||
export TEXTDOMAIN=@PACKAGE@
|
||||
export TEXTDOMAINDIR=@LOCALEDIR@
|
||||
export TEXTDOMAINDIR=@localedir@
|
||||
|
||||
CLASS="--class gnu-linux --class gnu --class os"
|
||||
|
||||
|
@ -56,11 +56,11 @@ linux_entry ()
|
|||
recovery="$3"
|
||||
args="$4"
|
||||
if ${recovery} ; then
|
||||
title="$(gettext "%s, with Linux %s (recovery mode)")"
|
||||
title="$(gettext_quoted "%s, with Linux %s (recovery mode)")"
|
||||
else
|
||||
title="$(gettext "%s, with Linux %s")"
|
||||
title="$(gettext_quoted "%s, with Linux %s")"
|
||||
fi
|
||||
printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}"
|
||||
printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}"
|
||||
save_default_entry | sed -e "s/^/\t/"
|
||||
|
||||
# Use ELILO's generic "efifb" when it's known to be available.
|
||||
|
@ -83,12 +83,12 @@ EOF
|
|||
fi
|
||||
printf '%s\n' "${prepare_boot_cache}"
|
||||
cat << EOF
|
||||
echo $(printf "$(gettext "Loading Linux %s ...")" ${version})
|
||||
echo '$(printf "$(gettext_quoted "Loading Linux %s ...")" ${version})'
|
||||
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
|
||||
EOF
|
||||
if test -n "${initrd}" ; then
|
||||
cat << EOF
|
||||
echo $(gettext "Loading initial ramdisk ...")
|
||||
echo '$(gettext_quoted "Loading initial ramdisk ...")'
|
||||
initrd ${rel_dirname}/${initrd}
|
||||
EOF
|
||||
fi
|
||||
|
|
86
util/grub.d/10_netbsd.in
Normal file
86
util/grub.d/10_netbsd.in
Normal file
|
@ -0,0 +1,86 @@
|
|||
#! /bin/sh -e
|
||||
|
||||
# grub-mkconfig helper script.
|
||||
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# GRUB is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# GRUB is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
bindir=@bindir@
|
||||
libdir=@libdir@
|
||||
. ${libdir}/grub/grub-mkconfig_lib
|
||||
|
||||
export TEXTDOMAIN=@PACKAGE@
|
||||
export TEXTDOMAINDIR=@localedir@
|
||||
|
||||
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
|
||||
OS=NetBSD
|
||||
else
|
||||
OS="${GRUB_DISTRIBUTOR} NetBSD"
|
||||
fi
|
||||
|
||||
netbsd_entry ()
|
||||
{
|
||||
loader="$1" # "knetbsd" or "multiboot"
|
||||
kernel="$2" # absolute path to the kernel file
|
||||
recovery="$3" # is this is a recovery entry?
|
||||
args="$4" # extra arguments appended to loader command
|
||||
|
||||
kroot_device="$(echo ${GRUB_DEVICE} | sed -e 's,^/dev/r,,')"
|
||||
if ${recovery} ; then
|
||||
title="$(gettext_quoted "%s, with kernel %s (via %s, recovery mode)")"
|
||||
else
|
||||
title="$(gettext_quoted "%s, with kernel %s (via %s)")"
|
||||
fi
|
||||
|
||||
printf "menuentry \"${title}\" {\n" \
|
||||
"${OS}" "$(echo ${kernel} | sed -e 's,^.*/,,')" "${loader}"
|
||||
printf "%s\n" "${prepare_boot_cache}"
|
||||
case "${loader}" in
|
||||
knetbsd)
|
||||
printf "\tknetbsd %s -r %s %s\n" \
|
||||
"${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}"
|
||||
;;
|
||||
multiboot)
|
||||
printf "\tmultiboot %s %s root=%s %s\n" \
|
||||
"${kernel}" "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}"
|
||||
;;
|
||||
esac
|
||||
printf "}\n"
|
||||
}
|
||||
|
||||
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e 's,^, ,')"
|
||||
|
||||
# We look for NetBSD kernels in / but not in subdirectories. We simply
|
||||
# pick all statically linked ELF executable files (or links) in / with a
|
||||
# name that starts with `netbsd'.
|
||||
pattern="^ELF[^,]*executable.*statically linked"
|
||||
for k in $(ls -t /netbsd*) ; do
|
||||
if ! grub_file_is_not_garbage "$k" ; then
|
||||
continue
|
||||
fi
|
||||
if ! ((file -bL "$k" | grep -q "${pattern}") ||
|
||||
(zcat "$k" | file -bL - | grep -q "${pattern}")) 2>/dev/null ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Found NetBSD kernel: $k" >&2
|
||||
netbsd_entry "knetbsd" "$k" false "${GRUB_CMDLINE_NETBSD_DEFAULT}"
|
||||
netbsd_entry "multiboot" "$k" false "${GRUB_CMDLINE_NETBSD_DEFAULT}"
|
||||
if [ "x${GRUB_DISABLE_NETBSD_RECOVERY}" != "xtrue" ]; then
|
||||
netbsd_entry "knetbsd" "$k" true "-s"
|
||||
netbsd_entry "multiboot" "$k" true "-s"
|
||||
fi
|
||||
done
|
|
@ -861,7 +861,7 @@ make_device_name (int drive, int dos_part, int bsd_part)
|
|||
dos_part_str = xasprintf (",%d", dos_part + 1);
|
||||
|
||||
if (bsd_part >= 0)
|
||||
bsd_part_str = xasprintf (",%c", bsd_part + 'a');
|
||||
bsd_part_str = xasprintf (",%d", bsd_part + 1);
|
||||
|
||||
ret = xasprintf ("%s%s%s", map[drive].drive,
|
||||
dos_part_str ? : "",
|
||||
|
@ -1352,3 +1352,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
|
|||
return make_device_name (drive, -1, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
grub_util_biosdisk_get_osdev (grub_disk_t disk)
|
||||
{
|
||||
return map[disk->id].device;
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma
|
|||
# The order in this list is critical. Be careful when modifying it.
|
||||
modules="$modules $fs_module $partmap_module $devabstraction_module"
|
||||
|
||||
$grub_mkimage --output=${grubdir}/grub.efi $modules || exit 1
|
||||
$grub_mkimage -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit 1
|
||||
|
||||
# Prompt the user to check if the device map is correct.
|
||||
echo "Installation finished. No error reported."
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -57,6 +57,13 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P
|
|||
#define DEFAULT_BOOT_FILE "boot.img"
|
||||
#define DEFAULT_CORE_FILE "core.img"
|
||||
|
||||
#define grub_target_to_host16(x) grub_le_to_cpu16(x)
|
||||
#define grub_target_to_host32(x) grub_le_to_cpu32(x)
|
||||
#define grub_target_to_host64(x) grub_le_to_cpu64(x)
|
||||
#define grub_host_to_target16(x) grub_cpu_to_le16(x)
|
||||
#define grub_host_to_target32(x) grub_cpu_to_le32(x)
|
||||
#define grub_host_to_target64(x) grub_cpu_to_le64(x)
|
||||
|
||||
void
|
||||
grub_putchar (int c)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ target_cpu=@target_cpu@
|
|||
platform=@platform@
|
||||
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
|
||||
|
||||
grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}`
|
||||
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
|
||||
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
|
||||
grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
|
||||
grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}`
|
||||
|
@ -189,7 +189,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma
|
|||
modules="$modules $fs_module $partmap_module $devabstraction_module"
|
||||
|
||||
# Now perform the installation.
|
||||
"$grub_mkimage" --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1
|
||||
"$grub_mkimage" -O ${target_cpu}-ieee1275 --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1
|
||||
|
||||
if test $update_nvram = yes; then
|
||||
set $ofpathname dummy
|
||||
|
|
|
@ -368,7 +368,7 @@ strip_trailing_digits (const char *p)
|
|||
}
|
||||
|
||||
char *
|
||||
grub_util_devname_to_ofpath (char *devname)
|
||||
grub_util_devname_to_ofpath (const char *devname)
|
||||
{
|
||||
char *name_buf, *device, *devnode, *devicenode, *ofpath;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ target_cpu=@target_cpu@
|
|||
platform=@platform@
|
||||
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
|
||||
|
||||
grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}`
|
||||
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
|
||||
|
||||
# Usage: usage
|
||||
# Print the usage.
|
||||
|
@ -104,7 +104,7 @@ boot_dir=${iso_dir}/boot/grub
|
|||
mkdir ${iso_dir}/boot
|
||||
mkdir ${boot_dir}
|
||||
core_img=${boot_dir}/grub.img
|
||||
${grub_mkimage} -n -d ${input_dir}/ -o ${core_img} ${modules}
|
||||
${grub_mkimage} -O powerpc-ieee1275 -n -d ${input_dir}/ -o ${core_img} ${modules}
|
||||
genisoimage -hfs -part -no-desktop -r -J -o ${output_image} \
|
||||
-map ${map_file} -hfs-bless ${boot_dir} -chrp-boot -sysid PPC \
|
||||
${iso_dir}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <grub/term.h>
|
||||
#include <grub/util/raid.h>
|
||||
#include <grub/util/lvm.h>
|
||||
#include <grub/util/ofpath.h>
|
||||
|
||||
#include <grub_setup_init.h>
|
||||
|
||||
|
@ -75,6 +76,13 @@
|
|||
#define DEFAULT_BOOT_FILE "boot.img"
|
||||
#define DEFAULT_CORE_FILE "core.img"
|
||||
|
||||
#define grub_target_to_host16(x) grub_be_to_cpu16(x)
|
||||
#define grub_target_to_host32(x) grub_be_to_cpu32(x)
|
||||
#define grub_target_to_host64(x) grub_be_to_cpu64(x)
|
||||
#define grub_host_to_target16(x) grub_cpu_to_be16(x)
|
||||
#define grub_host_to_target32(x) grub_cpu_to_be32(x)
|
||||
#define grub_host_to_target64(x) grub_cpu_to_be64(x)
|
||||
|
||||
/* This is the blocklist used in the diskboot image. */
|
||||
struct boot_blocklist
|
||||
{
|
||||
|
@ -103,28 +111,6 @@ grub_refresh (void)
|
|||
fflush (stdout);
|
||||
}
|
||||
|
||||
static char *compute_dest_ofpath (const char *dest)
|
||||
{
|
||||
int len = strlen (dest);
|
||||
char *res, *p, c;
|
||||
|
||||
res = xmalloc (len);
|
||||
p = res;
|
||||
while ((c = *dest++) != '\0')
|
||||
{
|
||||
if (c == '\\' && *dest == ',')
|
||||
{
|
||||
*p++ = ',';
|
||||
dest++;
|
||||
}
|
||||
else
|
||||
*p++ = c;
|
||||
}
|
||||
*p++ = '\0';
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
setup (const char *prefix, const char *dir,
|
||||
const char *boot_file, const char *core_file,
|
||||
|
@ -135,8 +121,8 @@ setup (const char *prefix, const char *dir,
|
|||
size_t boot_size, core_size;
|
||||
grub_uint16_t core_sectors;
|
||||
grub_device_t root_dev, dest_dev;
|
||||
char *boot_devpath, *dest_ofpath;
|
||||
grub_disk_addr_t *kernel_sector;
|
||||
char *boot_devpath;
|
||||
grub_disk_addr_t *kernel_byte;
|
||||
struct boot_blocklist *first_block, *block;
|
||||
char *tmp_img;
|
||||
int i;
|
||||
|
@ -195,8 +181,6 @@ setup (const char *prefix, const char *dir,
|
|||
last_length = length;
|
||||
}
|
||||
|
||||
dest_ofpath = compute_dest_ofpath (dest);
|
||||
|
||||
/* Read the boot image by the OS service. */
|
||||
boot_path = grub_util_get_path (dir, boot_file);
|
||||
boot_size = grub_util_get_image_size (boot_path);
|
||||
|
@ -210,9 +194,9 @@ setup (const char *prefix, const char *dir,
|
|||
boot_devpath = (char *) (boot_img
|
||||
+ GRUB_BOOT_AOUT_HEADER_SIZE
|
||||
+ GRUB_BOOT_MACHINE_BOOT_DEVPATH);
|
||||
kernel_sector = (grub_disk_addr_t *) (boot_img
|
||||
+ GRUB_BOOT_AOUT_HEADER_SIZE
|
||||
+ GRUB_BOOT_MACHINE_KERNEL_SECTOR);
|
||||
kernel_byte = (grub_disk_addr_t *) (boot_img
|
||||
+ GRUB_BOOT_AOUT_HEADER_SIZE
|
||||
+ GRUB_BOOT_MACHINE_KERNEL_BYTE);
|
||||
|
||||
core_path = grub_util_get_path (dir, core_file);
|
||||
core_size = grub_util_get_image_size (core_path);
|
||||
|
@ -229,8 +213,7 @@ setup (const char *prefix, const char *dir,
|
|||
+ GRUB_DISK_SECTOR_SIZE
|
||||
- sizeof (*block));
|
||||
|
||||
grub_util_info ("root is `%s', dest is `%s', and dest_ofpath is `%s'",
|
||||
root, dest, dest_ofpath);
|
||||
grub_util_info ("root is `%s', dest is `%s'", root, dest);
|
||||
|
||||
/* Open the root device and the destination device. */
|
||||
grub_util_info ("Opening root");
|
||||
|
@ -351,14 +334,30 @@ setup (const char *prefix, const char *dir,
|
|||
!= (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE)
|
||||
grub_util_error ("failed to read the rest sectors of the core image");
|
||||
|
||||
if (file->device->disk->id != dest_dev->disk->id)
|
||||
{
|
||||
const char *dest_ofpath;
|
||||
dest_ofpath
|
||||
= grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (file->device->disk));
|
||||
grub_util_info ("dest_ofpath is `%s'", dest_ofpath);
|
||||
strncpy (boot_devpath, dest_ofpath, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END
|
||||
- GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1);
|
||||
boot_devpath[GRUB_BOOT_MACHINE_BOOT_DEVPATH_END
|
||||
- GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_util_info ("non cross-disk install");
|
||||
memset (boot_devpath, 0, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END
|
||||
- GRUB_BOOT_MACHINE_BOOT_DEVPATH);
|
||||
}
|
||||
|
||||
grub_file_close (file);
|
||||
|
||||
free (core_path);
|
||||
free (tmp_img);
|
||||
|
||||
*kernel_sector = grub_cpu_to_be64 (first_sector);
|
||||
|
||||
strcpy(boot_devpath, dest_ofpath);
|
||||
*kernel_byte = grub_cpu_to_be64 (first_sector << GRUB_DISK_SECTOR_BITS);
|
||||
|
||||
grub_util_info ("boot device path %s, prefix is %s, dest is %s",
|
||||
boot_devpath, prefix, dest);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue