Merge mainline into legacy_parser

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-09-11 22:39:55 +02:00
commit bd9603071a
55 changed files with 2072 additions and 327 deletions

View file

@ -74,6 +74,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
if COND_i386_pc
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
@ -132,7 +133,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap_scale.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/serial.h
@ -140,11 +140,9 @@ endif
if COND_powerpc_ieee1275
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
endif
if COND_sparc64_ieee1275
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h
endif

View file

@ -404,7 +404,7 @@ module = {
module = {
name = acpi;
x86 = commands/acpi.c;
common = commands/acpi.c;
x86_efi = commands/efi/acpi.c;
i386_pc = commands/i386/pc/acpi.c;
i386_coreboot = commands/i386/pc/acpi.c;
@ -416,6 +416,17 @@ module = {
enable = i386_multiboot;
};
module = {
name = lsacpi;
common = commands/lsacpi.c;
enable = x86_efi;
enable = i386_pc;
enable = i386_coreboot;
enable = i386_multiboot;
};
module = {
name = blocklist;
common = commands/blocklist.c;
@ -493,6 +504,7 @@ module = {
name = halt;
nopc = commands/halt.c;
i386_pc = commands/i386/pc/halt.c;
i386_pc = commands/acpihalt.c;
i386_multiboot = lib/i386/halt.c;
i386_coreboot = lib/i386/halt.c;
i386_qemu = lib/i386/halt.c;
@ -835,6 +847,11 @@ module = {
common = fs/befs_be.c;
};
module = {
name = btrfs;
common = fs/btrfs.c;
};
module = {
name = cpio;
common = fs/cpio.c;
@ -880,6 +897,11 @@ module = {
common = fs/minix.c;
};
module = {
name = minix2;
common = fs/minix2.c;
};
module = {
name = nilfs2;
common = fs/nilfs2.c;
@ -1389,7 +1411,7 @@ module = {
common = commands/legacycfg.c;
common = lib/legacy_parse.c;
enable = i386_pc;
}
};
module = {
name = test_blockarg;
@ -1408,5 +1430,4 @@ module = {
module = {
name = testload;
common = commands/testload.c;
>>>>>>> MERGE-SOURCE
};

View file

@ -324,7 +324,7 @@ setup_common_tables (void)
/* If it's FADT correct DSDT and FACS addresses. */
fadt = (struct grub_acpi_fadt *) cur->addr;
if (grub_memcmp (fadt->hdr.signature, "FACP",
if (grub_memcmp (fadt->hdr.signature, GRUB_ACPI_FADT_SIGNATURE,
sizeof (fadt->hdr.signature)) == 0)
{
fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt);
@ -527,7 +527,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable;
/* Set root header variables to the same values
as FACP by default. */
as FADT by default. */
grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
sizeof (root_oemid));
grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),

View file

@ -0,0 +1,266 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/acpi.h>
#include <grub/misc.h>
#include <grub/cpu/io.h>
static inline grub_uint32_t
decode_length (const grub_uint8_t *ptr, int *numlen)
{
int num_bytes, i;
grub_uint32_t ret;
if (*ptr < 64)
{
if (numlen)
*numlen = 1;
return *ptr;
}
num_bytes = *ptr >> 6;
if (numlen)
*numlen = num_bytes + 1;
ret = *ptr & 0xf;
ptr++;
for (i = 0; i < num_bytes; i++)
{
ret |= *ptr << (8 * i + 4);
ptr++;
}
return ret;
}
static inline grub_uint32_t
skip_name_string (const grub_uint8_t *ptr, const grub_uint8_t *end)
{
const grub_uint8_t *ptr0 = ptr;
while (ptr < end && (*ptr == '^' || *ptr == '\\'))
ptr++;
switch (*ptr)
{
case '.':
ptr++;
ptr += 8;
break;
case '/':
ptr++;
ptr += 1 + (*ptr) * 4;
break;
case 0:
ptr++;
break;
default:
ptr += 4;
break;
}
return ptr - ptr0;
}
static inline grub_uint32_t
skip_data_ref_object (const grub_uint8_t *ptr, const grub_uint8_t *end)
{
grub_dprintf ("acpi", "data type = 0x%x\n", *ptr);
switch (*ptr)
{
case GRUB_ACPI_OPCODE_PACKAGE:
return 1 + decode_length (ptr + 1, 0);
case GRUB_ACPI_OPCODE_ZERO:
case GRUB_ACPI_OPCODE_ONES:
case GRUB_ACPI_OPCODE_ONE:
return 1;
case GRUB_ACPI_OPCODE_BYTE_CONST:
return 2;
case GRUB_ACPI_OPCODE_WORD_CONST:
return 3;
case GRUB_ACPI_OPCODE_DWORD_CONST:
return 5;
default:
if (*ptr == '^' || *ptr == '\\' || *ptr == '_'
|| (*ptr >= 'A' && *ptr <= 'Z'))
return skip_name_string (ptr, end);
grub_printf ("Unknown opcode 0x%x\n", *ptr);
return 0;
}
}
static inline grub_uint32_t
skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end)
{
const grub_uint8_t *ptr0 = ptr;
int add;
grub_dprintf ("acpi", "Extended opcode: 0x%x\n", *ptr);
switch (*ptr)
{
case GRUB_ACPI_EXTOPCODE_MUTEX:
ptr++;
ptr += skip_name_string (ptr, end);
ptr++;
break;
case GRUB_ACPI_EXTOPCODE_OPERATION_REGION:
ptr++;
ptr += skip_name_string (ptr, end);
ptr++;
ptr += add = skip_data_ref_object (ptr, end);
if (!add)
return 0;
ptr += add = skip_data_ref_object (ptr, end);
if (!add)
return 0;
break;
case GRUB_ACPI_EXTOPCODE_FIELD_OP:
ptr++;
ptr += decode_length (ptr, 0);
break;
default:
grub_printf ("Unexpected extended opcode: 0x%x\n", *ptr);
return 0;
}
return ptr - ptr0;
}
static int
get_sleep_type (grub_uint8_t *table, grub_uint8_t *end)
{
grub_uint8_t *ptr, *prev;
int sleep_type = -1;
ptr = table + sizeof (struct grub_acpi_table_header);
while (ptr < end && prev < ptr)
{
int add;
prev = ptr;
grub_dprintf ("acpi", "Opcode %x\n", *ptr);
grub_dprintf ("acpi", "Tell %x\n", ptr - table);
switch (*ptr)
{
case GRUB_ACPI_OPCODE_EXTOP:
ptr++;
ptr += add = skip_ext_op (ptr, end);
if (!add)
return -1;
break;
case GRUB_ACPI_OPCODE_NAME:
ptr++;
if (memcmp (ptr, "_S5_", 4) == 0)
{
int ll;
grub_uint8_t *ptr2 = ptr;
ptr2 += 4;
if (*ptr2 != 0x12)
{
grub_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2);
return -1;
}
ptr2++;
decode_length (ptr2, &ll);
ptr2 += ll;
ptr2++;
switch (*ptr2)
{
case GRUB_ACPI_OPCODE_ZERO:
sleep_type = 0;
break;
case GRUB_ACPI_OPCODE_ONE:
sleep_type = 1;
break;
case GRUB_ACPI_OPCODE_BYTE_CONST:
sleep_type = ptr2[1];
break;
default:
grub_printf ("Unknown data type in _S5: 0x%x\n", *ptr2);
return -1;
}
}
ptr += add = skip_name_string (ptr, end);
if (!add)
return -1;
ptr += add = skip_data_ref_object (ptr, end);
if (!add)
return -1;
break;
case GRUB_ACPI_OPCODE_SCOPE:
case GRUB_ACPI_OPCODE_IF:
case GRUB_ACPI_OPCODE_METHOD:
{
ptr++;
ptr += decode_length (ptr, 0);
break;
}
}
}
grub_dprintf ("acpi", "TYP = %d\n", sleep_type);
return sleep_type;
}
void
grub_acpi_halt (void)
{
struct grub_acpi_rsdp_v20 *rsdp2;
struct grub_acpi_rsdp_v10 *rsdp1;
struct grub_acpi_table_header *rsdt;
grub_uint32_t *entry_ptr;
rsdp2 = grub_acpi_get_rsdpv2 ();
if (rsdp2)
rsdp1 = &(rsdp2->rsdpv1);
else
rsdp1 = grub_acpi_get_rsdpv1 ();
grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1);
if (!rsdp1)
return;
rsdt = (struct grub_acpi_table_header *) rsdp1->rsdt_addr;
for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
+ rsdt->length);
entry_ptr++)
{
if (grub_memcmp ((void *)*entry_ptr, "FACP", 4) == 0)
{
grub_uint32_t port;
struct grub_acpi_fadt *fadt
= ((struct grub_acpi_fadt *) *entry_ptr);
struct grub_acpi_table_header *dsdt
= (struct grub_acpi_table_header *) fadt->dsdt_addr;
int sleep_type = -1;
port = fadt->pm1a;
grub_dprintf ("acpi", "PM1a port=%x\n", port);
if (grub_memcmp (dsdt->signature, "DSDT",
sizeof (dsdt->signature)) != 0)
break;
sleep_type = get_sleep_type ((grub_uint8_t *) dsdt,
(grub_uint8_t *) dsdt + dsdt->length);
if (sleep_type < 0 || sleep_type >= 8)
break;
grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n",
sleep_type, port);
grub_outw (GRUB_ACPI_SLP_EN
| (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), port & 0xffff);
}
}
grub_printf ("ACPI shutdown failed\n");
}

View file

@ -22,6 +22,7 @@
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/machine/int.h>
#include <grub/acpi.h>
static const struct grub_arg_option options[] =
{
@ -100,6 +101,9 @@ grub_cmd_halt (grub_extcmd_context_t ctxt,
{
struct grub_arg_list *state = ctxt->state;
int no_apm = 0;
grub_acpi_halt ();
if (state[0].set)
no_apm = 1;
grub_halt (no_apm);

View file

@ -23,7 +23,6 @@
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/file.h>
#include <grub/gzio.h>
#include <grub/normal.h>
#include <grub/script_sh.h>
#include <grub/i18n.h>
@ -37,7 +36,7 @@ legacy_file (const char *filename)
char *entryname = NULL, *entrysrc = NULL;
grub_menu_t menu;
file = grub_gzfile_open (filename, 1);
file = grub_file_open (filename);
if (! file)
return grub_errno;
@ -80,7 +79,8 @@ legacy_file (const char *filename)
return grub_errno;
}
args[0] = oldname;
grub_normal_add_menu_entry (1, args, entrysrc);
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL,
entrysrc);
}
}
@ -132,7 +132,7 @@ legacy_file (const char *filename)
return grub_errno;
}
args[0] = entryname;
grub_normal_add_menu_entry (1, args, entrysrc);
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc);
}
if (menu && menu->size)
@ -238,9 +238,9 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
if (argc < 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required");
cutargs = grub_malloc (sizeof (cutargsp[0]) * (argc - 1));
cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
cutargc = argc - 1;
grub_memcpy (cutargs + 1, args + 2, sizeof (cutargsp[0]) * (argc - 2));
grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2));
cutargs[0] = args[0];
do

251
grub-core/commands/lsacpi.c Normal file
View file

@ -0,0 +1,251 @@
/* acpi.c - Display acpi tables. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 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/types.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/normal.h>
#include <grub/acpi.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/dl.h>
static void
print_strn (grub_uint8_t *str, grub_size_t len)
{
for (; *str && len; str++, len--)
grub_printf ("%c", *str);
for (len++; len; len--)
grub_printf (" ");
}
#define print_field(x) print_strn(x, sizeof (x))
static void
disp_acpi_table (struct grub_acpi_table_header *t)
{
print_field (t->signature);
grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u OEM=", t->length, t->revision);
print_field (t->oemid);
print_field (t->oemtable);
grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T " ", t->oemrev);
print_field (t->creator_id);
grub_printf (" %08" PRIxGRUB_UINT32_T "\n", t->creator_rev);
}
static void
disp_madt_table (struct grub_acpi_madt *t)
{
struct grub_acpi_madt_entry_header *d;
grub_uint32_t len;
disp_acpi_table (&t->hdr);
grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T " Flags=%08"
PRIxGRUB_UINT32_T "\n",
t->lapic_addr, t->flags);
len = t->hdr.length - sizeof (struct grub_acpi_madt);
d = t->entries;
for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len))
{
grub_printf (" type=%x l=%u ", d->type, d->len);
switch (d->type)
{
case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE:
{
struct grub_acpi_madt_entry_interrupt_override *dt = (void *) d;
grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n",
dt->bus, dt->source, dt->global_sys_interrupt,
dt->flags);
}
break;
case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC:
{
struct grub_acpi_madt_entry_sapic *dt = (void *) d;
grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
"\n",
dt->id, dt->global_sys_interrupt_base,
dt->addr);
}
break;
case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC:
{
struct grub_acpi_madt_entry_lsapic *dt = (void *) d;
grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
dt->cpu_id, dt->id, dt->eid, dt->flags);
if (dt->flags & GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED)
grub_printf (" Enabled\n");
else
grub_printf (" Disabled\n");
if (d->len > sizeof (struct grub_acpi_madt_entry_sapic))
grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid,
dt->cpu_uid_str);
}
break;
case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE:
{
struct grub_acpi_madt_entry_platform_int_source *dt = (void *) d;
static const char * const platint_type[] =
{"Nul", "PMI", "INIT", "CPEI"};
grub_printf ("Platform INT flags=%04x type=%02x (%s)"
" ID=%02x EID=%02x\n",
dt->flags, dt->inttype,
(dt->inttype < ARRAY_SIZE (platint_type))
? platint_type[dt->inttype] : "??", dt->cpu_id,
dt->cpu_eid);
grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
dt->sapic_vector, dt->global_sys_int, dt->src_flags);
}
break;
default:
grub_printf (" ??\n");
}
}
}
static void
disp_acpi_xsdt_table (struct grub_acpi_table_header *t)
{
grub_uint32_t len;
grub_uint64_t *desc;
disp_acpi_table (t);
len = t->length - sizeof (*t);
desc = (grub_uint64_t *) (t + 1);
for (; len > 0; desc++, len -= sizeof (*desc))
{
if (sizeof (grub_addr_t) == 4 && *desc >= (1ULL << 32))
{
grub_printf ("Unreachable table\n");
continue;
}
t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
if (t == NULL)
continue;
if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
sizeof (t->signature)) == 0)
disp_madt_table ((struct grub_acpi_madt *) t);
else
disp_acpi_table (t);
}
}
static void
disp_acpi_rsdt_table (struct grub_acpi_table_header *t)
{
grub_uint32_t len;
grub_uint32_t *desc;
disp_acpi_table (t);
len = t->length - sizeof (*t);
desc = (grub_uint32_t *) (t + 1);
for (; len > 0; desc++, len -= sizeof (*desc))
{
t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
if (t == NULL)
continue;
if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
sizeof (t->signature)) == 0)
disp_madt_table ((struct grub_acpi_madt *) t);
else
disp_acpi_table (t);
}
}
static void
disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp)
{
print_field (rsdp->signature);
grub_printf ("chksum:%02x, OEM-ID: ", rsdp->checksum);
print_field (rsdp->oemid);
grub_printf ("rev=%d\n", rsdp->revision);
grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr);
}
static void
disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp)
{
disp_acpi_rsdpv1 (&rsdp->rsdpv1);
grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length,
rsdp->xsdt_addr);
}
static const struct grub_arg_option options[] = {
{"v1", '1', 0, N_("Show v1 tables only."), 0, ARG_TYPE_NONE},
{"v2", '2', 0, N_("Show v2 and v3 tablesv only."), 0, ARG_TYPE_NONE}
};
static grub_err_t
grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
if (!ctxt->state[1].set)
{
struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 ();
if (!rsdp1)
grub_printf ("No RSDPv1\n");
else
{
grub_printf ("RSDPv1 signature:");
disp_acpi_rsdpv1 (rsdp1);
disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr);
}
}
if (!ctxt->state[0].set)
{
struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
if (!rsdp2)
grub_printf ("No RSDPv2\n");
else
{
if (sizeof (grub_addr_t) == 4 && rsdp2->xsdt_addr >= (1ULL << 32))
grub_printf ("Unreachable RSDPv2\n");
else
{
grub_printf ("RSDPv2 signature:");
disp_acpi_rsdpv2 (rsdp2);
disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr);
grub_printf ("\n");
}
}
}
return GRUB_ERR_NONE;
}
static grub_extcmd_t cmd;
GRUB_MOD_INIT(lsapi)
{
cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, GRUB_COMMAND_FLAG_BOTH,
N_("[-1|-2]"),
N_("Show ACPI information."), options);
}
GRUB_MOD_FINI(lsacpi)
{
grub_unregister_extcmd (cmd);
}

View file

@ -52,10 +52,10 @@ static struct
/* Add a menu entry to the current menu context (as given by the environment
variable data slot `menu'). As the configuration file is read, the script
parser calls this when a menu entry is to be created. */
static grub_err_t
append_menu_entry (int argc, const char **args, char **classes,
const char *users, const char *hotkey,
const char *prefix, const char *sourcecode)
grub_err_t
grub_normal_add_menu_entry (int argc, const char **args, char **classes,
const char *users, const char *hotkey,
const char *prefix, const char *sourcecode)
{
unsigned i;
int menu_hotkey = 0;
@ -243,9 +243,10 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition");
if (! ctxt->script)
return append_menu_entry (argc, (const char **) args,
ctxt->state[0].args, ctxt->state[1].arg,
ctxt->state[2].arg, 0, ctxt->state[3].arg);
return grub_normal_add_menu_entry (argc, (const char **) args,
ctxt->state[0].args, ctxt->state[1].arg,
ctxt->state[2].arg, 0,
ctxt->state[3].arg);
src = args[argc - 1];
args[argc - 1] = NULL;
@ -258,9 +259,9 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
if (! prefix)
return grub_errno;
r = append_menu_entry (argc - 1, (const char **) args,
ctxt->state[0].args, ctxt->state[1].arg,
ctxt->state[2].arg, prefix, src + 1);
r = grub_normal_add_menu_entry (argc - 1, (const char **) args,
ctxt->state[0].args, ctxt->state[1].arg,
ctxt->state[2].arg, prefix, src + 1);
src[len - 1] = ch;
args[argc - 1] = src;

View file

@ -488,7 +488,7 @@ wildcard_expand (const char *s, char ***strs)
for (i = 0; paths && paths[i]; i++)
grub_free (paths[i]);
grub_free (paths[i]);
grub_free (paths);
regfree (&regexp);
return grub_errno;
}

View file

@ -248,6 +248,9 @@ grub_biosdisk_get_drive (const char *name)
{
unsigned long drive;
if (name[0] == 'c' && name[1] == 'd' && name[2] == 0 && cd_drive)
return cd_drive;
if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd')
goto fail;
@ -270,6 +273,9 @@ grub_biosdisk_call_hook (int (*hook) (const char *name), int drive)
{
char name[10];
if (cd_drive && drive == cd_drive)
return hook ("cd");
grub_snprintf (name, sizeof (name),
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
return hook (name);

View file

@ -274,6 +274,10 @@ grub_lvm_scan_device (const char *name)
struct grub_lvm_vg *vg;
struct grub_lvm_pv *pv;
#ifdef GRUB_UTIL
grub_util_info ("scanning %s for LVM", name);
#endif
disk = grub_disk_open (name);
if (!disk)
return 0;
@ -294,7 +298,12 @@ grub_lvm_scan_device (const char *name)
/* Return if we didn't find a label. */
if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
goto fail;
{
#ifdef GRUB_UTIL
grub_util_info ("no LVM signature found\n");
#endif
goto fail;
}
pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
@ -318,6 +327,9 @@ grub_lvm_scan_device (const char *name)
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"we don't support multiple LVM data areas");
#ifdef GRUB_UTIL
grub_util_info ("we don't support multiple LVM data areas\n");
#endif
goto fail;
}
@ -344,6 +356,9 @@ grub_lvm_scan_device (const char *name)
{
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unknown LVM metadata header");
#ifdef GRUB_UTIL
grub_util_info ("unknown LVM metadata header\n");
#endif
goto fail2;
}
@ -364,7 +379,12 @@ grub_lvm_scan_device (const char *name)
q++;
if (q == metadatabuf + mda_size)
goto fail2;
{
#ifdef GRUB_UTIL
grub_util_info ("error parsing metadata\n");
#endif
goto fail2;
}
vgname_len = q - p;
vgname = grub_malloc (vgname_len + 1);
@ -376,7 +396,12 @@ grub_lvm_scan_device (const char *name)
p = grub_strstr (q, "id = \"");
if (p == NULL)
goto fail3;
{
#ifdef GRUB_UTIL
grub_util_info ("couldn't find ID\n");
#endif
goto fail3;
}
p += sizeof ("id = \"") - 1;
grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN);
vg_id[GRUB_LVM_ID_STRLEN] = '\0';
@ -399,7 +424,12 @@ grub_lvm_scan_device (const char *name)
vg->extent_size = grub_lvm_getvalue (&p, "extent_size = ");
if (p == NULL)
goto fail4;
{
#ifdef GRUB_UTIL
grub_util_info ("unknown extent size\n");
#endif
goto fail4;
}
vg->lvs = NULL;
vg->pvs = NULL;
@ -439,11 +469,21 @@ grub_lvm_scan_device (const char *name)
pv->start = grub_lvm_getvalue (&p, "pe_start = ");
if (p == NULL)
goto pvs_fail;
{
#ifdef GRUB_UTIL
grub_util_info ("unknown pe_start\n");
#endif
goto pvs_fail;
}
p = grub_strchr (p, '}');
if (p == NULL)
goto pvs_fail;
{
#ifdef GRUB_UTIL
grub_util_info ("error parsing pe_start\n");
#endif
goto pvs_fail;
}
p++;
pv->disk = NULL;
@ -500,7 +540,12 @@ grub_lvm_scan_device (const char *name)
lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
if (p == NULL)
goto lvs_fail;
{
#ifdef GRUB_UTIL
grub_util_info ("unknown segment_count\n");
#endif
goto lvs_fail;
}
lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
seg = lv->segments;
@ -510,14 +555,29 @@ grub_lvm_scan_device (const char *name)
p = grub_strstr (p, "segment");
if (p == NULL)
goto lvs_segment_fail;
{
#ifdef GRUB_UTIL
grub_util_info ("unknown segment\n");
#endif
goto lvs_segment_fail;
}
seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
if (p == NULL)
goto lvs_segment_fail;
{
#ifdef GRUB_UTIL
grub_util_info ("unknown start_extent\n");
#endif
goto lvs_segment_fail;
}
seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
if (p == NULL)
goto lvs_segment_fail;
{
#ifdef GRUB_UTIL
grub_util_info ("unknown extent_count\n");
#endif
goto lvs_segment_fail;
}
if (grub_lvm_checkvalue (&p, "type = ", "snapshot"))
{
@ -528,7 +588,12 @@ grub_lvm_scan_device (const char *name)
seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
if (p == NULL)
goto lvs_segment_fail;
{
#ifdef GRUB_UTIL
grub_util_info ("unknown stripe_count\n");
#endif
goto lvs_segment_fail;
}
lv->size += seg->extent_count * vg->extent_size;
@ -541,7 +606,12 @@ grub_lvm_scan_device (const char *name)
p = grub_strstr (p, "stripes = [");
if (p == NULL)
goto lvs_segment_fail2;
{
#ifdef GRUB_UTIL
grub_util_info ("unknown stripes\n");
#endif
goto lvs_segment_fail2;
}
p += sizeof("stripes = [") - 1;
for (j = 0; j < seg->stripe_count; j++)

132
grub-core/fs/btrfs.c Normal file
View file

@ -0,0 +1,132 @@
/* btrfs.c - B-tree file system. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/err.h>
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/dl.h>
#include <grub/types.h>
#define BTRFS_SIGNATURE "_BHRfS_M"
struct btrfs_superblock
{
grub_uint8_t dummy1[32];
grub_uint16_t uuid[8];
grub_uint8_t dummy2[16];
grub_uint8_t signature[sizeof (BTRFS_SIGNATURE) - 1];
} __attribute__ ((packed));
struct grub_btrfs_data
{
struct btrfs_superblock sblock;
};
static struct grub_btrfs_data *
grub_btrfs_mount (grub_disk_t disk)
{
struct grub_btrfs_data *data = grub_malloc (sizeof (*data));
if (! data)
return NULL;
if (grub_disk_read (disk, 128, 0, sizeof (data->sblock),
&data->sblock) != GRUB_ERR_NONE)
goto fail;
if (grub_strncmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1))
{
grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem");
goto fail;
}
return data;
fail:
grub_free (data);
return NULL;
}
static grub_err_t
grub_btrfs_open (struct grub_file *file __attribute__ ((unused)),
const char *name __attribute__ ((unused)))
{
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "only detection is supported for Btrfs");
}
static grub_err_t
grub_btrfs_dir (grub_device_t device,
const char *path __attribute__ ((unused)),
int (*hook) (const char *filename,
const struct grub_dirhook_info *info)
__attribute__ ((unused)))
{
struct grub_btrfs_data *data = grub_btrfs_mount (device->disk);
if (grub_errno)
return grub_errno;
grub_free (data);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_btrfs_uuid (grub_device_t device, char **uuid)
{
struct grub_btrfs_data *data;
*uuid = NULL;
data = grub_btrfs_mount (device->disk);
if (! data)
return grub_errno;
*uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
grub_be_to_cpu16 (data->sblock.uuid[0]),
grub_be_to_cpu16 (data->sblock.uuid[1]),
grub_be_to_cpu16 (data->sblock.uuid[2]),
grub_be_to_cpu16 (data->sblock.uuid[3]),
grub_be_to_cpu16 (data->sblock.uuid[4]),
grub_be_to_cpu16 (data->sblock.uuid[5]),
grub_be_to_cpu16 (data->sblock.uuid[6]),
grub_be_to_cpu16 (data->sblock.uuid[7]));
grub_free (data);
return grub_errno;
}
static struct grub_fs grub_btrfs_fs =
{
.name = "btrfs",
.dir = grub_btrfs_dir,
.open = grub_btrfs_open,
.uuid = grub_btrfs_uuid,
};
GRUB_MOD_INIT(btrfs)
{
grub_fs_register (&grub_btrfs_fs);
}
GRUB_MOD_FINI(btrfs)
{
grub_fs_unregister (&grub_btrfs_fs);
}

View file

@ -25,10 +25,13 @@
#include <grub/dl.h>
#include <grub/types.h>
#ifdef MODE_MINIX2
#define GRUB_MINIX_MAGIC 0x2468
#define GRUB_MINIX_MAGIC_30 0x2478
#else
#define GRUB_MINIX_MAGIC 0x137F
#define GRUB_MINIX2_MAGIC 0x2468
#define GRUB_MINIX_MAGIC_30 0x138F
#define GRUB_MINIX2_MAGIC_30 0x2478
#endif
#define GRUB_MINIX_BSIZE 1024U
#define GRUB_MINIX_LOG2_BSIZE 1
#define GRUB_MINIX_ROOT_INODE 1
@ -38,20 +41,25 @@
#define GRUB_MINIX_IFDIR 0040000U
#define GRUB_MINIX_IFLNK 0120000U
#define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \
data->inode. field : data->inode2. field)
#define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ? \
grub_le_to_cpu##bits1 (data->inode.field) : \
grub_le_to_cpu##bits2 (data->inode2.field))
#define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32)
#define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16)
#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN \
(data,dir_zones[blk],16,32)
#define GRUB_MINIX_INODE_INDIR_ZONE(data) \
GRUB_MINIX_INODE_ENDIAN (data,indir_zone,16,32)
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) \
GRUB_MINIX_INODE_ENDIAN (data,double_indir_zone,16,32)
#define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4)
#ifdef MODE_MINIX2
typedef grub_uint32_t grub_minix_uintn_t;
#define grub_minix_le_to_cpu_n grub_le_to_cpu32
#else
typedef grub_uint16_t grub_minix_uintn_t;
#define grub_minix_le_to_cpu_n grub_le_to_cpu16
#endif
#define GRUB_MINIX_INODE_BLKSZ(data) sizeof (grub_minix_uintn_t)
#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size))
#define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode))
#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_le_to_cpu_n \
(data->inode.dir_zones[blk]))
#define GRUB_MINIX_INODE_INDIR_ZONE(data) (grub_minix_le_to_cpu_n \
(data->inode.indir_zone))
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_le_to_cpu_n \
(data->inode.double_indir_zone))
#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \
+ grub_le_to_cpu16 (sblock->log2_zone_size))
#define GRUB_MINIX_ZONESZ (GRUB_MINIX_BSIZE \
@ -69,6 +77,7 @@ struct grub_minix_sblock
grub_uint16_t magic;
};
#ifndef MODE_MINIX2
struct grub_minix_inode
{
grub_uint16_t mode;
@ -82,7 +91,9 @@ struct grub_minix_inode
grub_uint16_t double_indir_zone;
};
struct grub_minix2_inode
#else
struct grub_minix_inode
{
grub_uint16_t mode;
grub_uint16_t nlinks;
@ -99,16 +110,16 @@ struct grub_minix2_inode
};
#endif
/* Information about a "mounted" minix filesystem. */
struct grub_minix_data
{
struct grub_minix_sblock sblock;
struct grub_minix_inode inode;
struct grub_minix2_inode inode2;
int ino;
int linknest;
grub_disk_t disk;
int version;
int filename_size;
};
@ -128,24 +139,12 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
/* Read the block pointer in ZONE, on the offset NUM. */
int grub_get_indir (int zone, int num)
{
if (data->version == 1)
{
grub_uint16_t indir16;
grub_disk_read (data->disk,
zone << GRUB_MINIX_LOG2_ZONESZ,
sizeof (grub_uint16_t) * num,
sizeof (grub_uint16_t), (char *) &indir16);
return grub_le_to_cpu16 (indir16);
}
else
{
grub_uint32_t indir32;
grub_disk_read (data->disk,
zone << GRUB_MINIX_LOG2_ZONESZ,
sizeof (grub_uint32_t) * num,
sizeof (grub_uint32_t), (char *) &indir32);
return grub_le_to_cpu32 (indir32);
}
grub_minix_uintn_t indirn;
grub_disk_read (data->disk,
zone << GRUB_MINIX_LOG2_ZONESZ,
sizeof (grub_minix_uintn_t) * num,
sizeof (grub_minix_uintn_t), (char *) &indirn);
return grub_minix_le_to_cpu_n (indirn);
}
/* Direct block. */
@ -259,27 +258,13 @@ grub_minix_read_inode (struct grub_minix_data *data, int ino)
+ grub_le_to_cpu16 (sblock->zone_bmap_size))
<< GRUB_MINIX_LOG2_BSIZE);
if (data->version == 1)
{
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
/ sizeof (struct grub_minix_inode))
* sizeof (struct grub_minix_inode));
grub_disk_read (data->disk, block, offs,
sizeof (struct grub_minix_inode), &data->inode);
}
else
{
block += ino / (GRUB_DISK_SECTOR_SIZE
/ sizeof (struct grub_minix2_inode));
int offs = (ino
% (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix2_inode))
* sizeof (struct grub_minix2_inode));
grub_disk_read (data->disk, block, offs,
sizeof (struct grub_minix2_inode),&data->inode2);
}
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
/ sizeof (struct grub_minix_inode))
* sizeof (struct grub_minix_inode));
grub_disk_read (data->disk, block, offs,
sizeof (struct grub_minix_inode), &data->inode);
return GRUB_ERR_NONE;
}
@ -424,25 +409,9 @@ grub_minix_mount (grub_disk_t disk)
goto fail;
if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC)
{
data->version = 1;
data->filename_size = 14;
}
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC)
{
data->version = 2;
data->filename_size = 14;
}
data->filename_size = 14;
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30)
{
data->version = 1;
data->filename_size = 30;
}
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC_30)
{
data->version = 2;
data->filename_size = 30;
}
data->filename_size = 30;
else
goto fail;
@ -453,7 +422,11 @@ grub_minix_mount (grub_disk_t disk)
fail:
grub_free (data);
#ifdef MODE_MINIX2
grub_error (GRUB_ERR_BAD_FS, "not a minix2 filesystem");
#else
grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem");
#endif
return 0;
}
@ -583,32 +556,36 @@ grub_minix_close (grub_file_t file)
}
static grub_err_t
grub_minix_label (grub_device_t device __attribute ((unused)),
char **label __attribute ((unused)))
{
return GRUB_ERR_NONE;
}
static struct grub_fs grub_minix_fs =
{
#ifdef MODE_MINIX2
.name = "minix2",
#else
.name = "minix",
#endif
.dir = grub_minix_dir,
.open = grub_minix_open,
.read = grub_minix_read,
.close = grub_minix_close,
.label = grub_minix_label,
.next = 0
};
#ifdef MODE_MINIX2
GRUB_MOD_INIT(minix2)
#else
GRUB_MOD_INIT(minix)
#endif
{
grub_fs_register (&grub_minix_fs);
my_mod = mod;
}
#ifdef MODE_MINIX2
GRUB_MOD_FINI(minix2)
#else
GRUB_MOD_FINI(minix)
#endif
{
grub_fs_unregister (&grub_minix_fs);
}

2
grub-core/fs/minix2.c Normal file
View file

@ -0,0 +1,2 @@
#define MODE_MINIX2 1
#include "minix.c"

View file

@ -66,10 +66,33 @@ grub_efi_set_prefix (void)
path = grub_strdup (pptr);
}
if (!device || !path)
if ((!device || device[0] == ',' || !device[0]) || !path)
image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (image && !device)
device = grub_efidisk_get_device_name (image->device_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)
{

View file

@ -7,7 +7,20 @@
#elif defined(__sparc__)
#include "../sparc64/cache.S"
#elif defined(__mips__)
#include "../mips/cache.S"
/* On MIPS we must go through standard functions. */
#include <grub/symbol.h>
FUNCTION (grub_cpu_flush_cache)
FUNCTION (grub_arch_sync_caches)
.set nomacro
.set noreorder
lui $t0, %hi(_flush_cache)
addui $t0, $t0, %lo(_flush_cache)
move $a3, $zero
jr $t0
nop
.set reorder
.set macro
#elif defined(__powerpc__)
#include "../powerpc/cache.S"
#else

View file

@ -22,6 +22,7 @@
#include <grub/kernel.h>
#include <grub/misc.h>
#include <grub/emu/misc.h>
#include <grub/disk.h>
void
grub_register_exported_symbols (void)
@ -48,3 +49,21 @@ grub_emu_init (void)
{
grub_no_autoload = 1;
}
#ifdef GRUB_LINKER_HAVE_INIT
void
grub_arch_dl_init_linker (void)
{
}
#endif
void
grub_emu_post_init (void)
{
grub_lvm_fini ();
grub_mdraid_fini ();
grub_raid_fini ();
grub_raid_init ();
grub_mdraid_init ();
grub_lvm_init ();
}

View file

@ -38,3 +38,8 @@ grub_emu_init (void)
{
return;
}
void
grub_emu_post_init (void)
{
}

View file

@ -197,6 +197,8 @@ main (int argc, char *argv[])
grub_init_all ();
grub_emu_post_init ();
/* Make sure that there is a root device. */
if (! root_dev)
{

View file

@ -61,6 +61,15 @@
# include <sys/mount.h>
#endif
#ifdef HAVE_SYS_MNTTAB_H
# include <stdio.h> /* Needed by sys/mnttab.h. */
# include <sys/mnttab.h>
#endif
#ifdef HAVE_SYS_MKDEV_H
# include <sys/mkdev.h> /* makedev */
#endif
int verbosity;
void
@ -282,18 +291,52 @@ grub_get_libzfs_handle (void)
void
grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs)
{
struct statfs mnt;
char *slash;
*poolname = *poolfs = NULL;
if (statfs (dir, &mnt) != 0)
return;
#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) && defined(HAVE_STRUCT_STATFS_F_MNTFROMNAME)
/* FreeBSD and GNU/kFreeBSD. */
{
struct statfs mnt;
if (strcmp (mnt.f_fstypename, "zfs") != 0)
return;
if (statfs (dir, &mnt) != 0)
return;
*poolname = xstrdup (mnt.f_mntfromname);
if (strcmp (mnt.f_fstypename, "zfs") != 0)
return;
*poolname = xstrdup (mnt.f_mntfromname);
}
#elif defined(HAVE_GETEXTMNTENT)
/* Solaris. */
{
struct stat st;
struct extmnttab mnt;
if (stat (dir, &st) != 0)
return;
FILE *mnttab = fopen ("/etc/mnttab", "r");
if (! mnttab)
return;
while (getextmntent (mnttab, &mnt, sizeof (mnt)) == 0)
{
if (makedev (mnt.mnt_major, mnt.mnt_minor) == st.st_dev
&& !strcmp (mnt.mnt_fstype, "zfs"))
{
*poolname = xstrdup (mnt.mnt_special);
break;
}
}
fclose (mnttab);
}
#endif
if (! *poolname)
return;
slash = strchr (*poolname, '/');
if (slash)

View file

@ -138,11 +138,16 @@ grub_ieee1275_find_options (void)
*/
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY);
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF);
}
if (is_qemu)
/* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM);
{
/* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM);
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF);
}
if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom))
{

View file

@ -296,6 +296,7 @@ adjust_file (const char *in, grub_size_t len)
*outptr++ = *ptr;
}
*outptr = 0;
return ret;
}

View file

@ -547,13 +547,32 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
grub_script_function_t func = 0;
char errnobuf[18];
char *cmdname;
int argc;
char **args;
int invert;
struct grub_script_argv argv = { 0, 0, 0 };
/* Lookup the command. */
if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0])
return grub_errno;
invert = 0;
argc = argv.argc - 1;
args = argv.args + 1;
cmdname = argv.args[0];
if (grub_strcmp (cmdname, "!") == 0)
{
if (argv.argc < 2 || ! argv.args[1])
{
grub_script_argv_free (&argv);
return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments");
}
invert = 1;
argc = argv.argc - 2;
args = argv.args + 2;
cmdname = argv.args[1];
}
grubcmd = grub_command_find (cmdname);
if (! grubcmd)
{
@ -594,13 +613,25 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
{
if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) &&
(grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD))
ret = grub_extcmd_dispatcher (grubcmd, argv.argc - 1, argv.args + 1,
argv.script);
ret = grub_extcmd_dispatcher (grubcmd, argc, args, argv.script);
else
ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1);
ret = (grubcmd->func) (grubcmd, argc, args);
}
else
ret = grub_script_function_call (func, argv.argc - 1, argv.args + 1);
ret = grub_script_function_call (func, argc, args);
if (invert)
{
if (ret == GRUB_ERR_TEST_FAILURE)
grub_errno = ret = GRUB_ERR_NONE;
else if (ret == GRUB_ERR_NONE)
ret = grub_error (GRUB_ERR_TEST_FAILURE, "false");
else
{
grub_print_error ();
ret = GRUB_ERR_NONE;
}
}
/* Free arguments. */
grub_script_argv_free (&argv);

View file

@ -155,7 +155,6 @@ MULTILINE {WORD}?((\"{DQCHR}*)|(\'{SQCHR}*)|(\\\n))
">" { RECORD; return GRUB_PARSER_TOKEN_GT; }
/* Reserved words */
"!" { RECORD; return GRUB_PARSER_TOKEN_NOT; }
"{" { RECORD; return GRUB_PARSER_TOKEN_LBR; }
"}" { RECORD; return GRUB_PARSER_TOKEN_RBR; }
"[[" { RECORD; return GRUB_PARSER_TOKEN_RSQBR2; }

View file

@ -117,9 +117,14 @@ grub_ofconsole_getwh (struct grub_term_output *term __attribute__ ((unused)))
}
static void
grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)),
grub_ofconsole_setcursor (struct grub_term_output *term,
int on)
{
grub_terminfo_setcursor (term, on);
if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF))
return;
/* Understood by the Open Firmware flavour in OLPC. */
if (on)
grub_ieee1275_interpret ("cursor-on", 0);

View file

@ -32,6 +32,8 @@
static unsigned old_width, old_height;
static int restore_needed;
static char *display;
static grub_ieee1275_ihandle_t stdout_ihandle;
static int have_setcolors = 0;
static struct
{
@ -72,7 +74,17 @@ find_display (void)
static grub_err_t
grub_video_ieee1275_init (void)
{
grub_ssize_t actual;
grub_memset (&framebuffer, 0, sizeof(framebuffer));
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS)
&& !grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
"stdout", &stdout_ihandle,
sizeof (stdout_ihandle), &actual)
&& actual == sizeof (stdout_ihandle))
have_setcolors = 1;
return grub_video_fb_init ();
}
@ -169,9 +181,6 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height,
/* For some reason sparc64 uses 32-bit pointer too. */
framebuffer.ptr = (void *) (grub_addr_t) address;
grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
grub_video_fbstd_colors);
grub_dprintf ("video", "IEEE1275: initialising FB @ %p %dx%dx%d\n",
framebuffer.ptr, framebuffer.mode_info.width,
framebuffer.mode_info.height, framebuffer.mode_info.bpp);
@ -192,15 +201,10 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height,
grub_dprintf ("video", "IEEE1275: Couldn't set FB target\n");
return err;
}
err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
grub_video_fbstd_colors);
if (err)
grub_dprintf ("video", "IEEE1275: Couldn't set palette\n");
else
grub_dprintf ("video", "IEEE1275: Success\n");
grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
grub_video_fbstd_colors);
return err;
}
@ -243,9 +247,17 @@ grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
if (err)
return err;
grub_video_fb_get_palette (0, 256, fb_palette_data);
grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data), fb_palette_data);
/* TODO. */
/* Set colors. */
if (have_setcolors)
{
unsigned col;
for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++)
grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r,
fb_palette_data[col].g,
fb_palette_data[col].b);
}
return GRUB_ERR_NONE;
}