merge mainline into newreloc

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-30 16:46:16 +01:00
commit 6e308bd942
72 changed files with 1538 additions and 533 deletions

View file

@ -73,18 +73,6 @@ grub_core_cmd_unset (struct grub_command *cmd __attribute__ ((unused)),
return 0;
}
static grub_err_t
grub_core_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
{
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"no environment variable specified");
grub_env_export (args[0]);
return 0;
}
/* insmod MODULE */
static grub_err_t
grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
@ -193,8 +181,6 @@ grub_register_core_commands (void)
"[ENVVAR=VALUE]", "Set an environment variable.");
grub_register_command ("unset", grub_core_cmd_unset,
"ENVVAR", "Remove an environment variable.");
grub_register_command ("export", grub_core_cmd_export,
"ENVVAR", "Export a variable.");
grub_register_command ("ls", grub_core_cmd_ls,
"[ARG]", "List devices or files.");
grub_register_command ("insmod", grub_core_cmd_insmod,

View file

@ -441,7 +441,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_errno = GRUB_ERR_NONE;
num = ((size + GRUB_DISK_SECTOR_SIZE - 1)
num = ((size + real_offset + pos + GRUB_DISK_SECTOR_SIZE - 1)
>> GRUB_DISK_SECTOR_BITS);
p = grub_realloc (tmp_buf, num << GRUB_DISK_SECTOR_BITS);
@ -458,18 +458,20 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
goto finish;
}
grub_memcpy (buf, tmp_buf + real_offset, size);
grub_memcpy (buf, tmp_buf + pos + real_offset, size);
/* Call the read hook, if any. */
if (disk->read_hook)
while (size)
{
grub_size_t to_read = (size > GRUB_DISK_SECTOR_SIZE) ? GRUB_DISK_SECTOR_SIZE : size;
(disk->read_hook) (sector, real_offset,
((size > GRUB_DISK_SECTOR_SIZE)
? GRUB_DISK_SECTOR_SIZE
: size));
to_read);
if (grub_errno != GRUB_ERR_NONE)
goto finish;
sector++;
size -= GRUB_DISK_SECTOR_SIZE - real_offset;
size -= to_read - real_offset;
real_offset = 0;
}

View file

@ -1,7 +1,7 @@
/* efi.c - generic EFI support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
* 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
@ -162,6 +162,8 @@ grub_exit (void)
for (;;) ;
}
/* On i386, a firmware-independant grub_reboot() is provided by realmode.S. */
#ifndef __i386__
void
grub_reboot (void)
{
@ -169,6 +171,7 @@ grub_reboot (void)
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
}
#endif
void
grub_halt (void)

View file

@ -18,34 +18,15 @@
*/
#include <grub/env.h>
#include <grub/env_private.h>
#include <grub/misc.h>
#include <grub/mm.h>
/* The size of the hash table. */
#define HASHSZ 13
/* A hashtable for quick lookup of variables. */
struct grub_env_context
{
/* A hash table for variables. */
struct grub_env_var *vars[HASHSZ];
/* One level deeper on the stack. */
struct grub_env_context *prev;
};
/* This is used for sorting only. */
struct grub_env_sorted_var
{
struct grub_env_var *var;
struct grub_env_sorted_var *next;
};
/* The initial context. */
static struct grub_env_context initial_context;
/* The current context. */
static struct grub_env_context *current_context = &initial_context;
struct grub_env_context *grub_current_context = &initial_context;
/* Return the hash representation of the string S. */
static unsigned int
@ -60,88 +41,20 @@ grub_env_hashval (const char *s)
return i % HASHSZ;
}
static struct grub_env_var *
struct grub_env_var *
grub_env_find (const char *name)
{
struct grub_env_var *var;
int idx = grub_env_hashval (name);
/* Look for the variable in the current context. */
for (var = current_context->vars[idx]; var; var = var->next)
for (var = grub_current_context->vars[idx]; var; var = var->next)
if (grub_strcmp (var->name, name) == 0)
return var;
return 0;
}
grub_err_t
grub_env_context_open (int export)
{
struct grub_env_context *context;
int i;
context = grub_zalloc (sizeof (*context));
if (! context)
return grub_errno;
context->prev = current_context;
current_context = context;
/* Copy exported variables. */
for (i = 0; i < HASHSZ; i++)
{
struct grub_env_var *var;
for (var = context->prev->vars[i]; var; var = var->next)
{
if (export && var->type == GRUB_ENV_VAR_GLOBAL)
{
if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
{
grub_env_context_close ();
return grub_errno;
}
grub_env_export (var->name);
grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
}
}
}
return GRUB_ERR_NONE;
}
grub_err_t
grub_env_context_close (void)
{
struct grub_env_context *context;
int i;
if (! current_context->prev)
grub_fatal ("cannot close the initial context");
/* Free the variables associated with this context. */
for (i = 0; i < HASHSZ; i++)
{
struct grub_env_var *p, *q;
for (p = current_context->vars[i]; p; p = q)
{
q = p->next;
grub_free (p->name);
if (p->type != GRUB_ENV_VAR_DATA)
grub_free (p->value);
grub_free (p);
}
}
/* Restore the previous context. */
context = current_context->prev;
grub_free (current_context);
current_context = context;
return GRUB_ERR_NONE;
}
static void
grub_env_insert (struct grub_env_context *context,
struct grub_env_var *var)
@ -165,26 +78,6 @@ grub_env_remove (struct grub_env_var *var)
var->next->prevp = var->prevp;
}
grub_err_t
grub_env_export (const char *name)
{
struct grub_env_var *var;
var = grub_env_find (name);
if (! var)
{
grub_err_t err;
err = grub_env_set (name, "");
if (err)
return err;
var = grub_env_find (name);
}
var->type = GRUB_ENV_VAR_GLOBAL;
return GRUB_ERR_NONE;
}
grub_err_t
grub_env_set (const char *name, const char *val)
{
@ -216,9 +109,8 @@ grub_env_set (const char *name, const char *val)
if (! var)
return grub_errno;
/* This is not necessary, because GRUB_ENV_VAR_LOCAL == 0. But leave
this for readability. */
var->type = GRUB_ENV_VAR_LOCAL;
/* This is not necessary. But leave this for readability. */
var->global = 0;
var->name = grub_strdup (name);
if (! var->name)
@ -228,7 +120,7 @@ grub_env_set (const char *name, const char *val)
if (! var->value)
goto fail;
grub_env_insert (current_context, var);
grub_env_insert (grub_current_context, var);
return GRUB_ERR_NONE;
@ -273,8 +165,7 @@ grub_env_unset (const char *name)
grub_env_remove (var);
grub_free (var->name);
if (var->type != GRUB_ENV_VAR_DATA)
grub_free (var->value);
grub_free (var->value);
grub_free (var);
}
@ -290,14 +181,10 @@ grub_env_iterate (int (*func) (struct grub_env_var *var))
{
struct grub_env_var *var;
for (var = current_context->vars[i]; var; var = var->next)
for (var = grub_current_context->vars[i]; var; var = var->next)
{
struct grub_env_sorted_var *p, **q;
/* Ignore data slots. */
if (var->type == GRUB_ENV_VAR_DATA)
continue;
sorted_var = grub_malloc (sizeof (*sorted_var));
if (! sorted_var)
goto fail;
@ -353,77 +240,3 @@ grub_register_variable_hook (const char *name,
return GRUB_ERR_NONE;
}
static char *
mangle_data_slot_name (const char *name)
{
return grub_xasprintf ("\e%s", name);
}
grub_err_t
grub_env_set_data_slot (const char *name, const void *ptr)
{
char *mangled_name;
struct grub_env_var *var;
mangled_name = mangle_data_slot_name (name);
if (! mangled_name)
goto fail;
/* If the variable does already exist, just update the variable. */
var = grub_env_find (mangled_name);
if (var)
{
var->value = (char *) ptr;
return GRUB_ERR_NONE;
}
/* The variable does not exist, so create a new one. */
var = grub_zalloc (sizeof (*var));
if (! var)
goto fail;
var->type = GRUB_ENV_VAR_DATA;
var->name = mangled_name;
var->value = (char *) ptr;
grub_env_insert (current_context, var);
return GRUB_ERR_NONE;
fail:
grub_free (mangled_name);
return grub_errno;
}
void *
grub_env_get_data_slot (const char *name)
{
char *mangled_name;
void *ptr = 0;
mangled_name = mangle_data_slot_name (name);
if (! mangled_name)
goto fail;
ptr = grub_env_get (mangled_name);
grub_free (mangled_name);
fail:
return ptr;
}
void
grub_env_unset_data_slot (const char *name)
{
char *mangled_name;
mangled_name = mangle_data_slot_name (name);
if (! mangled_name)
return;
grub_env_unset (mangled_name);
grub_free (mangled_name);
}

View file

@ -1,7 +1,7 @@
/* startup.S - bootstrap GRUB itself */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007 Free Software Foundation, Inc.
* Copyright (C) 2006,2007,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
@ -62,3 +62,5 @@ codestart:
movl %eax, EXT_C(grub_efi_system_table)
call EXT_C(grub_main)
ret
#include "../realmode.S"

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
* 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
@ -18,6 +18,7 @@
#include <grub/kernel.h>
#include <grub/mm.h>
#include <grub/machine/boot.h>
#include <grub/machine/init.h>
#include <grub/machine/memory.h>
#include <grub/machine/console.h>
@ -59,22 +60,28 @@ make_install_device (void)
{
/* No hardcoded root partition - make it from the boot drive and the
partition number encoded at the install time. */
grub_snprintf (dev, sizeof (dev),
"(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
grub_boot_drive & 0x7f);
ptr += grub_strlen (ptr);
if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL)
{
grub_strcpy (dev, "(pxe");
ptr += sizeof ("(pxe") - 1;
}
else
{
grub_snprintf (dev, sizeof (dev),
"(%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),
",%u", grub_install_dos_part + 1);
if (grub_install_dos_part >= 0)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev),
",%u", grub_install_dos_part + 1);
ptr += grub_strlen (ptr);
ptr += grub_strlen (ptr);
if (grub_install_bsd_part >= 0)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c",
grub_install_bsd_part + 'a');
ptr += grub_strlen (ptr);
if (grub_install_bsd_part >= 0)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c",
grub_install_bsd_part + 'a');
ptr += grub_strlen (ptr);
}
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix);
grub_strcpy (grub_prefix, dev);

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009 Free Software Foundation, Inc.
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,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
@ -16,6 +16,7 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/i386/pc/memory.h>
/*
* Note: These functions defined in this file may be called from C.

View file

@ -75,10 +75,6 @@ grub_machine_set_prefix (void)
char *filename;
char *prefix;
if (grub_env_get ("prefix"))
/* We already set prefix in grub_machine_init(). */
return;
if (grub_prefix[0])
{
grub_env_set ("prefix", grub_prefix);

View file

@ -114,7 +114,6 @@ grub_set_root_dev (void)
const char *prefix;
grub_register_variable_hook ("root", 0, grub_env_write_root);
grub_env_export ("root");
prefix = grub_env_get ("prefix");
@ -167,7 +166,6 @@ grub_main (void)
/* It is better to set the root device as soon as possible,
for convenience. */
grub_machine_set_prefix ();
grub_env_export ("prefix");
grub_set_root_dev ();
grub_register_core_commands ();