unify prefix handling across platforms

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-07-02 14:09:36 +02:00
parent 59b455fcea
commit 574618a2e9
17 changed files with 189 additions and 399 deletions

View file

@ -102,6 +102,7 @@ kernel = {
ieee1275 = kern/ieee1275/mmap.c;
ieee1275 = kern/ieee1275/openfw.c;
ieee1275 = term/ieee1275/ofconsole.c;
ieee1275 = kern/ieee1275/init.c;
terminfoinkernel = term/terminfo.c;
terminfoinkernel = term/tparm.c;
@ -153,8 +154,6 @@ kernel = {
i386_multiboot = kern/i386/multiboot_mmap.c;
i386_multiboot = kern/i386/tsc.c;
i386_ieee1275 = kern/ieee1275/init.c;
mips = kern/mips/cache.S;
mips = kern/mips/dl.c;
mips = kern/mips/init.c;
@ -179,14 +178,12 @@ kernel = {
extra_dist = video/sm712_init.c;
mips_loongson = commands/keylayouts.c;
powerpc_ieee1275 = kern/ieee1275/init.c;
powerpc_ieee1275 = kern/powerpc/cache.S;
powerpc_ieee1275 = kern/powerpc/dl.c;
sparc64_ieee1275 = kern/sparc64/cache.S;
sparc64_ieee1275 = kern/sparc64/dl.c;
sparc64_ieee1275 = kern/sparc64/ieee1275/ieee1275.c;
sparc64_ieee1275 = kern/sparc64/ieee1275/init.c;
emu = disk/host.c;
emu = gnulib/progname.c;

View file

@ -83,7 +83,7 @@ LOCAL(setup_sectors):
/* the maximum is limited to 0x7f because of Phoenix EDD */
xorl %eax, %eax
movb $0x7f, %al
movb $0x1, %al
/* how many do we really want to read? */
cmpw %ax, 8(%di) /* compare against total number of sectors */

View file

@ -530,7 +530,7 @@ grub_efidisk_open (const char *name, struct grub_disk *disk)
and total sectors should be replaced with total blocks. */
grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
m, (unsigned long long) m->last_block, m->block_size);
disk->total_sectors = m->last_block;
disk->total_sectors = m->last_block + 1;
if (m->block_size & (m->block_size - 1) || !m->block_size)
return grub_error (GRUB_ERR_IO, "invalid sector size %d",
m->block_size);
@ -788,6 +788,15 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
/* Find a partition which matches the hard drive device path. */
grub_memcpy (&hd, ldp, sizeof (hd));
if (hd.partition_start == 0
&& hd.partition_size == grub_disk_get_size (parent))
{
device_name = grub_strdup (parent->name);
}
else
{
char *partition_name;
grub_partition_iterate (parent, find_partition);
if (! tpart)
@ -796,8 +805,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
return 0;
}
{
char *partition_name = grub_partition_get_name (tpart);
partition_name = grub_partition_get_name (tpart);
device_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
grub_free (partition_name);
}

View file

@ -43,85 +43,23 @@ grub_efi_init (void)
}
void
grub_efi_set_prefix (void)
grub_machine_get_bootlocation (char **device, char **path)
{
grub_efi_loaded_image_t *image = NULL;
char *device = NULL;
char *path = NULL;
{
char *pptr = NULL;
if (grub_prefix[0] == '(')
{
pptr = grub_strrchr (grub_prefix, ')');
if (pptr)
{
device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1);
pptr++;
}
}
if (!pptr)
pptr = grub_prefix;
if (pptr[0])
path = grub_strdup (pptr);
}
if ((!device || device[0] == ',' || !device[0]) || !path)
image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (image)
{
if (!device)
device = grub_efidisk_get_device_name (image->device_handle);
else if (device[0] == ',' || !device[0])
{
/* We have a partition, but still need to fill in the drive. */
char *image_device, *comma, *new_device;
image_device = grub_efidisk_get_device_name (image->device_handle);
comma = grub_strchr (image_device, ',');
if (comma)
{
char *drive = grub_strndup (image_device, comma - image_device);
new_device = grub_xasprintf ("%s%s", drive, device);
grub_free (drive);
}
else
new_device = grub_xasprintf ("%s%s", image_device, device);
grub_free (image_device);
grub_free (device);
device = new_device;
}
}
if (image && !path)
{
char *p;
path = grub_efi_get_filename (image->file_path);
image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (!image)
return;
*device = grub_efidisk_get_device_name (image->device_handle);
*path = grub_efi_get_filename (image->file_path);
/* Get the directory. */
p = grub_strrchr (path, '/');
p = grub_strrchr (*path, '/');
if (p)
*p = '\0';
}
if (device && path)
{
char *prefix;
prefix = grub_xasprintf ("(%s)%s", device, path);
if (prefix)
{
grub_env_set ("prefix", prefix);
grub_free (prefix);
}
}
grub_free (device);
grub_free (path);
}
void
grub_efi_fini (void)
{

View file

@ -49,7 +49,7 @@
static jmp_buf main_env;
/* Store the prefix specified by an argument. */
static char *prefix = NULL;
static char *root_dev = NULL, *dir = DEFAULT_DIRECTORY;
int grub_no_autoload;
@ -71,11 +71,10 @@ grub_machine_init (void)
}
void
grub_machine_set_prefix (void)
grub_machine_get_bootlocation (char **device, char **path)
{
grub_env_set ("prefix", prefix);
free (prefix);
prefix = 0;
*device = root_dev;
*path = dir;
}
void
@ -84,6 +83,8 @@ grub_machine_fini (void)
grub_console_fini ();
}
char grub_prefix[64] = "";
static struct option options[] =
@ -132,8 +133,6 @@ void grub_emu_init (void);
int
main (int argc, char *argv[])
{
char *root_dev = 0;
char *dir = DEFAULT_DIRECTORY;
char *dev_map = DEFAULT_DEVICE_MAP;
volatile int hold = 0;
int opt;
@ -219,9 +218,6 @@ main (int argc, char *argv[])
dir = xstrdup (dir);
else
dir = grub_make_system_path_relative_to_its_root (dir);
prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1);
sprintf (prefix, "(%s)%s", root_dev, dir);
free (dir);
/* Start GRUB! */
if (setjmp (main_env) == 0)

View file

@ -107,10 +107,9 @@ grub_machine_init (void)
}
void
grub_machine_set_prefix (void)
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
/* Initialize the prefix. */
grub_env_set ("prefix", grub_prefix);
}
void

View file

@ -39,9 +39,3 @@ grub_machine_fini (void)
{
grub_efi_fini ();
}
void
grub_machine_set_prefix (void)
{
grub_efi_set_prefix ();
}

View file

@ -45,52 +45,39 @@ struct mem_region
static struct mem_region mem_regions[MAX_REGIONS];
static int num_regions;
static char *
make_install_device (void)
void
grub_machine_get_bootlocation (char **device,
char **path __attribute__ ((unused)))
{
/* XXX: This should be enough. */
char dev[100], *ptr = dev;
char *ptr;
if (grub_prefix[0] != '(')
{
/* No hardcoded root partition - make it from the boot drive and the
partition number encoded at the install time. */
if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL)
{
grub_strcpy (dev, "(pxe");
ptr += sizeof ("(pxe") - 1;
*device = grub_strdup ("pxe");
return;
}
else
{
grub_snprintf (dev, sizeof (dev),
"(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
/* XXX: This should be enough. */
#define DEV_SIZE 100
*device = grub_malloc (DEV_SIZE);
ptr = *device;
grub_snprintf (*device, DEV_SIZE,
"%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
grub_boot_drive & 0x7f);
ptr += grub_strlen (ptr);
if (grub_install_dos_part >= 0)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev),
grub_snprintf (ptr, DEV_SIZE - (ptr - *device),
",%u", grub_install_dos_part + 1);
ptr += grub_strlen (ptr);
if (grub_install_bsd_part >= 0)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%u",
grub_snprintf (ptr, DEV_SIZE - (ptr - *device), ",%u",
grub_install_bsd_part + 1);
ptr += grub_strlen (ptr);
}
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix);
grub_strcpy (grub_prefix, dev);
}
else if (grub_prefix[1] == ',' || grub_prefix[1] == ')')
{
/* We have a prefix, but still need to fill in the boot drive. */
grub_snprintf (dev, sizeof (dev),
"(%cd%u%s", (grub_boot_drive & 0x80) ? 'h' : 'f',
grub_boot_drive & 0x7f, grub_prefix + 1);
grub_strcpy (grub_prefix, dev);
}
return grub_prefix;
*ptr = 0;
}
/* Add a memory region. */
@ -211,13 +198,6 @@ grub_machine_init (void)
grub_tsc_init ();
}
void
grub_machine_set_prefix (void)
{
/* Initialize the prefix. */
grub_env_set ("prefix", make_install_device ());
}
void
grub_machine_fini (void)
{

View file

@ -40,12 +40,6 @@ grub_machine_fini (void)
grub_efi_fini ();
}
void
grub_machine_set_prefix (void)
{
grub_efi_set_prefix ();
}
void
grub_arch_sync_caches (void *address, grub_size_t len)
{

View file

@ -60,6 +60,10 @@ grub_ieee1275_find_options (void)
int is_olpc = 0;
int is_qemu = 0;
#ifdef _sparc64
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
#endif
grub_ieee1275_finddevice ("/", &root);
grub_ieee1275_finddevice ("/options", &options);
grub_ieee1275_finddevice ("/openprom", &openprom);

View file

@ -35,6 +35,9 @@
#include <grub/net.h>
#include <grub/offsets.h>
#include <grub/memory.h>
#ifdef __sparc__
#include <grub/machine/kernel.h>
#endif
/* The minimal heap size we can live with. */
#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024)
@ -49,6 +52,10 @@
extern char _start[];
extern char _end[];
#ifdef __sparc__
grub_addr_t grub_ieee1275_original_stack;
#endif
void
grub_exit (void)
{
@ -71,31 +78,21 @@ grub_translate_ieee1275_path (char *filepath)
}
void
grub_machine_set_prefix (void)
grub_machine_get_bootlocation (char **device, char **path)
{
char bootpath[64]; /* XXX check length */
char *filename;
char *prefix;
grub_bootp_t bootp_pckt;
char addr[GRUB_NET_MAX_STR_ADDR_LEN];
/* Set the net prefix when possible. */
if (grub_getbootp && (bootp_pckt = grub_getbootp()))
{
grub_uint32_t n = bootp_pckt->siaddr;
char addr[GRUB_NET_MAX_STR_ADDR_LEN];
grub_snprintf (addr, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d",
((n >> 24) & 0xff), ((n >> 16) & 0xff),
((n >> 8) & 0xff), ((n >> 0) & 0xff));
prefix = grub_xasprintf ("(tftp,%s)%s", addr,grub_prefix);
grub_env_set ("prefix", prefix);
grub_free (prefix);
return;
}
if (grub_prefix[0])
{
grub_env_set ("prefix", grub_prefix);
/* Prefix is hardcoded in the core image. */
*device = grub_xasprintf ("(tftp,%s)", addr);
return;
}
@ -104,18 +101,16 @@ grub_machine_set_prefix (void)
{
/* Should never happen. */
grub_printf ("/chosen/bootpath property missing!\n");
grub_env_set ("prefix", "");
return;
}
/* Transform an OF device path to a GRUB path. */
prefix = grub_ieee1275_encode_devname (bootpath);
*device = grub_ieee1275_encode_devname (bootpath);
filename = grub_ieee1275_get_filename (bootpath);
if (filename)
{
char *newprefix;
char *lastslash = grub_strrchr (filename, '\\');
/* Truncate at last directory. */
@ -124,23 +119,22 @@ grub_machine_set_prefix (void)
*lastslash = '\0';
grub_translate_ieee1275_path (filename);
newprefix = grub_xasprintf ("%s%s", prefix, filename);
if (newprefix)
{
grub_free (prefix);
prefix = newprefix;
*path = filename;
}
}
}
grub_env_set ("prefix", prefix);
grub_free (filename);
grub_free (prefix);
}
/* Claim some available memory in the first /memory node. */
static void grub_claim_heap (void)
#ifdef __sparc__
static void
grub_claim_heap (void)
{
grub_mm_init_region ((void *) (grub_modules_get_end ()
+ GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
}
#else
static void
grub_claim_heap (void)
{
unsigned long total = 0;
@ -208,23 +202,14 @@ static void grub_claim_heap (void)
else
grub_machine_mmap_iterate (heap_init);
}
#endif
static grub_uint64_t ieee1275_get_time_ms (void);
void
grub_machine_init (void)
static void
grub_parse_cmdline (void)
{
char args[256];
grub_ssize_t actual;
char args[256];
grub_ieee1275_init ();
grub_console_init_early ();
grub_claim_heap ();
grub_console_init_lately ();
grub_ofdisk_init ();
/* Process commandline. */
if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
sizeof args, &actual) == 0
&& actual > 1)
@ -257,6 +242,21 @@ grub_machine_init (void)
}
}
}
}
static grub_uint64_t ieee1275_get_time_ms (void);
void
grub_machine_init (void)
{
grub_ieee1275_init ();
grub_console_init_early ();
grub_claim_heap ();
grub_console_init_lately ();
grub_ofdisk_init ();
grub_parse_cmdline ();
grub_install_get_time_ms (ieee1275_get_time_ms);
}

View file

@ -369,6 +369,11 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
ret = grub_strdup (args);
else
ret = grub_strndup (args, (grub_size_t)(comma - args));
/* Consistently provide numbered partitions to GRUB.
OpenBOOT traditionally uses alphabetical partition
specifiers. */
if (ret[0] >= 'a' && ret[0] <= 'z')
ret[0] = '1' + (ret[0] - 'a');
}
}

View file

@ -129,27 +129,74 @@ grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)),
return grub_strdup (val);
}
/* Set the root device according to the dl prefix. */
static void
grub_set_root_dev (void)
grub_set_prefix_and_root (void)
{
const char *prefix;
char *device = NULL;
char *path = NULL;
char *fwdevice = NULL;
char *fwpath = NULL;
grub_register_variable_hook ("root", 0, grub_env_write_root);
prefix = grub_env_get ("prefix");
{
char *pptr = NULL;
if (grub_prefix[0] == '(')
{
pptr = grub_strrchr (grub_prefix, ')');
if (pptr)
{
device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1);
pptr++;
}
}
if (!pptr)
pptr = grub_prefix;
if (pptr[0])
path = grub_strdup (pptr);
}
if ((!device || device[0] == ',' || !device[0]) || !path)
grub_machine_get_bootlocation (&fwdevice, &fwpath);
if (!device && fwdevice)
device = fwdevice;
else if (fwdevice && (device[0] == ',' || !device[0]))
{
/* We have a partition, but still need to fill in the drive. */
char *comma, *new_device;
comma = grub_strchr (fwdevice, ',');
if (comma)
{
char *drive = grub_strndup (fwdevice, comma - fwdevice);
new_device = grub_xasprintf ("%s%s", drive, device);
grub_free (drive);
}
else
new_device = grub_xasprintf ("%s%s", fwdevice, device);
grub_free (fwdevice);
grub_free (device);
device = new_device;
}
if (fwpath && !path)
path = fwpath;
if (device)
{
char *prefix;
prefix = grub_xasprintf ("(%s)%s", device, path ? : "");
if (prefix)
{
char *dev;
grub_env_set ("prefix", prefix);
grub_free (prefix);
}
grub_env_set ("root", device);
}
dev = grub_file_get_device_name (prefix);
if (dev)
{
grub_env_set ("root", dev);
grub_free (dev);
}
}
grub_free (device);
grub_free (path);
grub_print_error ();
}
/* Load the normal mode module and execute the normal mode if possible. */
@ -187,8 +234,7 @@ grub_main (void)
/* It is better to set the root device as soon as possible,
for convenience. */
grub_machine_set_prefix ();
grub_set_root_dev ();
grub_set_prefix_and_root ();
grub_env_export ("root");
grub_env_export ("prefix");

View file

@ -38,7 +38,7 @@ grub_get_rtc (void)
}
void
grub_machine_set_prefix (void)
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
grub_env_set ("prefix", grub_prefix);
}

View file

@ -1,174 +0,0 @@
/* init.c -- Initialize GRUB on SPARC64. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/kernel.h>
#include <grub/mm.h>
#include <grub/env.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/time.h>
#include <grub/machine/boot.h>
#include <grub/ieee1275/console.h>
#include <grub/machine/kernel.h>
#include <grub/machine/time.h>
#include <grub/ieee1275/ofdisk.h>
#include <grub/ieee1275/ieee1275.h>
grub_addr_t grub_ieee1275_original_stack;
void
grub_exit (void)
{
grub_ieee1275_exit ();
}
static grub_uint64_t
ieee1275_get_time_ms (void)
{
grub_uint32_t msecs = 0;
grub_ieee1275_milliseconds (&msecs);
return msecs;
}
grub_uint32_t
grub_get_rtc (void)
{
return ieee1275_get_time_ms ();
}
grub_addr_t
grub_arch_modules_addr (void)
{
extern char _end[];
return (grub_addr_t) _end;
}
void
grub_machine_set_prefix (void)
{
if (grub_prefix[0] != '(')
{
char bootpath[IEEE1275_MAX_PATH_LEN];
char *prefix, *path, *colon;
grub_ssize_t actual;
if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath",
&bootpath, sizeof (bootpath), &actual))
{
/* Should never happen. */
grub_printf ("/chosen/bootpath property missing!\n");
grub_env_set ("prefix", "");
return;
}
/* Transform an OF device path to a GRUB path. */
colon = grub_strchr (bootpath, ':');
if (colon)
{
char *part = colon + 1;
/* Consistently provide numbered partitions to GRUB.
OpenBOOT traditionally uses alphabetical partition
specifiers. */
if (part[0] >= 'a' && part[0] <= 'z')
part[0] = '1' + (part[0] - 'a');
}
prefix = grub_ieee1275_encode_devname (bootpath);
path = grub_xasprintf("%s%s", prefix, grub_prefix);
grub_strcpy (grub_prefix, path);
grub_free (path);
grub_free (prefix);
}
grub_env_set ("prefix", grub_prefix);
}
static void
grub_heap_init (void)
{
grub_mm_init_region ((void *) (grub_modules_get_end ()
+ GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
}
static void
grub_parse_cmdline (void)
{
grub_ssize_t actual;
char args[256];
if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
sizeof args, &actual) == 0
&& actual > 1)
{
int i = 0;
while (i < actual)
{
char *command = &args[i];
char *end;
char *val;
end = grub_strchr (command, ';');
if (end == 0)
i = actual; /* No more commands after this one. */
else
{
*end = '\0';
i += end - command + 1;
while (grub_isspace(args[i]))
i++;
}
/* Process command. */
val = grub_strchr (command, '=');
if (val)
{
*val = '\0';
grub_env_set (command, val + 1);
}
}
}
}
void
grub_machine_init (void)
{
grub_ieee1275_init ();
grub_console_init_early ();
grub_heap_init ();
grub_console_init_lately ();
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
grub_ofdisk_init ();
grub_parse_cmdline ();
grub_install_get_time_ms (ieee1275_get_time_ms);
}
void
grub_machine_fini (void)
{
grub_ofdisk_fini ();
grub_console_fini ();
}

View file

@ -84,12 +84,13 @@ void grub_machine_init (void);
void EXPORT_FUNC(grub_machine_fini) (void);
/* The machine-specific prefix initialization. */
void grub_machine_set_prefix (void);
void
grub_machine_get_bootlocation (char **device, char **path);
/* Register all the exported symbols. This is automatically generated. */
void grub_register_exported_symbols (void);
#if ! defined (ASM_FILE) && !defined (GRUB_MACHINE_EMU)
#if ! defined (ASM_FILE)
extern char grub_prefix[];
#endif

View file

@ -169,8 +169,10 @@
/* Non-zero value is only needed for PowerMacs. */
#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0
#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0
#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x0
#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000
#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN 0x1
#define GRUB_KERNEL_MIPS_LOONGSON_MOD_ALIGN 0x1
#define GRUB_KERNEL_MIPS_ARC_MOD_ALIGN 0x1
@ -179,7 +181,7 @@
/* Minimal gap between _end and the start of the modules. It's a hack
for PowerMac to prevent "CLAIM failed" error. The real fix is to
rewrite grub-mkimage to generate valid ELF files. */
#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x8000
#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x8000
#ifdef GRUB_MACHINE
#define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c