merge mainline into newenv

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-20 21:31:39 +01:00
commit 61c501a941
415 changed files with 17977 additions and 6997 deletions

View file

@ -37,7 +37,7 @@ grub_register_command_prio (const char *name,
cmd->name = name;
cmd->func = func;
cmd->summary = (summary) ? summary : name;
cmd->summary = (summary) ? summary : "";
cmd->description = description;
cmd->flags = GRUB_COMMAND_FLAG_BOTH;

View file

@ -178,11 +178,11 @@ void
grub_register_core_commands (void)
{
grub_register_command ("set", grub_core_cmd_set,
"set [ENVVAR=VALUE]", "set an environment variable");
"[ENVVAR=VALUE]", "Set an environment variable.");
grub_register_command ("unset", grub_core_cmd_unset,
"unset ENVVAR", "remove an environment variable");
"ENVVAR", "Remove an environment variable.");
grub_register_command ("ls", grub_core_cmd_ls,
"ls [ARG]", "list devices or files");
"[ARG]", "List devices or files.");
grub_register_command ("insmod", grub_core_cmd_insmod,
"insmod MODULE", "insert a module");
"MODULE", "Insert a module.");
}

View file

@ -1,7 +1,7 @@
/* device.c - device manager */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2005,2007,2008,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
@ -86,7 +86,7 @@ grub_device_iterate (int (*hook) (const char *name))
struct part_ent
{
struct part_ent *next;
char name[0];
char *name;
} *ents;
int iterate_disk (const char *disk_name)
@ -118,6 +118,7 @@ grub_device_iterate (int (*hook) (const char *name))
if (!ret)
ret = hook (p->name);
grub_free (p->name);
grub_free (p);
p = next;
}
@ -138,15 +139,20 @@ grub_device_iterate (int (*hook) (const char *name))
if (! partition_name)
return 1;
p = grub_malloc (sizeof (p->next) + grub_strlen (disk->name) + 1 +
grub_strlen (partition_name) + 1);
p = grub_malloc (sizeof (*p));
if (!p)
{
grub_free (partition_name);
return 1;
}
grub_sprintf (p->name, "%s,%s", disk->name, partition_name);
p->name = grub_xasprintf ("%s,%s", disk->name, partition_name);
if (!p->name)
{
grub_free (partition_name);
grub_free (p);
return 1;
}
grub_free (partition_name);
p->next = ents;

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,2004,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
@ -386,8 +386,6 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
char *tmp_buf;
unsigned real_offset;
grub_dprintf ("disk", "Reading `%s'...\n", disk->name);
/* First of all, check if the region is within the disk. */
if (grub_disk_adjust_range (disk, &sector, &offset, size) != GRUB_ERR_NONE)
{
@ -432,8 +430,9 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
else
{
/* Otherwise read data from the disk actually. */
if ((disk->dev->read) (disk, start_sector,
GRUB_DISK_CACHE_SIZE, tmp_buf)
if (start_sector + GRUB_DISK_CACHE_SIZE > disk->total_sectors
|| (disk->dev->read) (disk, start_sector,
GRUB_DISK_CACHE_SIZE, tmp_buf)
!= GRUB_ERR_NONE)
{
/* Uggh... Failed. Instead, just read necessary data. */

View file

@ -341,6 +341,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
switch (type)
{
case STT_NOTYPE:
case STT_OBJECT:
/* Resolve a global symbol. */
if (sym->st_name != 0 && sym->st_shndx == 0)
{
@ -350,15 +351,13 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
"the symbol `%s' not found", name);
}
else
sym->st_value = 0;
break;
case STT_OBJECT:
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
sym->st_shndx);
if (bind != STB_LOCAL)
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
return grub_errno;
{
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
sym->st_shndx);
if (bind != STB_LOCAL)
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
return grub_errno;
}
break;
case STT_FUNC:
@ -628,12 +627,10 @@ grub_dl_load (const char *name)
return 0;
}
filename = (char *) grub_malloc (grub_strlen (grub_dl_dir) + 1
+ grub_strlen (name) + 4 + 1);
filename = grub_xasprintf ("%s/%s.mod", grub_dl_dir, name);
if (! filename)
return 0;
grub_sprintf (filename, "%s/%s.mod", grub_dl_dir, name);
mod = grub_dl_load_file (filename);
grub_free (filename);

View file

@ -1,7 +1,7 @@
/* efi.c - generic EFI support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2006,2007,2008,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

View file

@ -63,11 +63,10 @@ grub_efi_set_prefix (void)
if (p)
*p = '\0';
prefix = grub_malloc (1 + grub_strlen (device) + 1
+ grub_strlen (file) + 1);
prefix = grub_xasprintf ("(%s)%s", device, file);
if (prefix)
{
grub_sprintf (prefix, "(%s)%s", device, file);
grub_env_set ("prefix", prefix);
grub_free (prefix);
}
@ -82,6 +81,5 @@ void
grub_efi_fini (void)
{
grub_efidisk_fini ();
grub_efi_mm_fini ();
grub_console_fini ();
}

View file

@ -1,7 +1,7 @@
/* mm.c - generic EFI memory management */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2006,2007,2008,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

View file

@ -1,7 +1,7 @@
/* elf.c - load ELF files */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2003,2004,2005,2006,2007,2008,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
@ -74,7 +74,7 @@ grub_elf_file (grub_file_t file)
!= sizeof (elf->ehdr))
{
grub_error_push ();
grub_error (GRUB_ERR_READ_ERROR, "Cannot read ELF header.");
grub_error (GRUB_ERR_READ_ERROR, "cannot read ELF header");
goto fail;
}
@ -134,7 +134,7 @@ grub_elf32_load_phdrs (grub_elf_t elf)
|| (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
{
grub_error_push ();
return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
return grub_error (GRUB_ERR_READ_ERROR, "cannot read program headers");
}
return GRUB_ERR_NONE;
@ -172,7 +172,7 @@ 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)
grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
{
Elf32_Addr segments_start = (Elf32_Addr) -1;
Elf32_Addr segments_end = 0;
@ -198,23 +198,28 @@ grub_elf32_size (grub_elf_t elf)
grub_elf32_phdr_iterate (elf, calcsize, 0);
if (base)
*base = 0;
if (nr_phdrs == 0)
{
grub_error (GRUB_ERR_BAD_OS, "No program headers present");
grub_error (GRUB_ERR_BAD_OS, "no program headers present");
return 0;
}
if (segments_end < segments_start)
{
/* Very bad addresses. */
grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses");
grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses");
return 0;
}
if (base)
*base = segments_start;
return segments_end - segments_start;
}
/* Load every loadable segment into memory specified by `_load_hook'. */
grub_err_t
grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook,
@ -249,7 +254,7 @@ grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook,
{
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS,
"Invalid offset in program header.");
"invalid offset in program header");
}
if (phdr->p_filesz)
@ -261,8 +266,8 @@ grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook,
/* XXX How can we free memory from `load_hook'? */
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS,
"Couldn't read segment from file: "
"wanted 0x%lx bytes; read 0x%lx bytes.",
"couldn't read segment from file: "
"wanted 0x%lx bytes; read 0x%lx bytes",
phdr->p_filesz, read);
}
}
@ -315,7 +320,7 @@ grub_elf64_load_phdrs (grub_elf_t elf)
|| (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
{
grub_error_push ();
return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
return grub_error (GRUB_ERR_READ_ERROR, "cannot read program headers");
}
return GRUB_ERR_NONE;
@ -353,7 +358,7 @@ 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)
grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
{
Elf64_Addr segments_start = (Elf64_Addr) -1;
Elf64_Addr segments_end = 0;
@ -379,19 +384,25 @@ grub_elf64_size (grub_elf_t elf)
grub_elf64_phdr_iterate (elf, calcsize, 0);
if (base)
*base = 0;
if (nr_phdrs == 0)
{
grub_error (GRUB_ERR_BAD_OS, "No program headers present");
grub_error (GRUB_ERR_BAD_OS, "no program headers present");
return 0;
}
if (segments_end < segments_start)
{
/* Very bad addresses. */
grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses");
grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses");
return 0;
}
if (base)
*base = segments_start;
return segments_end - segments_start;
}
@ -431,7 +442,7 @@ grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook,
{
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS,
"Invalid offset in program header.");
"invalid offset in program header");
}
if (phdr->p_filesz)
@ -443,8 +454,8 @@ grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook,
/* XXX How can we free memory from `load_hook'? */
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS,
"Couldn't read segment from file: "
"wanted 0x%lx bytes; read 0x%lx bytes.",
"couldn't read segment from file: "
"wanted 0x%lx bytes; read 0x%lx bytes",
phdr->p_filesz, read);
}
}

View file

@ -156,10 +156,11 @@ grub_env_unset (const char *name)
if (! var)
return;
/* XXX: It is not possible to unset variables with a read or write
hook. */
if (var->read_hook || var->write_hook)
return;
{
grub_env_set (name, "");
return;
}
grub_env_remove (var);

View file

@ -20,6 +20,7 @@
#include <grub/err.h>
#include <grub/misc.h>
#include <stdarg.h>
#include <grub/i18n.h>
#define GRUB_MAX_ERRMSG 256
#define GRUB_ERROR_STACK_SIZE 10
@ -44,7 +45,7 @@ grub_error (grub_err_t n, const char *fmt, ...)
grub_errno = n;
va_start (ap, fmt);
grub_vsprintf (grub_errmsg, fmt, ap);
grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
va_end (ap);
return n;
@ -56,7 +57,7 @@ grub_fatal (const char *fmt, ...)
va_list ap;
va_start (ap, fmt);
grub_vprintf (fmt, ap);
grub_vprintf (_(fmt), ap);
va_end (ap);
grub_abort ();
@ -121,7 +122,7 @@ grub_print_error (void)
do
{
if (grub_errno != GRUB_ERR_NONE)
grub_err_printf ("error: %s\n", grub_errmsg);
grub_err_printf (_("error: %s.\n"), grub_errmsg);
}
while (grub_error_pop ());

View file

@ -1,7 +1,7 @@
/* file.c - file I/O functions */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2006,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2006,2007,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
@ -115,7 +115,7 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
if (file->offset > file->size)
{
grub_error (GRUB_ERR_OUT_OF_RANGE,
"Attempt to read past the end of file.");
"attempt to read past the end of file");
return -1;
}

View file

@ -66,7 +66,7 @@ multiboot_header:
.long -0x1BADB002 - MULTIBOOT_MEMORY_INFO
codestart:
cmpl $MULTIBOOT_MAGIC2, %eax
cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax
jne 0f
movl %ebx, EXT_C(startup_multiboot_info)
0:

View file

@ -1,7 +1,7 @@
/* dl-386.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2005,2007,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

View file

@ -59,7 +59,7 @@ VARIABLE(grub_linux_real_addr)
VARIABLE(grub_linux_is_bzimage)
.long 0
FUNCTION(grub_linux16_boot)
FUNCTION(grub_linux16_real_boot)
/* Must be done before zImage copy. */
call EXT_C(grub_dl_unload_all)

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,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
@ -56,22 +56,30 @@ static char *
make_install_device (void)
{
/* XXX: This should be enough. */
char dev[100];
char dev[100], *ptr = dev;
if (grub_prefix[0] != '(')
{
/* No hardcoded root partition - make it from the boot drive and the
partition number encoded at the install time. */
grub_sprintf (dev, "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
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_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
grub_snprintf (ptr, sizeof (dev) - (ptr - dev),
",%u", grub_install_dos_part + 1);
ptr += grub_strlen (ptr);
if (grub_install_bsd_part >= 0)
grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c",
grub_install_bsd_part + 'a');
grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix);
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,2008 Free Software Foundation, Inc.
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,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
@ -764,6 +764,11 @@ FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)
movw %cx, %ax
movw %bx, %ds
int $0x13 /* do the operation */
jc noclean
/* Clean return value if carry isn't set to workaround
some buggy BIOSes. */
xor %ax, %ax
noclean:
movb %ah, %bl /* save return value in %bl */
/* back to protected mode */
DATA32 call real_to_prot
@ -807,6 +812,11 @@ FUNCTION(grub_biosdisk_get_diskinfo_standard)
.code16
movb $0x8, %ah
int $0x13 /* do the operation */
jc noclean2
/* Clean return value if carry isn't set to workaround
some buggy BIOSes. */
xor %ax, %ax
noclean2:
/* check if successful */
testb %ah, %ah
jnz 1f

View file

@ -22,7 +22,7 @@
#include <grub/types.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/i386/cmos.h>
#include <grub/cmos.h>
#define QEMU_CMOS_MEMSIZE_HIGH 0x35
#define QEMU_CMOS_MEMSIZE_LOW 0x34

View file

@ -81,7 +81,7 @@ codestart:
movl $END_SYMBOL, %ecx
subl %edi, %ecx
#endif
/* clean out */
xorl %eax, %eax
cld

View file

@ -1,7 +1,7 @@
/* of.c - Access the Open Firmware client interface. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2003,2004,2005,2007,2008,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

View file

@ -1,7 +1,7 @@
/* init.c -- Initialize GRUB on the newworld mac (PPC). */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2003,2004,2005,2007,2008,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
@ -111,11 +111,12 @@ grub_machine_set_prefix (void)
*lastslash = '\0';
grub_translate_ieee1275_path (filename);
newprefix = grub_malloc (grub_strlen (prefix)
+ grub_strlen (filename));
grub_sprintf (newprefix, "%s%s", prefix, filename);
grub_free (prefix);
prefix = newprefix;
newprefix = grub_xasprintf ("%s%s", prefix, filename);
if (newprefix)
{
grub_free (prefix);
prefix = newprefix;
}
}
}
@ -164,7 +165,7 @@ static void grub_claim_heap (void)
/* Claim and use it. */
if (grub_claimmap (addr, len) < 0)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Failed to claim heap at 0x%llx, len 0x%llx\n",
"failed to claim heap at 0x%llx, len 0x%llx",
addr, len);
grub_mm_init_region ((void *) (grub_addr_t) addr, len);
}

View file

@ -44,11 +44,11 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
/* Load `/memory/available'. */
if (grub_ieee1275_finddevice ("/memory", &memory))
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"Couldn't find /memory node");
"couldn't find /memory node");
if (grub_ieee1275_get_integer_property (memory, "available", available,
sizeof available, &available_size))
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"Couldn't examine /memory/available property");
"couldn't examine /memory/available property");
/* Decode each entry and call `hook'. */
i = 0;

View file

@ -38,7 +38,7 @@ grub_children_iterate (char *devpath,
grub_ieee1275_phandle_t dev;
grub_ieee1275_phandle_t child;
char *childtype, *childpath;
char *childname, *fullname;
char *childname;
int ret = 0;
if (grub_ieee1275_finddevice (devpath, &dev))
@ -63,19 +63,12 @@ grub_children_iterate (char *devpath,
grub_free (childtype);
return 0;
}
fullname = grub_malloc (IEEE1275_MAX_PATH_LEN);
if (!fullname)
{
grub_free (childname);
grub_free (childpath);
grub_free (childtype);
return 0;
}
do
{
struct grub_ieee1275_devalias alias;
grub_ssize_t actual;
char *fullname;
if (grub_ieee1275_get_property (child, "device_type", childtype,
IEEE1275_MAX_PROP_LEN, &actual))
@ -89,18 +82,25 @@ grub_children_iterate (char *devpath,
IEEE1275_MAX_PROP_LEN, &actual))
continue;
grub_sprintf (fullname, "%s/%s", devpath, childname);
fullname = grub_xasprintf ("%s/%s", devpath, childname);
if (!fullname)
{
grub_free (childname);
grub_free (childpath);
grub_free (childtype);
return 0;
}
alias.type = childtype;
alias.path = childpath;
alias.name = fullname;
ret = hook (&alias);
grub_free (fullname);
if (ret)
break;
}
while (grub_ieee1275_peer (child, &child));
grub_free (fullname);
grub_free (childname);
grub_free (childpath);
grub_free (childtype);
@ -308,13 +308,13 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
file path properly. */
if (grub_ieee1275_finddevice (device, &dev))
{
grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Device %s not found\n", device);
grub_error (GRUB_ERR_UNKNOWN_DEVICE, "device %s not found", device);
goto fail;
}
if (grub_ieee1275_get_property (dev, "device_type", &type, sizeof type, 0))
{
grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"Device %s lacks a device_type property\n", device);
"device %s lacks a device_type property", device);
goto fail;
}
@ -330,12 +330,11 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
{
char *filepath = comma + 1;
ret = grub_malloc (grub_strlen (filepath) + 1);
/* Make sure filepath has leading backslash. */
if (filepath[0] != '\\')
grub_sprintf (ret, "\\%s", filepath);
ret = grub_xasprintf ("\\%s", filepath);
else
grub_strcpy (ret, filepath);
ret = grub_strdup (filepath);
}
}
else if (ptype == GRUB_PARSE_PARTITION)
@ -383,15 +382,10 @@ grub_ieee1275_encode_devname (const char *path)
/* GRUB partition 1 is OF partition 0. */
partno++;
/* Assume partno will require less than five bytes to encode. */
encoding = grub_malloc (grub_strlen (device) + 3 + 5);
grub_sprintf (encoding, "(%s,%d)", device, partno);
encoding = grub_xasprintf ("(%s,%d)", device, partno);
}
else
{
encoding = grub_malloc (grub_strlen (device) + 2);
grub_sprintf (encoding, "(%s)", device);
}
encoding = grub_xasprintf ("(%s)", device);
grub_free (partition);
grub_free (device);

View file

@ -1,7 +1,7 @@
/* main.c - the kernel main routine */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2005,2006,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,2005,2006,2008,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
@ -158,6 +158,9 @@ grub_main (void)
/* Load pre-loaded modules and free the space. */
grub_register_exported_symbols ();
#ifdef GRUB_LINKER_HAVE_INIT
grub_arch_dl_init_linker ();
#endif
grub_load_modules ();
/* It is better to set the root device as soon as possible,
@ -167,9 +170,8 @@ grub_main (void)
grub_register_core_commands ();
grub_register_rescue_parser ();
grub_register_rescue_reader ();
grub_load_config ();
grub_load_normal_mode ();
grub_reader_loop (0);
grub_rescue_run ();
}

7
kern/mips/cache.S Normal file
View file

@ -0,0 +1,7 @@
#include <grub/symbol.h>
FUNCTION (grub_cpu_flush_cache)
FUNCTION (grub_arch_sync_caches)
#include "cache_flush.S"
j $ra

23
kern/mips/cache_flush.S Normal file
View file

@ -0,0 +1,23 @@
move $t2, $a0
addu $t3, $a0, $a1
srl $t2, $t2, 5
sll $t2, $t2, 5
addu $t3, $t3, 0x1f
srl $t3, $t3, 5
sll $t3, $t3, 5
move $t0, $t2
subu $t1, $t3, $t2
1:
cache 1, 0($t0)
addiu $t0, $t0, 0x1
addiu $t1, $t1, 0xffff
bne $t1, $zero, 1b
sync
move $t0, $t2
subu $t1, $t3, $t2
2:
cache 0, 0($t0)
addiu $t0, $t0, 0x1
addiu $t1, $t1, 0xffff
bne $t1, $zero, 2b
sync

237
kern/mips/dl.c Normal file
View file

@ -0,0 +1,237 @@
/* dl-386.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007,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/dl.h>
#include <grub/elf.h>
#include <grub/misc.h>
#include <grub/err.h>
#include <grub/cpu/types.h>
#include <grub/mm.h>
/* Dummy __gnu_local_gp. Resolved by linker. */
static char __gnu_local_gp_dummy;
/* Check if EHDR is a valid ELF header. */
grub_err_t
grub_arch_dl_check_header (void *ehdr)
{
Elf_Ehdr *e = ehdr;
/* Check the magic numbers. */
#ifdef WORDS_BIGENDIAN
if (e->e_ident[EI_CLASS] != ELFCLASS32
|| e->e_ident[EI_DATA] != ELFDATA2MSB
|| e->e_machine != EM_MIPS)
#else
if (e->e_ident[EI_CLASS] != ELFCLASS32
|| e->e_ident[EI_DATA] != ELFDATA2LSB
|| e->e_machine != EM_MIPS)
#endif
return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
return GRUB_ERR_NONE;
}
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
Elf_Word entsize;
unsigned i;
grub_size_t gp_size = 0;
/* FIXME: suboptimal. */
grub_uint32_t *gp, *gpptr;
grub_uint32_t gp0;
/* Find a symbol table. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
entsize = s->sh_entsize;
/* Find reginfo. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_MIPS_REGINFO)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found");
gp0 = ((grub_uint32_t *)((char *) e + s->sh_offset))[5];
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL)
{
grub_dl_segment_t seg;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
Elf_Rel *rel, *max;
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
switch (ELF_R_TYPE (rel->r_info))
{
case R_MIPS_GOT16:
case R_MIPS_CALL16:
case R_MIPS_GPREL32:
gp_size += 4;
break;
}
}
}
if (gp_size > 0x08000)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "__gnu_local_gp is too big\n");
gpptr = gp = grub_malloc (gp_size);
if (!gp)
return grub_errno;
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL)
{
grub_dl_segment_t seg;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
Elf_Rel *rel, *max;
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
{
Elf_Word *addr;
Elf_Sym *sym;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
sym->st_value = (grub_addr_t) gp;
switch (ELF_R_TYPE (rel->r_info))
{
case R_MIPS_HI16:
{
grub_uint32_t value;
Elf_Rel *rel2;
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
value = (*(grub_uint16_t *) addr << 16)
+ sym->st_value + 0x8000;
for (rel2 = rel + 1; rel2 < max; rel2++)
if (ELF_R_SYM (rel2->r_info)
== ELF_R_SYM (rel->r_info)
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
{
value += *(grub_int16_t *)
((char *) seg->addr + rel2->r_offset);
break;
}
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
}
break;
case R_MIPS_LO16:
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
break;
case R_MIPS_32:
*(grub_uint32_t *) addr += sym->st_value;
break;
case R_MIPS_GPREL32:
*(grub_uint32_t *) addr = sym->st_value
+ *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)gp;
break;
case R_MIPS_26:
{
grub_uint32_t value;
grub_uint32_t raw;
raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
value = raw << 2;
value += sym->st_value;
raw = (value >> 2) & 0x3ffffff;
*(grub_uint32_t *) addr =
raw | ((*(grub_uint32_t *) addr) & 0xfc000000);
}
break;
case R_MIPS_GOT16:
case R_MIPS_CALL16:
/* FIXME: reuse*/
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
*(grub_uint16_t *) addr
= sizeof (grub_uint32_t) * (gpptr - gp);
gpptr++;
break;
default:
{
grub_free (gp);
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Unknown relocation type %d\n",
ELF_R_TYPE (rel->r_info));
}
break;
}
}
}
}
return GRUB_ERR_NONE;
}
void
grub_arch_dl_init_linker (void)
{
grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0);
}

View file

@ -1,4 +1,3 @@
/* reader.c - reader support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
@ -17,33 +16,20 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/mm.h>
#include <grub/reader.h>
#include <grub/parser.h>
#include <grub/kernel.h>
#include <grub/env.h>
#include <grub/mips/kernel.h>
struct grub_handler_class grub_reader_class =
{
.name = "reader"
};
grub_err_t
grub_reader_loop (grub_reader_getline_t getline)
void
grub_machine_set_prefix (void)
{
while (1)
{
char *line;
grub_reader_getline_t func;
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
func = (getline) ? : grub_reader_get_current ()->read_line;
if ((func (&line, 0)) || (! line))
return grub_errno;
grub_parser_get_current ()->parse_line (line, func);
grub_free (line);
}
grub_env_set ("prefix", grub_prefix);
}
extern char _end[];
grub_addr_t
grub_arch_modules_addr (void)
{
return (grub_addr_t) _end;
}

View file

@ -0,0 +1,61 @@
#include <grub/kernel.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/time.h>
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/machine/kernel.h>
#include <grub/machine/memory.h>
#include <grub/cpu/kernel.h>
#define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264))
grub_uint32_t
grub_get_rtc (void)
{
static int calln = 0;
return calln++;
}
void
grub_machine_init (void)
{
grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE,
RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff));
grub_install_get_time_ms (grub_rtc_get_time_ms);
}
void
grub_machine_fini (void)
{
}
void
grub_exit (void)
{
while (1);
}
void
grub_halt (void)
{
while (1);
}
void
grub_reboot (void)
{
while (1);
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint64_t,
grub_uint32_t))
{
hook (0, RAMSIZE,
GRUB_MACHINE_MEMORY_AVAILABLE);
return GRUB_ERR_NONE;
}

218
kern/mips/startup.S Normal file
View file

@ -0,0 +1,218 @@
/* startup.S - Startup code for the MIPS. */
/*
* 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/symbol.h>
#include <grub/cpu/kernel.h>
#include <grub/machine/memory.h>
#define BASE_ADDR 8
.extern __bss_start
.extern _end
.globl __start, _start, start
__start:
_start:
start:
bal codestart
base:
. = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE
compressed_size:
.long 0
. = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE
total_module_size:
.long 0
. = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE
kernel_image_size:
.long 0
codestart:
/* Save our base. */
move $s0, $ra
/* Parse arguments. Has to be done before relocation.
So need to do it in asm. */
#ifdef GRUB_MACHINE_MIPS_YEELOONG
/* $a2 has the environment. */
move $t0, $a2
argcont:
lw $t1, 0($t0)
beq $t1, $zero, argdone
#define DO_PARSE(str, reg) \
addiu $t2, $s0, (str-base);\
bal parsestr;\
beq $v0, $zero, 1f;\
move reg, $v0;\
b 2f;\
1:
DO_PARSE (busclockstr, $s2)
DO_PARSE (cpuclockstr, $s3)
DO_PARSE (memsizestr, $s4)
DO_PARSE (highmemsizestr, $s5)
2:
addiu $t0, $t0, 4
b argcont
parsestr:
move $v0, $zero
move $t3, $t1
3:
lb $t4, 0($t2)
lb $t5, 0($t3)
addiu $t2, $t2, 1
addiu $t3, $t3, 1
beq $t5, $zero, 1f
beq $t5, $t4, 3b
bne $t4, $zero, 1f
addiu $t3, $t3, 0xffff
digcont:
lb $t5, 0($t3)
/* Substract '0' from digit. */
addiu $t5, $t5, 0xffd0
bltz $t5, 1f
addiu $t4, $t5, 0xfff7
bgtz $t4, 1f
/* Multiply $v0 by 10 with bitshifts. */
sll $v0, $v0, 1
sll $t4, $v0, 2
addu $v0, $v0, $t4
addu $v0, $v0, $t5
addiu $t3, $t3, 1
b digcont
1:
jr $ra
busclockstr: .asciiz "busclock="
cpuclockstr: .asciiz "cpuclock="
memsizestr: .asciiz "memsize="
highmemsizestr: .asciiz "highmemsize="
.p2align 2
argdone:
#endif
/* Decompress the payload. */
addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR
lui $a1, %hi(compressed)
addiu $a1, %lo(compressed)
lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0)
move $s1, $a1
/* $a0 contains source compressed address, $a1 is destination,
$a2 is compressed size. FIXME: put LZMA here. Don't clober $s0,
$s1, $s2, $s3, $s4 and $s5.
On return $v0 contains uncompressed size.
*/
move $v0, $a2
reloccont:
lb $t4, 0($a0)
sb $t4, 0($a1)
addiu $a1,$a1,1
addiu $a0,$a0,1
addiu $a2, 0xffff
bne $a2, $0, reloccont
move $a0, $s1
move $a1, $v0
#include "cache_flush.S"
lui $t1, %hi(cont)
addiu $t1, %lo(cont)
jr $t1
. = _start + GRUB_KERNEL_CPU_RAW_SIZE
compressed:
. = _start + GRUB_KERNEL_CPU_PREFIX
VARIABLE(grub_prefix)
/* to be filled by grub-mkelfimage */
/*
* Leave some breathing room for the prefix.
*/
. = _start + GRUB_KERNEL_CPU_DATA_END
#ifdef GRUB_MACHINE_MIPS_YEELOONG
VARIABLE (grub_arch_busclock)
.long 0
VARIABLE (grub_arch_cpuclock)
.long 0
VARIABLE (grub_arch_memsize)
.long 0
VARIABLE (grub_arch_highmemsize)
.long 0
#endif
cont:
#ifdef GRUB_MACHINE_MIPS_YEELOONG
lui $t1, %hi(grub_arch_busclock)
addiu $t1, %lo(grub_arch_busclock)
sw $s2, 0($t1)
sw $s3, 4($t1)
sw $s4, 8($t1)
sw $s5, 12($t1)
#endif
/* Move the modules out of BSS. */
lui $t1, %hi(_start)
addiu $t1, %lo(_start)
lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0)
addu $t2, $t1, $t2
lui $t1, %hi(_end)
addiu $t1, %lo(_end)
addiu $t1, (GRUB_MOD_ALIGN-1)
li $t3, (GRUB_MOD_ALIGN-1)
nor $t3, $t3, $0
and $t1, $t1, $t3
lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0)
/* Backward copy. */
add $t1, $t1, $t3
add $t2, $t2, $t3
addiu $t1, $t1, 0xffff
addiu $t2, $t2, 0xffff
/* $t2 is source. $t1 is destination. $t3 is size. */
modulesmovcont:
lb $t4, 0($t2)
sb $t4, 0($t1)
addiu $t1,$t1,0xffff
addiu $t2,$t2,0xffff
addiu $t3, 0xffff
bne $t3, $0, modulesmovcont
/* Clean BSS. */
lui $t1, %hi(__bss_start)
addiu $t1, %lo(__bss_start)
lui $t2, %hi(_end)
addiu $t2, %lo(_end)
bsscont:
sb $0,0($t1)
addiu $t1,$t1,1
sltu $t3,$t1,$t2
bne $t3, $0, bsscont
li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH
lui $t1, %hi(grub_main)
addiu $t1, %lo(grub_main)
jr $t1

131
kern/mips/yeeloong/init.c Normal file
View file

@ -0,0 +1,131 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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 <grub/kernel.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/time.h>
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/machine/kernel.h>
#include <grub/machine/memory.h>
#include <grub/cpu/kernel.h>
extern void grub_video_sm712_init (void);
extern void grub_video_video_init (void);
extern void grub_video_bitmap_init (void);
extern void grub_font_manager_init (void);
extern void grub_term_gfxterm_init (void);
extern void grub_at_keyboard_init (void);
/* FIXME: use interrupt to count high. */
grub_uint64_t
grub_get_rtc (void)
{
static grub_uint32_t high = 0;
static grub_uint32_t last = 0;
grub_uint32_t low;
asm volatile ("mfc0 %0, $9": "=r" (low));
if (low < last)
high++;
last = low;
return (((grub_uint64_t) high) << 32) | low;
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint64_t,
grub_uint32_t))
{
hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20,
GRUB_MACHINE_MEMORY_AVAILABLE);
hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20,
GRUB_MACHINE_MEMORY_AVAILABLE);
return GRUB_ERR_NONE;
}
static void *
get_modules_end (void)
{
struct grub_module_info *modinfo;
struct grub_module_header *header;
grub_addr_t modbase;
modbase = grub_arch_modules_addr ();
modinfo = (struct grub_module_info *) modbase;
/* Check if there are any modules. */
if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC)
return modinfo;
for (header = (struct grub_module_header *) (modbase + modinfo->offset);
header < (struct grub_module_header *) (modbase + modinfo->size);
header = (struct grub_module_header *) ((char *) header + header->size));
return header;
}
void
grub_machine_init (void)
{
void *modend;
modend = get_modules_end ();
grub_mm_init_region (modend, (grub_arch_memsize << 20)
- (((grub_addr_t) modend) - GRUB_ARCH_LOWMEMVSTART));
/* FIXME: use upper memory as well. */
grub_install_get_time_ms (grub_rtc_get_time_ms);
/* Initialize output terminal (can't be done earlier, as gfxterm
relies on a working heap. */
grub_video_sm712_init ();
grub_video_video_init ();
grub_video_bitmap_init ();
grub_font_manager_init ();
grub_term_gfxterm_init ();
grub_at_keyboard_init ();
}
void
grub_machine_fini (void)
{
}
void
grub_exit (void)
{
while (1);
}
void
grub_halt (void)
{
while (1);
}
void
grub_reboot (void)
{
while (1);
}

View file

@ -1,7 +1,7 @@
/* misc.c - definitions of misc functions */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 1999,2000,2001,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
@ -25,6 +25,9 @@
#include <grub/env.h>
#include <grub/i18n.h>
static int
grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args);
static int
grub_iswordseparator (int c)
{
@ -202,7 +205,7 @@ grub_vprintf (const char *fmt, va_list args)
{
int ret;
ret = grub_vsprintf (0, fmt, args);
ret = grub_vsnprintf_real (0, 0, fmt, args);
grub_refresh ();
return ret;
}
@ -227,6 +230,11 @@ grub_memcmp (const void *s1, const void *s2, grub_size_t n)
#ifndef APPLE_CC
int memcmp (const void *s1, const void *s2, grub_size_t n)
__attribute__ ((alias ("grub_memcmp")));
#else
int memcmp (const void *s1, const void *s2, grub_size_t n)
{
return grub_memcmp (s1, s2, n);
}
#endif
int
@ -512,6 +520,11 @@ grub_memset (void *s, int c, grub_size_t n)
#ifndef APPLE_CC
void *memset (void *s, int c, grub_size_t n)
__attribute__ ((alias ("grub_memset")));
#else
void *memset (void *s, int c, grub_size_t n)
{
return grub_memset (s, c, n);
}
#endif
grub_size_t
@ -626,11 +639,11 @@ grub_lltoa (char *str, int c, unsigned long long n)
return p;
}
int
grub_vsprintf (char *str, const char *fmt, va_list args)
static int
grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args)
{
char c;
int count = 0;
grub_size_t count = 0;
auto void write_char (unsigned char ch);
auto void write_str (const char *s);
auto void write_fill (const char ch, int n);
@ -638,7 +651,10 @@ grub_vsprintf (char *str, const char *fmt, va_list args)
void write_char (unsigned char ch)
{
if (str)
*str++ = ch;
{
if (count < max_len)
*str++ = ch;
}
else
grub_putchar (ch);
@ -867,13 +883,64 @@ grub_vsprintf (char *str, const char *fmt, va_list args)
}
int
grub_sprintf (char *str, const char *fmt, ...)
grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap)
{
grub_size_t ret;
if (!n)
return 0;
n--;
ret = grub_vsnprintf_real (str, n, fmt, ap);
return ret < n ? ret : n;
}
int
grub_snprintf (char *str, grub_size_t n, const char *fmt, ...)
{
va_list ap;
int ret;
va_start (ap, fmt);
ret = grub_vsprintf (str, fmt, ap);
ret = grub_vsnprintf (str, n, fmt, ap);
va_end (ap);
return ret;
}
#define PREALLOC_SIZE 255
char *
grub_xvasprintf (const char *fmt, va_list ap)
{
grub_size_t s, as = PREALLOC_SIZE;
char *ret;
while (1)
{
ret = grub_malloc (as + 1);
if (!ret)
return NULL;
s = grub_vsnprintf_real (ret, as, fmt, ap);
if (s <= as)
return ret;
grub_free (ret);
as = s;
}
}
char *
grub_xasprintf (const char *fmt, ...)
{
va_list ap;
char *ret;
va_start (ap, fmt);
ret = grub_xvasprintf (fmt, ap);
va_end (ap);
return ret;
@ -882,10 +949,10 @@ grub_sprintf (char *str, const char *fmt, ...)
/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
Return the number of characters converted. DEST must be able to hold
at least DESTSIZE characters. If an invalid sequence is found, return -1.
at least DESTSIZE characters.
If SRCEND is not NULL, then *SRCEND is set to the next byte after the
last byte used in SRC. */
grub_ssize_t
grub_size_t
grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend)
@ -907,7 +974,8 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
if ((c & 0xc0) != 0x80)
{
/* invalid */
return -1;
code = '?';
count = 0;
}
else
{
@ -949,7 +1017,11 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
code = c & 0x01;
}
else
return -1;
{
/* invalid */
code = '?';
count = 0;
}
}
if (count == 0)
@ -968,15 +1040,14 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
void
grub_abort (void)
{
if (grub_term_get_current_output ())
grub_printf ("\nAborted.");
#ifndef GRUB_UTIL
if (grub_term_inputs)
#endif
{
grub_printf ("\nAborted.");
if (grub_term_get_current_input ())
{
grub_printf (" Press any key to exit.");
grub_getkey ();
}
grub_printf (" Press any key to exit.");
grub_getkey ();
}
grub_exit ();

View file

@ -1,7 +1,7 @@
/* mm.c - functions for memory manager */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2005,2007,2008,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

View file

@ -145,13 +145,16 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
*argc = 0;
do
{
if (! *rd)
if (! rd || !*rd)
{
if (getline)
getline (&rd, 1);
else break;
}
if (!rd)
break;
for (; *rd; rd++)
{
grub_parser_state_t newstate;

View file

@ -1,7 +1,7 @@
/* dl.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2004,2005,2007,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
@ -106,7 +106,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
Elf_Sword delta = value - (Elf_Word) addr;
if (delta << 6 >> 6 != delta)
return grub_error (GRUB_ERR_BAD_MODULE, "Relocation overflow");
return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
*addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
break;
}
@ -125,7 +125,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"This relocation (%d) is not implemented yet",
"this relocation (%d) is not implemented yet",
ELF_R_TYPE (rel->r_info));
}
}

View file

@ -1,7 +1,7 @@
/* rescue_reader.c - rescue mode reader */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
* Copyright (C) 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
@ -19,20 +19,15 @@
#include <grub/types.h>
#include <grub/reader.h>
#include <grub/parser.h>
#include <grub/misc.h>
#include <grub/term.h>
#include <grub/mm.h>
#define GRUB_RESCUE_BUF_SIZE 256
static char linebuf[GRUB_RESCUE_BUF_SIZE];
static grub_err_t
grub_rescue_init (void)
{
grub_printf ("Entering rescue mode...\n");
return 0;
}
/* Prompt to input a command and read the line. */
static grub_err_t
grub_rescue_read_line (char **line, int cont)
@ -74,15 +69,24 @@ grub_rescue_read_line (char **line, int cont)
return 0;
}
static struct grub_reader grub_rescue_reader =
{
.name = "rescue",
.init = grub_rescue_init,
.read_line = grub_rescue_read_line
};
void
grub_register_rescue_reader (void)
grub_rescue_run (void)
{
grub_reader_register ("rescue", &grub_rescue_reader);
grub_printf ("Entering rescue mode...\n");
while (1)
{
char *line;
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_rescue_read_line (&line, 0);
if (! line || line[0] == '\0')
continue;
grub_parser_get_current ()->parse_line (line, grub_rescue_read_line);
grub_free (line);
}
}

View file

@ -1,7 +1,7 @@
/* dl.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2004,2005,2007,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
@ -98,7 +98,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
case R_SPARC_32: /* 3 V-word32 */
if (value & 0xFFFFFFFF00000000)
return grub_error (GRUB_ERR_BAD_MODULE,
"Address out of 32 bits range");
"address out of 32 bits range");
*addr = value;
break;
case R_SPARC_WDISP30: /* 7 V-disp30 */
@ -106,7 +106,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
(((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000)
!= 0xFFFFFFFF00000000))
return grub_error (GRUB_ERR_BAD_MODULE,
"Displacement out of 30 bits range");
"displacement out of 30 bits range");
*addr = (*addr & 0xC0000000) |
(((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) &
0x3FFFFFFF);
@ -114,7 +114,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
case R_SPARC_HI22: /* 9 V-imm22 */
if (((grub_int32_t) value) & 0xFF00000000)
return grub_error (GRUB_ERR_BAD_MODULE,
"High address out of 22 bits range");
"high address out of 22 bits range");
*addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF);
break;
case R_SPARC_LO10: /* 12 T-simm13 */
@ -131,7 +131,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"This relocation (%d) is not implemented yet",
"this relocation (%d) is not implemented yet",
ELF_R_TYPE (rel->r_info));
}
}

View file

@ -90,10 +90,7 @@ grub_machine_set_prefix (void)
}
prefix = grub_ieee1275_encode_devname (bootpath);
path = grub_malloc (grub_strlen (grub_prefix)
+ grub_strlen (prefix)
+ 2);
grub_sprintf(path, "%s%s", prefix, grub_prefix);
path = grub_xasprintf("%s%s", prefix, grub_prefix);
grub_strcpy (grub_prefix, path);

View file

@ -21,79 +21,33 @@
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/time.h>
/* The amount of lines counted by the pager. */
static int grub_more_lines;
struct grub_term_output *grub_term_outputs_disabled;
struct grub_term_input *grub_term_inputs_disabled;
struct grub_term_output *grub_term_outputs;
struct grub_term_input *grub_term_inputs;
/* If the more pager is active. */
static int grub_more;
/* The current cursor state. */
static int cursor_state = 1;
struct grub_handler_class grub_term_input_class =
{
.name = "terminal_input"
};
struct grub_handler_class grub_term_output_class =
{
.name = "terminal_output"
};
#define grub_cur_term_input grub_term_get_current_input ()
#define grub_cur_term_output grub_term_get_current_output ()
void (*grub_newline_hook) (void) = NULL;
/* Put a Unicode character. */
void
grub_putcode (grub_uint32_t code)
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
{
int height = grub_getwh () & 255;
if (code == '\t' && grub_cur_term_output->getxy)
if (code == '\t' && term->getxy)
{
int n;
n = 8 - ((grub_getxy () >> 8) & 7);
n = 8 - ((term->getxy () >> 8) & 7);
while (n--)
grub_putcode (' ');
grub_putcode (' ', term);
return;
}
(grub_cur_term_output->putchar) (code);
(term->putchar) (code);
if (code == '\n')
{
grub_putcode ('\r');
grub_more_lines++;
if (grub_more && grub_more_lines == height - 1)
{
char key;
int pos = grub_getxy ();
/* Show --MORE-- on the lower left side of the screen. */
grub_gotoxy (1, height - 1);
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf ("--MORE--");
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
key = grub_getkey ();
/* Remove the message. */
grub_gotoxy (1, height - 1);
grub_printf (" ");
grub_gotoxy (pos >> 8, pos & 0xFF);
/* Scroll one lines or an entire page, depending on the key. */
if (key == '\r' || key =='\n')
grub_more_lines--;
else
grub_more_lines = 0;
}
}
(term->putchar) ('\r');
}
/* Put a character. C is one byte of a UTF-8 stream.
@ -104,136 +58,101 @@ grub_putchar (int c)
static grub_size_t size = 0;
static grub_uint8_t buf[6];
grub_uint32_t code;
grub_ssize_t ret;
grub_size_t ret;
buf[size++] = c;
ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
if (ret > 0)
if (ret != 0)
{
struct grub_term_output *term;
size = 0;
grub_putcode (code);
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_putcode (code, term);
if (code == '\n' && grub_newline_hook)
grub_newline_hook ();
}
else if (ret < 0)
{
size = 0;
grub_putcode ('?');
}
}
/* Return the number of columns occupied by the character code CODE. */
grub_ssize_t
grub_getcharwidth (grub_uint32_t code)
{
return (grub_cur_term_output->getcharwidth) (code);
}
int
grub_getkey (void)
{
return (grub_cur_term_input->getkey) ();
grub_term_input_t term;
while (1)
{
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
if (key != -1)
return term->getkey ();
}
grub_cpu_idle ();
}
}
int
grub_checkkey (void)
{
return (grub_cur_term_input->checkkey) ();
grub_term_input_t term;
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
if (key != -1)
return key;
}
return -1;
}
int
grub_getkeystatus (void)
{
if (grub_cur_term_input->getkeystatus)
return (grub_cur_term_input->getkeystatus) ();
else
return 0;
}
int status = 0;
grub_term_input_t term;
grub_uint16_t
grub_getxy (void)
{
return (grub_cur_term_output->getxy) ();
}
FOR_ACTIVE_TERM_INPUTS(term)
{
if (term->getkeystatus)
status |= term->getkeystatus ();
}
grub_uint16_t
grub_getwh (void)
{
return (grub_cur_term_output->getwh) ();
}
void
grub_gotoxy (grub_uint8_t x, grub_uint8_t y)
{
(grub_cur_term_output->gotoxy) (x, y);
return status;
}
void
grub_cls (void)
{
if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
{
grub_putchar ('\n');
grub_refresh ();
}
else
(grub_cur_term_output->cls) ();
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
{
grub_putcode ('\n', term);
grub_term_refresh (term);
}
else
(term->cls) ();
}
}
void
grub_setcolorstate (grub_term_color_state state)
{
if (grub_cur_term_output->setcolorstate)
(grub_cur_term_output->setcolorstate) (state);
}
void
grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
if (grub_cur_term_output->setcolor)
(grub_cur_term_output->setcolor) (normal_color, highlight_color);
}
void
grub_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
if (grub_cur_term_output->getcolor)
(grub_cur_term_output->getcolor) (normal_color, highlight_color);
}
int
grub_setcursor (int on)
{
int ret = cursor_state;
if (grub_cur_term_output->setcursor)
{
(grub_cur_term_output->setcursor) (on);
cursor_state = on;
}
return ret;
}
int
grub_getcursor (void)
{
return cursor_state;
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_setcolorstate (term, state);
}
void
grub_refresh (void)
{
if (grub_cur_term_output->refresh)
(grub_cur_term_output->refresh) ();
}
struct grub_term_output *term;
void
grub_set_more (int onoff)
{
if (onoff == 1)
grub_more++;
else
grub_more--;
grub_more_lines = 0;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_refresh (term);
}

View file

@ -1,7 +1,7 @@
/* dl-x86_64.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2005,2007,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