Merge mainline.

This commit is contained in:
Manoel Rebelo Abranches 2011-04-01 04:45:37 -03:00
commit 50ee5d686d
193 changed files with 9983 additions and 1425 deletions

View file

@ -52,13 +52,13 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
grub_efi_status_t status;
grub_efi_boot_services_t *b;
#if GRUB_TARGET_SIZEOF_VOID_P < 8
#if 1
/* Limit the memory access to less than 4GB for 32-bit platforms. */
if (address > 0xffffffff)
return 0;
#endif
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
#if 1
if (address == 0)
{
type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
@ -251,7 +251,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
{
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
#if 1
&& desc->physical_start <= 0xffffffff
#endif
&& desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
@ -267,7 +267,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
desc->physical_start = 0x100000;
}
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
#if 1
if (BYTES_TO_PAGES (filtered_desc->physical_start)
+ filtered_desc->num_pages
> BYTES_TO_PAGES (0x100000000LL))

View file

@ -171,11 +171,12 @@ grub_elf32_phdr_iterate (grub_elf_t elf,
/* Calculate the amount of memory spanned by the segments. */
grub_size_t
grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
grub_elf32_size (grub_elf_t elf, Elf32_Addr *base, grub_uint32_t *max_align)
{
Elf32_Addr segments_start = (Elf32_Addr) -1;
Elf32_Addr segments_end = 0;
int nr_phdrs = 0;
grub_uint32_t curr_align = 1;
/* Run through the program headers to calculate the total memory size we
* should claim. */
@ -192,6 +193,8 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
segments_start = phdr->p_paddr;
if (phdr->p_paddr + phdr->p_memsz > segments_end)
segments_end = phdr->p_paddr + phdr->p_memsz;
if (curr_align < phdr->p_align)
curr_align = phdr->p_align;
return 0;
}
@ -215,7 +218,8 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
if (base)
*base = segments_start;
if (max_align)
*max_align = curr_align;
return segments_end - segments_start;
}
@ -290,7 +294,6 @@ grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook,
return err;
}
/* 64-bit */
@ -357,16 +360,17 @@ grub_elf64_phdr_iterate (grub_elf_t elf,
/* Calculate the amount of memory spanned by the segments. */
grub_size_t
grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
grub_elf64_size (grub_elf_t elf, Elf64_Addr *base, grub_uint64_t *max_align)
{
Elf64_Addr segments_start = (Elf64_Addr) -1;
Elf64_Addr segments_end = 0;
int nr_phdrs = 0;
grub_uint64_t curr_align = 1;
/* Run through the program headers to calculate the total memory size we
* should claim. */
auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg);
int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)),
int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)),
Elf64_Phdr *phdr,
void *_arg __attribute__ ((unused)))
{
@ -378,6 +382,8 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
segments_start = phdr->p_paddr;
if (phdr->p_paddr + phdr->p_memsz > segments_end)
segments_end = phdr->p_paddr + phdr->p_memsz;
if (curr_align < phdr->p_align)
curr_align = phdr->p_align;
return 0;
}
@ -401,11 +407,11 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
if (base)
*base = segments_start;
if (max_align)
*max_align = curr_align;
return segments_end - segments_start;
}
/* Load every loadable segment into memory specified by `_load_hook'. */
grub_err_t
grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook,

View file

@ -17,7 +17,9 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <config.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
@ -135,8 +137,12 @@ find_root_device_from_mountinfo (const char *dir)
continue; /* only a subtree is mounted */
enc_path_len = strlen (enc_path);
/* Check that enc_path is a prefix of dir. The prefix must either be
the entire string, or end with a slash, or be immediately followed
by a slash. */
if (strncmp (dir, enc_path, enc_path_len) != 0 ||
(dir[enc_path_len] && dir[enc_path_len] != '/'))
(enc_path_len && dir[enc_path_len - 1] != '/' &&
dir[enc_path_len] && dir[enc_path_len] != '/'))
continue;
/* This is a parent of the requested directory. /proc/self/mountinfo
@ -178,7 +184,7 @@ find_root_device_from_mountinfo (const char *dir)
static char *
find_root_device_from_libzfs (const char *dir)
{
char *device;
char *device = NULL;
char *poolname;
char *poolfs;
@ -219,7 +225,10 @@ find_root_device_from_libzfs (const char *dir)
struct stat st;
if (stat (device, &st) == 0)
break;
{
device = xstrdup (device);
break;
}
device = NULL;
}
@ -582,6 +591,8 @@ grub_util_is_dmraid (const char *os_dev)
return 1;
else if (! strncmp (os_dev, "/dev/mapper/sil_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/ddf1_", 17))
return 1;
return 0;
}
@ -792,11 +803,36 @@ grub_util_get_grub_dev (const char *os_dev)
#ifdef __linux__
{
char *mdadm_name = get_mdadm_name (os_dev);
struct stat st;
if (mdadm_name)
{
free (grub_dev);
grub_dev = xasprintf ("md/%s", mdadm_name);
char *newname;
char *q;
for (q = os_dev + strlen (os_dev) - 1; q >= os_dev && isdigit (*q);
q--);
if (q >= os_dev && *q == 'p')
{
newname = xasprintf ("/dev/md/%sp%s", mdadm_name, q + 1);
if (stat (newname, &st) == 0)
{
free (grub_dev);
grub_dev = xasprintf ("md/%s,%s", mdadm_name, q + 1);
goto done;
}
free (newname);
}
newname = xasprintf ("/dev/md/%s", mdadm_name);
if (stat (newname, &st) == 0)
{
free (grub_dev);
grub_dev = xasprintf ("md/%s", mdadm_name);
}
done:
free (newname);
free (mdadm_name);
}
}

View file

@ -92,6 +92,8 @@ struct hd_geometry
# include <sys/disk.h> /* DIOCGMEDIASIZE */
# include <sys/param.h>
# include <sys/sysctl.h>
# define MAJOR(dev) major(dev)
# define FLOPPY_MAJOR 2
#endif
#if defined(__APPLE__)
@ -102,7 +104,9 @@ struct hd_geometry
# include <libdevmapper.h>
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <libgeom.h>
#elif defined(__NetBSD__)
# define HAVE_DIOCGDINFO
# include <sys/ioctl.h>
# include <sys/disklabel.h> /* struct disklabel */
@ -337,7 +341,68 @@ device_is_mapped (const char *dev)
}
#endif /* HAVE_DEVICE_MAPPER */
#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
/* FIXME: geom actually gives us the whole container hierarchy.
It can be used more efficiently than this. */
static void
follow_geom_up (const char *name, grub_disk_addr_t *off_out, char **name_out)
{
struct gmesh mesh;
struct gclass *class;
int error;
struct ggeom *geom;
grub_util_info ("following geom '%s'", name);
error = geom_gettree (&mesh);
if (error != 0)
grub_util_error ("couldn't open geom");
LIST_FOREACH (class, &mesh.lg_class, lg_class)
if (strcasecmp (class->lg_name, "part") == 0)
break;
if (!class)
grub_util_error ("couldn't open geom part");
LIST_FOREACH (geom, &class->lg_geom, lg_geom)
{
struct gprovider *provider;
LIST_FOREACH (provider, &geom->lg_provider, lg_provider)
if (strcmp (provider->lg_name, name) == 0)
{
char *name_tmp = xstrdup (geom->lg_name);
grub_disk_addr_t off = 0;
struct gconfig *config;
grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name);
follow_geom_up (name_tmp, &off, name_out);
free (name_tmp);
LIST_FOREACH (config, &provider->lg_config, lg_config)
if (strcasecmp (config->lg_name, "start") == 0)
off += strtoull (config->lg_val, 0, 10);
if (off_out)
*off_out = off;
return;
}
}
grub_util_info ("geom '%s' has no parent", name);
if (name_out)
*name_out = xstrdup (name);
if (off_out)
*off_out = 0;
}
static grub_disk_addr_t
find_partition_start (const char *dev)
{
grub_disk_addr_t out;
if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0)
return 0;
follow_geom_up (dev + sizeof ("/dev/") - 1, &out, NULL);
return out;
}
#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
static grub_disk_addr_t
find_partition_start (const char *dev)
{
@ -453,9 +518,12 @@ devmapper_fail:
# if !defined(HAVE_DIOCGDINFO)
return hdg.start;
# else /* defined(HAVE_DIOCGDINFO) */
p_index = dev[strlen(dev) - 1] - 'a';
if (p_index >= label.d_npartitions)
if (dev[0])
p_index = dev[strlen(dev) - 1] - 'a';
else
p_index = -1;
if (p_index >= label.d_npartitions || p_index < 0)
{
grub_error (GRUB_ERR_BAD_DEVICE,
"no disk label entry for `%s'", dev);
@ -1152,16 +1220,22 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|| strncmp ("sd", p, 2) == 0)
&& p[2] >= 'a' && p[2] <= 'z')
{
/* /dev/[hsv]d[a-z][0-9]* */
p[3] = '\0';
char *pp = p + 2;
while (*pp >= 'a' && *pp <= 'z')
pp++;
/* /dev/[hsv]d[a-z]+[0-9]* */
*pp = '\0';
return path;
}
/* If this is a Xen virtual block device. */
if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z')
{
/* /dev/xvd[a-z][0-9]* */
p[4] = '\0';
char *pp = p + 3;
while (*pp >= 'a' && *pp <= 'z')
pp++;
/* /dev/xvd[a-z]+[0-9]* */
*pp = '\0';
return path;
}
@ -1278,7 +1352,17 @@ devmapper_out:
path[8] = 0;
return path;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
char *out, *out2;
if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0)
return xstrdup (os_dev);
follow_geom_up (os_dev + sizeof ("/dev/") - 1, NULL, &out);
out2 = xasprintf ("/dev/%s", out);
free (out);
return out2;
#elif defined(__APPLE__)
char *path = xstrdup (os_dev);
if (strncmp ("/dev/", path, 5) == 0)
{
@ -1434,6 +1518,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
if (stat (os_dev, &st) < 0)
{
grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", os_dev);
grub_util_info ("cannot stat `%s'", os_dev);
return 0;
}
@ -1442,6 +1527,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
{
grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"no mapping exists for `%s'", os_dev);
grub_util_info ("no mapping exists for `%s'", os_dev);
return 0;
}
@ -1456,7 +1542,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
#endif
return make_device_name (drive, -1, -1);
#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
/* Linux counts partitions uniformly, whether a BSD partition or a DOS
partition, so mapping them to GRUB devices is not trivial.
Here, get the start sector of a partition by HDIO_GETGEO, and

View file

@ -240,3 +240,23 @@ grub_register_variable_hook (const char *name,
return GRUB_ERR_NONE;
}
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->global = 1;
return GRUB_ERR_NONE;
}

View file

@ -140,36 +140,27 @@ compact_mem_regions (void)
}
}
/*
*
* grub_get_conv_memsize(i) : return the conventional memory size in KB.
* BIOS call "INT 12H" to get conventional memory size
* The return value in AX.
*/
static inline grub_uint16_t
grub_get_conv_memsize (void)
{
struct grub_bios_int_registers regs;
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
grub_bios_interrupt (0x12, &regs);
return regs.eax & 0xffff;
}
void
grub_machine_init (void)
{
int i;
#if 0
int grub_lower_mem;
#endif
/* Initialize the console as early as possible. */
grub_console_init ();
/* This sanity check is useless since top of GRUB_MEMORY_MACHINE_RESERVED_END
is used for stack and if it's unavailable we wouldn't have gotten so far.
*/
#if 0
grub_lower_mem = grub_get_conv_memsize () << 10;
/* Sanity check. */
if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
grub_fatal ("too small memory");
#endif
/* FIXME: This prevents loader/i386/linux.c from using low memory. When our
heap implements support for requesting a chunk in low memory, this should

View file

@ -36,6 +36,22 @@ struct grub_machine_mmap_entry
} __attribute__((packed));
/*
*
* grub_get_conv_memsize(i) : return the conventional memory size in KB.
* BIOS call "INT 12H" to get conventional memory size
* The return value in AX.
*/
static inline grub_uint16_t
grub_get_conv_memsize (void)
{
struct grub_bios_int_registers regs;
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
grub_bios_interrupt (0x12, &regs);
return regs.eax & 0xffff;
}
/*
* grub_get_ext_memsize() : return the extended memory size in KB.
* BIOS call "INT 15H, AH=88H" to get extended memory size
@ -155,6 +171,10 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
if (hook (0x0, ((grub_uint32_t) grub_get_conv_memsize ()) << 10,
GRUB_MEMORY_AVAILABLE))
return 0;
if (eisa_mmap)
{
if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10,
@ -162,7 +182,8 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE);
}
else
hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MEMORY_AVAILABLE);
hook (0x100000, ((grub_uint32_t) grub_get_ext_memsize ()) << 10,
GRUB_MEMORY_AVAILABLE);
}
return 0;

View file

@ -151,8 +151,6 @@ LOCAL (codestart):
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx
movl reed_solomon_redundancy, %ecx
leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax
testl %edx, %edx
jz post_reed_solomon
call EXT_C (grub_reed_solomon_recover)
jmp post_reed_solomon
@ -224,6 +222,7 @@ multiboot_trampoline:
movb $0xFF, %dh
/* enter the usual booting */
call prot_to_real
jmp LOCAL (codestart)
post_reed_solomon:
@ -649,7 +648,7 @@ FUNCTION(grub_console_getkey)
jae 2f
movl %edx, %eax
leal LOCAL(bypass_table), %edi
movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) / 2), %ecx
movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) >> 1), %ecx
repne scasw
jz 3f

View file

@ -84,6 +84,9 @@ grub_ieee1275_find_options (void)
if (rc >= 0 && !grub_strcmp (tmp, "Emulated PC"))
is_qemu = 1;
if (grub_strncmp (tmp, "PowerMac", sizeof ("PowerMac") - 1) == 0)
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS);
if (is_smartfirmware)
{
/* Broken in all versions */

View file

@ -50,6 +50,12 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"couldn't examine /memory/available property");
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS))
{
address_cells = 1;
size_cells = 1;
}
/* Decode each entry and call `hook'. */
i = 0;
available_size /= sizeof (grub_uint32_t);

View file

@ -189,6 +189,8 @@ grub_main (void)
for convenience. */
grub_machine_set_prefix ();
grub_set_root_dev ();
grub_env_export ("root");
grub_env_export ("prefix");
grub_register_core_commands ();

View file

@ -41,6 +41,7 @@ extern void grub_at_keyboard_init (void);
extern void grub_serial_init (void);
extern void grub_terminfo_init (void);
extern void grub_keylayouts_init (void);
extern void grub_boot_init (void);
/* FIXME: use interrupt to count high. */
grub_uint64_t
@ -210,6 +211,8 @@ grub_machine_init (void)
grub_terminfo_init ();
grub_serial_init ();
grub_boot_init ();
}
void
@ -223,6 +226,8 @@ grub_halt (void)
grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG)
& ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG);
grub_millisleep (1500);
grub_printf ("Shutdown failed\n");
grub_refresh ();
while (1);
@ -239,6 +244,8 @@ grub_reboot (void)
{
grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT);
grub_millisleep (1500);
grub_printf ("Reboot failed\n");
grub_refresh ();
while (1);

View file

@ -37,80 +37,80 @@
.text
FUNCTION(efi_wrap_0)
subq $40, %rsp
subq $48, %rsp
call *%rdi
addq $40, %rsp
addq $48, %rsp
ret
FUNCTION(efi_wrap_1)
subq $40, %rsp
subq $48, %rsp
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
addq $48, %rsp
ret
FUNCTION(efi_wrap_2)
subq $40, %rsp
subq $48, %rsp
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
addq $48, %rsp
ret
FUNCTION(efi_wrap_3)
subq $40, %rsp
subq $48, %rsp
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
addq $48, %rsp
ret
FUNCTION(efi_wrap_4)
subq $40, %rsp
subq $48, %rsp
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
addq $48, %rsp
ret
FUNCTION(efi_wrap_5)
subq $40, %rsp
subq $48, %rsp
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
addq $48, %rsp
ret
FUNCTION(efi_wrap_6)
subq $56, %rsp
mov 56+8(%rsp), %rax
subq $64, %rsp
mov 64+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $56, %rsp
addq $64, %rsp
ret
FUNCTION(efi_wrap_10)
subq $88, %rsp
mov 88+40(%rsp), %rax
subq $96, %rsp
mov 96+40(%rsp), %rax
mov %rax, 72(%rsp)
mov 88+32(%rsp), %rax
mov 96+32(%rsp), %rax
mov %rax, 64(%rsp)
mov 88+24(%rsp), %rax
mov 96+24(%rsp), %rax
mov %rax, 56(%rsp)
mov 88+16(%rsp), %rax
mov 96+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 88+8(%rsp), %rax
mov 96+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $88, %rsp
addq $96, %rsp
ret