merge mainline into ahci

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-05-18 12:36:26 +02:00
commit 548937c6d6
70 changed files with 2735 additions and 287 deletions

View file

@ -131,6 +131,19 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
endif
if COND_mips
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h
endif
if COND_mips_arc
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arc/arc.h
endif
if COND_mips_qemu_mips
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
endif
if COND_mips_loongson
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
@ -151,6 +164,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
endif
if COND_mips_qemu_mips
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
endif
if COND_powerpc_ieee1275
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
@ -311,6 +329,7 @@ CLEANFILES += config.log syminfo.lst moddep.lst
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT)
TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
platform_DATA += $(MOD_FILES)
platform_DATA += modinfo.sh
CLEANFILES += $(MOD_FILES)
if COND_ENABLE_EFIEMU

View file

@ -12,6 +12,12 @@ script = {
common = genmod.sh.in;
};
script = {
installdir = noinst;
name = modinfo.sh;
common = modinfo.sh.in;
};
kernel = {
name = kernel;
@ -41,6 +47,8 @@ kernel = {
mips_loongson_ldflags = '-Wl,-Ttext,0x80200000';
powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
mips_arc_ldflags = '-Wl,-Ttext,0x8bd00000';
mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000';
mips_loongson_cppflags = '-DUSE_ASCII_FAILBACK';
i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
@ -54,7 +62,7 @@ kernel = {
i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
i386_coreboot_startup = kern/i386/coreboot/startup.S;
i386_multiboot_startup = kern/i386/coreboot/startup.S;
mips_loongson_startup = kern/mips/startup.S;
mips_startup = kern/mips/startup.S;
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
@ -86,7 +94,7 @@ kernel = {
i386_qemu = kern/generic/rtc_get_time_ms.c;
i386_coreboot = kern/generic/rtc_get_time_ms.c;
i386_multiboot = kern/generic/rtc_get_time_ms.c;
mips_loongson = kern/generic/rtc_get_time_ms.c;
mips = kern/generic/rtc_get_time_ms.c;
ieee1275 = disk/ieee1275/ofdisk.c;
ieee1275 = kern/ieee1275/cmain.c;
@ -147,13 +155,22 @@ kernel = {
i386_ieee1275 = kern/ieee1275/init.c;
mips = kern/mips/cache.S;
mips = kern/mips/dl.c;
mips = kern/mips/init.c;
mips_qemu_mips = kern/mips/qemu_mips/init.c;
mips_qemu_mips = term/ns8250.c;
mips_qemu_mips = term/serial.c;
mips_arc = kern/mips/arc/init.c;
mips_arc = term/arc/console.c;
mips_arc = disk/arc/arcdisk.c;
mips_loongson = term/ns8250.c;
mips_loongson = bus/bonito.c;
mips_loongson = bus/cs5536.c;
mips_loongson = bus/pci.c;
mips_loongson = kern/mips/cache.S;
mips_loongson = kern/mips/dl.c;
mips_loongson = kern/mips/init.c;
mips_loongson = kern/mips/loongson/init.c;
mips_loongson = term/at_keyboard.c;
mips_loongson = term/serial.c;
@ -308,12 +325,12 @@ image = {
common = lib/xzembed/xz_dec_lzma2.c;
common = lib/xzembed/xz_dec_stream.c;
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed';
mips_cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000';
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1';
objcopyflags = '-O binary';
ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000';
ldadd = '-lgcc';
cflags = '-static-libgcc';
enable = mips;
@ -324,10 +341,12 @@ image = {
mips = boot/mips/startup_raw.S;
common = boot/decompressor/none.c;
mips_cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000';
cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1';
objcopyflags = '-O binary';
ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000';
ldadd = '-lgcc';
cflags = '-static-libgcc';
enable = mips;
@ -430,6 +449,13 @@ module = {
emu_condition = COND_GRUB_EMU_PCI;
};
module = {
name = lsdev;
common = commands/arc/lsdev.c;
enable = mips_arc;
};
library = {
name = libgnulib.a;
common = gnulib/regex.c;
@ -836,6 +862,7 @@ module = {
name = ata;
common = disk/ata.c;
enable = pci;
enable = mips_qemu_mips;
};
module = {
@ -848,6 +875,7 @@ module = {
name = pata;
common = disk/pata.c;
enable = pci;
enable = mips_qemu_mips;
};
module = {
@ -1163,6 +1191,7 @@ module = {
efi = lib/efi/datetime.c;
sparc64_ieee1275 = lib/ieee1275/datetime.c;
powerpc_ieee1275 = lib/ieee1275/datetime.c;
mips_arc = lib/arc/datetime.c;
enable = noemu;
};
@ -1207,6 +1236,12 @@ module = {
enable = i386_pc;
};
module = {
name = freedos;
i386_pc = loader/i386/pc/freedos.c;
enable = i386_pc;
};
module = {
name = multiboot2;
cppflags = "-DGRUB_USE_MULTIBOOT2";
@ -1276,11 +1311,11 @@ module = {
efi = mmap/efi/mmap.c;
mips_loongson = mmap/mips/loongson/uppermem.c;
mips = mmap/mips/uppermem.c;
enable = x86;
enable = ia64_efi;
enable = mips_loongson;
enable = mips;
};
module = {
@ -1354,6 +1389,11 @@ module = {
common = partmap/sun.c;
};
module = {
name = part_dvh;
common = partmap/dvh.c;
};
module = {
name = part_bsd;
common = partmap/bsdlabel.c;

View file

@ -25,6 +25,9 @@ grub_decompress_core (void *src, void *dest, unsigned long n,
char *d = (char *) dest;
const char *s = (const char *) src;
if (d == s)
return;
if (d < s)
while (n--)
*d++ = *s++;

View file

@ -44,12 +44,20 @@ compressed_size:
. = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE
uncompressed_size:
.long 0
. = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR
uncompressed_addr:
.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_QEMU_MIPS
lui $t0, %hi (((16 << 20) - 264) | 0x80000000)
lw $s4, %lo (((16 << 20) - 264) | 0x80000000) ($t0)
#endif
#ifdef GRUB_MACHINE_MIPS_LOONGSON
move $s2, $zero
move $s3, $zero
@ -216,8 +224,7 @@ cmdlinedone:
subu $a0, $a0, $t0
addu $a0, $a0, $s0
lui $a1, %hi(GRUB_MACHINE_LINK_ADDR)
addiu $a1, %lo(GRUB_MACHINE_LINK_ADDR)
lw $a1, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0)
lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
lw $a3, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0)
move $s1, $a1

View file

@ -0,0 +1,53 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/misc.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/arc/arc.h>
GRUB_MOD_LICENSE ("GPLv3+");
static grub_err_t
grub_cmd_lsdev (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
auto int hook (const char *name, const struct grub_arc_component *comp);
int hook (const char *name, const struct grub_arc_component *comp __attribute__ ((unused)))
{
grub_printf ("%s\n", name);
return 0;
}
grub_arc_iterate_devs (hook, 0);
return 0;
}
static grub_command_t cmd;
GRUB_MOD_INIT(lsdev)
{
cmd = grub_register_command ("lsdev", grub_cmd_lsdev, "",
N_("List devices."));
}
GRUB_MOD_FINI(lsdev)
{
grub_unregister_command (cmd);
}

View file

@ -0,0 +1,295 @@
/* ofdisk.c - Open Firmware disk access. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,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
* 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/misc.h>
#include <grub/disk.h>
#include <grub/mm.h>
#include <grub/arc/arc.h>
static grub_arc_fileno_t last_handle = 0;
static char *last_path = NULL;
static int lnum = 0;
struct arcdisk_hash_ent
{
char *devpath;
int num;
struct arcdisk_hash_ent *next;
};
#define ARCDISK_HASH_SZ 8
static struct arcdisk_hash_ent *arcdisk_hash[ARCDISK_HASH_SZ];
static int
arcdisk_hash_fn (const char *devpath)
{
int hash = 0;
while (*devpath)
hash ^= *devpath++;
return (hash & (ARCDISK_HASH_SZ - 1));
}
static struct arcdisk_hash_ent *
arcdisk_hash_find (const char *devpath)
{
struct arcdisk_hash_ent *p = arcdisk_hash[arcdisk_hash_fn (devpath)];
while (p)
{
if (!grub_strcmp (p->devpath, devpath))
break;
p = p->next;
}
return p;
}
static struct arcdisk_hash_ent *
arcdisk_hash_add (char *devpath)
{
struct arcdisk_hash_ent *p;
struct arcdisk_hash_ent **head = &arcdisk_hash[arcdisk_hash_fn(devpath)];
p = grub_malloc (sizeof (*p));
if (!p)
return NULL;
p->devpath = devpath;
p->next = *head;
p->num = lnum++;
*head = p;
return p;
}
static int
grub_arcdisk_iterate (int (*hook_in) (const char *name))
{
auto int hook (const char *name, const struct grub_arc_component *comp);
int hook (const char *name, const struct grub_arc_component *comp)
{
if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
|| comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
|| comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE))
return 0;
return hook_in (name);
}
return grub_arc_iterate_devs (hook, 1);
}
#define RAW_SUFFIX "partition(10)"
static grub_err_t
reopen (const char *name)
{
grub_arc_fileno_t handle;
if (last_path && grub_strcmp (last_path, name) == 0)
{
grub_dprintf ("arcdisk", "using already opened %s\n", name);
return GRUB_ERR_NONE;
}
if (GRUB_ARC_FIRMWARE_VECTOR->open (name, 0, &handle))
{
grub_dprintf ("arcdisk", "couldn't open %s\n", name);
return grub_error (GRUB_ERR_IO, "couldn't open %s", name);
}
if (last_path)
{
GRUB_ARC_FIRMWARE_VECTOR->close (last_handle);
grub_free (last_path);
last_path = NULL;
last_handle = 0;
}
last_path = grub_strdup (name);
if (!last_path)
return grub_errno;
last_handle = handle;
grub_dprintf ("arcdisk", "opened %s\n", name);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_arcdisk_open (const char *name, grub_disk_t disk)
{
char *fullname, *optr;
const char *iptr;
int state = 0;
grub_err_t err;
grub_arc_err_t r;
struct grub_arc_fileinfo info;
struct arcdisk_hash_ent *hash;
if (grub_memcmp (name, "arc/", 4) != 0)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not arc device");
fullname = grub_malloc (2 * grub_strlen (name) + sizeof (RAW_SUFFIX));
if (!fullname)
return grub_errno;
optr = fullname;
for (iptr = name + 4; *iptr; iptr++)
if (state == 0)
{
if (!grub_isdigit (*iptr))
*optr++ = *iptr;
else
{
*optr++ = '(';
*optr++ = *iptr;
state = 1;
}
}
else
{
if (grub_isdigit (*iptr))
*optr++ = *iptr;
else
{
*optr++ = ')';
state = 0;
}
}
if (state)
*optr++ = ')';
grub_memcpy (optr, RAW_SUFFIX, sizeof (RAW_SUFFIX));
disk->data = fullname;
grub_dprintf ("arcdisk", "opening %s\n", fullname);
hash = arcdisk_hash_find (fullname);
if (!hash)
hash = arcdisk_hash_add (fullname);
if (!hash)
return grub_errno;
err = reopen (fullname);
if (err)
return err;
r = GRUB_ARC_FIRMWARE_VECTOR->getfileinformation (last_handle, &info);
if (r)
{
grub_uint64_t res = 0;
int i;
grub_dprintf ("arcdisk", "couldn't retrieve size: %ld\n", r);
for (i = 40; i >= 9; i--)
{
grub_uint64_t pos = res | (1ULL << i);
char buf[512];
long unsigned count = 0;
grub_dprintf ("arcdisk",
"seek to 0x%" PRIxGRUB_UINT64_T "\n", pos);
if (GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0))
continue;
if (GRUB_ARC_FIRMWARE_VECTOR->read (last_handle, buf,
0x200, &count))
continue;
if (count == 0)
continue;
res |= (1ULL << i);
}
grub_dprintf ("arcdisk",
"determined disk size 0x%" PRIxGRUB_UINT64_T "\n", res);
disk->total_sectors = (res + 0x200) >> 9;
}
else
disk->total_sectors = (info.end >> 9);
disk->id = hash->num;
return GRUB_ERR_NONE;
}
static void
grub_arcdisk_close (grub_disk_t disk)
{
grub_free (disk->data);
}
static grub_err_t
grub_arcdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf)
{
grub_err_t err;
grub_uint64_t pos = sector << 9;
unsigned long count;
grub_uint64_t totl = size << 9;
grub_arc_err_t r;
err = reopen (disk->data);
if (err)
return err;
r = GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0);
if (r)
{
grub_dprintf ("arcdisk", "seek to 0x%" PRIxGRUB_UINT64_T " failed: %ld\n",
pos, r);
return grub_error (GRUB_ERR_IO, "couldn't seek");
}
while (totl)
{
if (GRUB_ARC_FIRMWARE_VECTOR->read (last_handle, buf,
totl, &count))
return grub_error (GRUB_ERR_READ_ERROR, "read failed");
totl -= count;
buf += count;
}
return GRUB_ERR_NONE;
}
static grub_err_t
grub_arcdisk_write (grub_disk_t disk __attribute ((unused)),
grub_disk_addr_t sector __attribute ((unused)),
grub_size_t size __attribute ((unused)),
const char *buf __attribute ((unused)))
{
return GRUB_ERR_NOT_IMPLEMENTED_YET;
}
static struct grub_disk_dev grub_arcdisk_dev =
{
.name = "arcdisk",
.id = GRUB_DISK_DEVICE_ARCDISK_ID,
.iterate = grub_arcdisk_iterate,
.open = grub_arcdisk_open,
.close = grub_arcdisk_close,
.read = grub_arcdisk_read,
.write = grub_arcdisk_write,
.next = 0
};
void
grub_arcdisk_init (void)
{
grub_disk_dev_register (&grub_arcdisk_dev);
}
void
grub_arcdisk_fini (void)
{
if (last_path)
{
GRUB_ARC_FIRMWARE_VECTOR->close (last_handle);
grub_free (last_path);
last_path = NULL;
last_handle = 0;
}
grub_disk_dev_unregister (&grub_arcdisk_dev);
}

View file

@ -22,8 +22,12 @@
#include <grub/disk.h>
#include <grub/dl.h>
#include <grub/mm.h>
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
#include <grub/pci.h>
#include <grub/cs5536.h>
#else
#define GRUB_MACHINE_PCI_IO_BASE 0xb4000000
#endif
#include <grub/time.h>
GRUB_MOD_LICENSE ("GPLv3+");
@ -319,6 +323,7 @@ grub_pata_device_initialize (int port, int device, int addr)
return 0;
}
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
static int NESTED_FUNC_ATTR
grub_pata_pciinit (grub_pci_device_t dev,
grub_pci_id_t pciid)
@ -430,6 +435,21 @@ grub_pata_initialize (void)
grub_pci_iterate (grub_pata_pciinit);
return 0;
}
#else
static grub_err_t
grub_ata_initialize (void)
{
int i;
for (i = 0; i < 2; i++)
{
grub_ata_device_initialize (i, 0, grub_ata_ioaddress[i],
grub_ata_ioaddress2[i]);
grub_ata_device_initialize (i, 1, grub_ata_ioaddress[i],
grub_ata_ioaddress2[i]);
}
return 0;
}
#endif
static grub_err_t
grub_pata_open (int id, int devnum, struct grub_ata *ata)

View file

@ -34,6 +34,10 @@
#include <stdint.h>
#include <grub/util/misc.h>
#ifdef HAVE_DEVICE_MAPPER
# include <libdevmapper.h>
#endif
#ifdef __GNU__
#include <hurd.h>
#include <hurd/lookup.h>
@ -634,32 +638,65 @@ grub_guess_root_device (const char *dir)
}
static int
grub_util_is_dmraid (const char *os_dev)
grub_util_is_lvm (const char *os_dev)
{
if (! strncmp (os_dev, "/dev/mapper/nvidia_", 19))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/isw_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/hpt37x_", 19))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/hpt45x_", 19))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/via_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/lsi_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/pdc_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/jmicron_", 20))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/asr_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/sil_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/ddf1_", 17))
return 1;
if ((strncmp ("/dev/mapper/", os_dev, 12) != 0))
return 0;
#ifdef HAVE_DEVICE_MAPPER
{
struct dm_tree *tree;
uint32_t maj, min;
struct dm_tree_node *node = NULL;
const char *node_uuid;
struct stat st;
return 0;
if (stat (os_dev, &st) < 0)
return 0;
tree = dm_tree_create ();
if (! tree)
{
grub_printf ("Failed to create tree\n");
grub_dprintf ("hostdisk", "dm_tree_create failed\n");
return 0;
}
maj = major (st.st_rdev);
min = minor (st.st_rdev);
if (! dm_tree_add_dev (tree, maj, min))
{
grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n");
dm_tree_free (tree);
return 0;
}
node = dm_tree_find_node (tree, maj, min);
if (! node)
{
grub_dprintf ("hostdisk", "dm_tree_find_node failed\n");
dm_tree_free (tree);
return 0;
}
node_uuid = dm_tree_node_get_uuid (node);
if (! node_uuid)
{
grub_dprintf ("hostdisk", "%s has no DM uuid\n", os_dev);
dm_tree_free (tree);
return 0;
}
if (strncmp (node_uuid, "LVM-", 4) != 0)
{
dm_tree_free (tree);
return 0;
}
dm_tree_free (tree);
return 1;
}
#else
return 1;
#endif /* HAVE_DEVICE_MAPPER */
}
int
@ -671,13 +708,11 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
return GRUB_DEV_ABSTRACTION_NONE;
/* Check for LVM. */
if (!strncmp (os_dev, "/dev/mapper/", 12)
&& ! grub_util_is_dmraid (os_dev)
&& strncmp (os_dev, "/dev/mapper/mpath", 17) != 0)
if (grub_util_is_lvm (os_dev))
return GRUB_DEV_ABSTRACTION_LVM;
/* Check for RAID. */
if (!strncmp (os_dev, "/dev/md", 7))
if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev))
return GRUB_DEV_ABSTRACTION_RAID;
#endif

View file

@ -24,6 +24,7 @@
#include <grub/err.h>
#include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/list.h>
@ -331,18 +332,23 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
return GRUB_ERR_NONE;
}
#ifdef HAVE_DEVICE_MAPPER
static int
device_is_mapped (const char *dev)
int
grub_util_device_is_mapped (const char *dev)
{
#ifdef HAVE_DEVICE_MAPPER
struct stat st;
if (!grub_device_mapper_supported ())
return 0;
if (stat (dev, &st) < 0)
return 0;
return dm_is_dm_major (major (st.st_rdev));
}
#else
return 0;
#endif /* HAVE_DEVICE_MAPPER */
}
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
/* FIXME: geom actually gives us the whole container hierarchy.
@ -418,7 +424,7 @@ find_partition_start (const char *dev)
# endif /* !defined(HAVE_DIOCGDINFO) */
# ifdef HAVE_DEVICE_MAPPER
if (grub_device_mapper_supported () && device_is_mapped (dev)) {
if (grub_util_device_is_mapped (dev)) {
struct dm_task *task = NULL;
grub_uint64_t start, length;
char *target_type, *params, *space;
@ -1149,6 +1155,54 @@ make_device_name (int drive, int dos_part, int bsd_part)
return ret;
}
#ifdef HAVE_DEVICE_MAPPER
static int
grub_util_get_dm_node_linear_info (const char *dev,
int *maj, int *min)
{
struct dm_task *dmt;
void *next = NULL;
uint64_t length, start;
char *target, *params;
char *ptr;
int major, minor;
dmt = dm_task_create(DM_DEVICE_TABLE);
if (!dmt)
return 0;
if (!dm_task_set_name(dmt, dev))
return 0;
dm_task_no_open_count(dmt);
if (!dm_task_run(dmt))
return 0;
next = dm_get_next_target(dmt, next, &start, &length,
&target, &params);
if (grub_strcmp (target, "linear") != 0)
return 0;
major = grub_strtoul (params, &ptr, 10);
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;
return 0;
}
if (*ptr != ':')
return 0;
ptr++;
minor = grub_strtoul (ptr, 0, 10);
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;
return 0;
}
if (maj)
*maj = major;
if (min)
*min = minor;
return 1;
}
#endif
static char *
convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
{
@ -1325,9 +1379,39 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
node = NULL;
goto devmapper_out;
}
else if (strncmp (node_uuid, "DMRAID-", 7) != 0)
if (strncmp (node_uuid, "LVM-", 4) == 0)
{
grub_dprintf ("hostdisk", "%s is an LVM\n", path);
node = NULL;
goto devmapper_out;
}
if (strncmp (node_uuid, "mpath-", 6) == 0)
{
/* Multipath partitions have partN-mpath-* UUIDs, and are
linear mappings so are handled by
grub_util_get_dm_node_linear_info. Multipath disks are not
linear mappings and must be handled specially. */
grub_dprintf ("hostdisk", "%s is a multipath disk\n", path);
mapper_name = dm_tree_node_get_name (node);
goto devmapper_out;
}
if (strncmp (node_uuid, "DMRAID-", 7) != 0)
{
int major, minor;
const char *node_name;
grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path);
if ((node_name = dm_tree_node_get_name (node))
&& grub_util_get_dm_node_linear_info (node_name,
&major, &minor))
{
if (tree)
dm_tree_free (tree);
free (path);
char *ret = grub_find_device (NULL, (major << 8) | minor);
return ret;
}
node = NULL;
goto devmapper_out;
}

View file

@ -27,35 +27,35 @@ void
grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
const Elf_Ehdr *e = ehdr;
const Elf64_Ehdr *e = ehdr;
grub_size_t cntt = 0, cntg = 0;;
const Elf_Shdr *s;
Elf_Word entsize;
const Elf64_Shdr *s;
Elf64_Word entsize;
unsigned i;
/* 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)
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff));
i < grub_le_to_cpu16 (e->e_shnum);
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
if (grub_le_to_cpu32 (s->sh_type) == SHT_SYMTAB)
break;
if (i == e->e_shnum)
if (i == grub_le_to_cpu16 (e->e_shnum))
return;
entsize = s->sh_entsize;
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_RELA)
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff));
i < grub_le_to_cpu16 (e->e_shnum);
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
if (grub_le_to_cpu32 (s->sh_type) == SHT_RELA)
{
Elf_Rela *rel, *max;
Elf64_Rela *rel, *max;
for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu32 (s->sh_offset)),
max = rel + grub_le_to_cpu32 (s->sh_size) / grub_le_to_cpu16 (s->sh_entsize);
rel < max; rel++)
switch (ELF_R_TYPE (rel->r_info))
switch (ELF64_R_TYPE (grub_le_to_cpu32 (rel->r_info)))
{
case R_IA64_PCREL21B:
cntt++;

View file

@ -54,7 +54,7 @@ grub_module_iterate (int (*hook) (struct grub_module_header *header))
}
/* This is actualy platform-independant but used only on loongson and sparc. */
#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_SPARC64)
#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64)
grub_addr_t
grub_modules_get_end (void)
{

View file

@ -0,0 +1,213 @@
/*
* 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/arc/console.h>
#include <grub/cpu/memory.h>
#include <grub/cpu/time.h>
#include <grub/memory.h>
#include <grub/term.h>
#include <grub/arc/arc.h>
#include <grub/offsets.h>
const char *type_names[] = {
#ifdef GRUB_CPU_WORDS_BIGENDIAN
NULL,
#endif
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"eisa", "tc", "scsi", "dti", "multi", "disk", "tape", "cdrom", "worm",
"serial", "net", "video", "par", "point", "key", "audio", "other",
"rdisk", "fdisk", "tape", "modem", "monitor", "print", "pointer",
"keyboard", "term", "other", "line", "network", NULL
};
static int
iterate_rec (const char *prefix, const struct grub_arc_component *parent,
int (*hook) (const char *name,
const struct grub_arc_component *comp),
int alt_names)
{
const struct grub_arc_component *comp;
FOR_ARC_CHILDREN(comp, parent)
{
char *name;
const char *cname = NULL;
if (comp->type < ARRAY_SIZE (type_names))
cname = type_names[comp->type];
if (!cname)
cname = "unknown";
if (alt_names)
name = grub_xasprintf ("%s/%s%lu", prefix, cname, comp->key);
else
name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key);
if (!name)
return 1;
if (hook (name, comp))
{
grub_free (name);
return 1;
}
if (iterate_rec ((parent ? name : prefix), comp, hook, alt_names))
{
grub_free (name);
return 1;
}
grub_free (name);
}
return 0;
}
int
grub_arc_iterate_devs (int (*hook) (const char *name,
const struct grub_arc_component *comp),
int alt_names)
{
return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, alt_names);
}
grub_err_t
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
struct grub_arc_memory_descriptor *cur = NULL;
while (1)
{
grub_memory_type_t type;
cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur);
if (!cur)
return GRUB_ERR_NONE;
switch (cur->type)
{
case GRUB_ARC_MEMORY_EXCEPTION_BLOCK:
case GRUB_ARC_MEMORY_SYSTEM_PARAMETER_BLOCK:
case GRUB_ARC_MEMORY_FW_PERMANENT:
default:
type = GRUB_MEMORY_RESERVED;
break;
case GRUB_ARC_MEMORY_FW_TEMPORARY:
case GRUB_ARC_MEMORY_FREE:
case GRUB_ARC_MEMORY_LOADED:
case GRUB_ARC_MEMORY_FREE_CONTIGUOUS:
type = GRUB_MEMORY_AVAILABLE;
break;
case GRUB_ARC_MEMORY_BADRAM:
type = GRUB_MEMORY_BADRAM;
break;
}
if (hook (((grub_uint64_t) cur->start_page) << 12,
((grub_uint64_t) cur->num_pages) << 12, type))
return GRUB_ERR_NONE;
}
}
extern grub_uint32_t grub_total_modules_size;
void
grub_machine_init (void)
{
struct grub_arc_memory_descriptor *cur = NULL;
grub_console_init_early ();
/* FIXME: measure this. */
grub_arch_cpuclock = 64000000;
grub_install_get_time_ms (grub_rtc_get_time_ms);
while (1)
{
grub_uint64_t start, end;
cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur);
if (!cur)
break;
if (cur->type != GRUB_ARC_MEMORY_FREE
&& cur->type != GRUB_ARC_MEMORY_LOADED
&& cur->type != GRUB_ARC_MEMORY_FREE_CONTIGUOUS)
continue;
start = ((grub_uint64_t) cur->start_page) << 12;
end = ((grub_uint64_t) cur->num_pages) << 12;
end += start;
if ((grub_uint64_t) end > ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR
- grub_total_modules_size) & 0x1fffffff))
end = ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size)
& 0x1fffffff);
if (end > start)
grub_mm_init_region ((void *) (grub_addr_t) (start | 0x80000000),
end - start);
}
grub_console_init_lately ();
grub_arcdisk_init ();
}
grub_addr_t
grub_arch_modules_addr (void)
{
return GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size;
}
void
grub_machine_fini (void)
{
}
void
grub_halt (void)
{
GRUB_ARC_FIRMWARE_VECTOR->powerdown ();
grub_millisleep (1500);
grub_printf ("Shutdown failed\n");
grub_refresh ();
while (1);
}
void
grub_exit (void)
{
GRUB_ARC_FIRMWARE_VECTOR->exit ();
grub_millisleep (1500);
grub_printf ("Exit failed\n");
grub_refresh ();
while (1);
}
void
grub_reboot (void)
{
GRUB_ARC_FIRMWARE_VECTOR->restart ();
grub_millisleep (1500);
grub_printf ("Reboot failed\n");
grub_refresh ();
while (1);
}

View file

@ -9,15 +9,15 @@
subu $t1, $t3, $t2
1:
cache 1, 0($t0)
addiu $t1, $t1, 0xffff
addiu $t1, $t1, -0x4
bne $t1, $zero, 1b
addiu $t0, $t0, 0x1
addiu $t0, $t0, 0x4
sync
move $t0, $t2
subu $t1, $t3, $t2
2:
cache 0, 0($t0)
addiu $t1, $t1, 0xffff
addiu $t1, $t1, -0x4
bne $t1, $zero, 2b
addiu $t0, $t0, 0x1
addiu $t0, $t0, 0x4
sync

View file

@ -34,7 +34,7 @@ grub_arch_dl_check_header (void *ehdr)
Elf_Ehdr *e = ehdr;
/* Check the magic numbers. */
#ifdef WORDS_BIGENDIAN
#ifdef GRUB_CPU_WORDS_BIGENDIAN
if (e->e_ident[EI_CLASS] != ELFCLASS32
|| e->e_ident[EI_DATA] != ELFDATA2MSB
|| e->e_machine != EM_MIPS)
@ -144,14 +144,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
rel < max;
rel++)
{
Elf_Word *addr;
grub_uint8_t *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);
addr = (grub_uint8_t *) ((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)
@ -163,7 +163,11 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
grub_uint32_t value;
Elf_Rel *rel2;
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
#endif
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
@ -175,13 +179,20 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
{
value += *(grub_int16_t *)
((char *) seg->addr + rel2->r_offset);
((char *) seg->addr + rel2->r_offset
#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ 2
#endif
);
break;
}
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
}
break;
case R_MIPS_LO16:
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
#endif
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
break;
case R_MIPS_32:
@ -208,6 +219,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
case R_MIPS_GOT16:
case R_MIPS_CALL16:
/* FIXME: reuse*/
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
#endif
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
*(grub_uint16_t *) addr
= sizeof (grub_uint32_t) * (gpptr - gp);

View file

@ -18,17 +18,27 @@
#include <grub/kernel.h>
#include <grub/env.h>
#include <grub/cpu/time.h>
#include <grub/cpu/mips.h>
/* 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, " GRUB_CPU_MIPS_COP0_TIMER_COUNT : "=r" (low));
if (low < last)
high++;
last = low;
return (((grub_uint64_t) high) << 32) | low;
}
void
grub_machine_set_prefix (void)
{
grub_env_set ("prefix", grub_prefix);
}
extern char _end[];
grub_addr_t
grub_arch_modules_addr (void)
{
return (grub_addr_t) _end;
}

View file

@ -31,6 +31,7 @@
#include <grub/cs5536.h>
#include <grub/term.h>
#include <grub/machine/ec.h>
#include <grub/cpu/memory.h>
extern void grub_video_sm712_init (void);
extern void grub_video_sis315pro_init (void);
@ -44,22 +45,6 @@ extern void grub_terminfo_init (void);
extern void grub_keylayouts_init (void);
extern void grub_boot_init (void);
/* FIXME: use interrupt to count high. */
grub_uint64_t
grub_get_rtc (void)
{
static grub_uint32_t high = 0;
static grub_uint32_t last = 0;
grub_uint32_t low;
asm volatile ("mfc0 %0, " GRUB_CPU_LOONGSON_COP0_TIMER_COUNT : "=r" (low));
if (low < last)
high++;
last = low;
return (((grub_uint64_t) high) << 32) | low;
}
grub_err_t
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
@ -272,3 +257,10 @@ grub_reboot (void)
while (1);
}
extern char _end[];
grub_addr_t
grub_arch_modules_addr (void)
{
return (grub_addr_t) _end;
}

View file

@ -6,25 +6,29 @@
#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>
#include <grub/cpu/memory.h>
#include <grub/memory.h>
#define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264))
grub_uint32_t
grub_get_rtc (void)
{
static int calln = 0;
return calln++;
}
extern void grub_serial_init (void);
extern void grub_terminfo_init (void);
void
grub_machine_init (void)
{
grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE,
RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff));
grub_addr_t modend;
/* FIXME: measure this. */
grub_arch_cpuclock = 64000000;
modend = grub_modules_get_end ();
grub_mm_init_region ((void *) modend, grub_arch_memsize
- (modend - GRUB_ARCH_LOWMEMVSTART));
grub_install_get_time_ms (grub_rtc_get_time_ms);
grub_terminfo_init ();
grub_serial_init ();
}
void
@ -53,6 +57,14 @@ grub_reboot (void)
grub_err_t
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
hook (0, RAMSIZE, GRUB_MEMORY_AVAILABLE);
hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE);
return GRUB_ERR_NONE;
}
extern char _end[];
grub_addr_t
grub_arch_modules_addr (void)
{
return (grub_addr_t) _end;
}

View file

@ -36,8 +36,8 @@ start:
bal cont
nop
. = _start + GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE
total_module_size:
. = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
VARIABLE(grub_total_modules_size)
.long 0
. = _start + GRUB_KERNEL_MACHINE_PREFIX
@ -51,7 +51,6 @@ VARIABLE(grub_prefix)
*/
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
#ifdef GRUB_MACHINE_MIPS_LOONGSON
VARIABLE (grub_arch_busclock)
.long 0
VARIABLE (grub_arch_cpuclock)
@ -60,6 +59,7 @@ VARIABLE (grub_arch_memsize)
.long 0
VARIABLE (grub_arch_highmemsize)
.long 0
#ifdef GRUB_MACHINE_MIPS_LOONGSON
VARIABLE (grub_arch_machine)
.long GRUB_ARCH_MACHINE_FULOONG
#endif
@ -67,6 +67,12 @@ cont:
/* Save our base. */
move $s0, $ra
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
lui $t1, %hi(grub_arch_busclock)
addiu $t1, %lo(grub_arch_busclock)
sw $s4, 8($t1)
#endif
#ifdef GRUB_MACHINE_MIPS_LOONGSON
lui $t1, %hi(grub_arch_busclock)
addiu $t1, %lo(grub_arch_busclock)
@ -78,6 +84,7 @@ cont:
#endif
/* Move the modules out of BSS. */
#ifndef GRUB_MACHINE_ARC
lui $t2, %hi(__bss_start)
addiu $t2, %lo(__bss_start)
@ -107,6 +114,7 @@ modulesmovcont:
b modulesmovcont
addiu $t3, $t3, -1
modulesmovdone:
#endif
/* Clean BSS. */

View file

@ -0,0 +1,48 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/datetime.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/arc/arc.h>
GRUB_MOD_LICENSE ("GPLv3+");
grub_err_t
grub_get_datetime (struct grub_datetime *datetime)
{
struct grub_arc_timeinfo *dt;
grub_memset (datetime, 0, sizeof (*datetime));
dt = GRUB_ARC_FIRMWARE_VECTOR->gettime ();
datetime->year = dt->y;
datetime->month = dt->m;
datetime->day = dt->d;
datetime->hour = dt->h;
datetime->minute = dt->min;
datetime->second = dt->s;
return 0;
}
grub_err_t
grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
{
return grub_error (GRUB_ERR_IO, "setting time isn't supported");
}

View file

@ -50,6 +50,7 @@ extern grub_uint16_t grub_relocator16_gs;
extern grub_uint16_t grub_relocator16_ss;
extern grub_uint16_t grub_relocator16_sp;
extern grub_uint32_t grub_relocator16_edx;
extern grub_uint32_t grub_relocator16_ebx;
extern grub_uint8_t grub_relocator32_start;
extern grub_uint8_t grub_relocator32_end;
@ -212,6 +213,7 @@ grub_relocator16_boot (struct grub_relocator *rel,
grub_relocator16_ss = state.ss;
grub_relocator16_sp = state.sp;
grub_relocator16_ebx = state.ebx;
grub_relocator16_edx = state.edx;
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,

View file

@ -136,7 +136,12 @@ VARIABLE(grub_relocator16_sp)
.byte 0x66, 0xba
VARIABLE(grub_relocator16_edx)
.long 0
/* movw imm32, %ebx. */
.byte 0x66, 0xbb
VARIABLE(grub_relocator16_ebx)
.long 0
/* Cleared direction flag is of no problem with any current
payload and makes this implementation easier. */
cld

View file

@ -57,7 +57,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
#endif
#define GRUB_LINUX_CL_OFFSET 0x1000
#define GRUB_LINUX_CL_END_OFFSET 0x2000
static grub_dl_t my_mod;
@ -74,6 +73,7 @@ static grub_uint32_t prot_mode_pages;
static grub_uint32_t initrd_pages;
static struct grub_relocator *relocator = NULL;
static void *efi_mmap_buf;
static grub_size_t maximal_cmdline_size;
#ifdef GRUB_MACHINE_EFI
static grub_efi_uintn_t efi_mmap_size;
#else
@ -189,7 +189,7 @@ allocate_pages (grub_size_t prot_size)
grub_err_t err;
/* Make sure that each size is aligned to a page boundary. */
real_size = GRUB_LINUX_CL_END_OFFSET;
real_size = GRUB_LINUX_CL_OFFSET + maximal_cmdline_size;
prot_size = page_align (prot_size);
mmap_size = find_mmap_size ();
@ -663,6 +663,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
if (grub_le_to_cpu16 (lh.version) >= 0x0206)
maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1;
else
maximal_cmdline_size = 256;
if (maximal_cmdline_size < 128)
maximal_cmdline_size = 128;
setup_sects = lh.setup_sects;
/* If SETUP_SECTS is not set, set it to the default (4). */
@ -676,7 +684,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
params = (struct linux_kernel_params *) real_mode_mem;
grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
grub_memset (params, 0, GRUB_LINUX_CL_OFFSET + maximal_cmdline_size);
grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
params->ps_mouse = params->padding10 = 0;
@ -871,7 +879,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_create_loader_cmdline (argc, argv,
(char *)real_mode_mem + GRUB_LINUX_CL_OFFSET
+ sizeof (LINUX_IMAGE) - 1,
GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET
maximal_cmdline_size
- (sizeof (LINUX_IMAGE) - 1));
len = prot_size;

View file

@ -0,0 +1,136 @@
/* chainloader.c - boot another boot loader */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2007,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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/loader.h>
#include <grub/file.h>
#include <grub/err.h>
#include <grub/device.h>
#include <grub/disk.h>
#include <grub/misc.h>
#include <grub/types.h>
#include <grub/partition.h>
#include <grub/dl.h>
#include <grub/command.h>
#include <grub/machine/biosnum.h>
#include <grub/i18n.h>
#include <grub/video.h>
#include <grub/mm.h>
#include <grub/cpu/relocator.h>
static grub_dl_t my_mod;
static struct grub_relocator *rel;
static grub_uint32_t ebx = 0xffffffff;
#define GRUB_FREEDOS_SEGMENT 0x60
#define GRUB_FREEDOS_STACK_SEGMENT 0x1fe0
#define GRUB_FREEDOS_STACK_POINTER 0x8000
static grub_err_t
grub_freedos_boot (void)
{
struct grub_relocator16_state state = {
.cs = GRUB_FREEDOS_SEGMENT,
.ip = 0,
.ds = 0,
.es = 0,
.fs = 0,
.gs = 0,
.ss = GRUB_FREEDOS_STACK_SEGMENT,
.sp = GRUB_FREEDOS_STACK_POINTER,
.ebx = ebx,
.edx = 0
};
grub_video_set_mode ("text", 0, 0);
return grub_relocator16_boot (rel, state);
}
static grub_err_t
grub_freedos_unload (void)
{
grub_relocator_unload (rel);
rel = NULL;
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_file_t file = 0;
grub_err_t err;
void *kernelsys;
grub_size_t kernelsyssize;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
grub_dl_ref (my_mod);
rel = grub_relocator_new ();
if (!rel)
goto fail;
file = grub_file_open (argv[0]);
if (! file)
goto fail;
ebx = grub_get_root_biosnumber ();
kernelsyssize = grub_file_size (file);
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_SEGMENT << 4,
kernelsyssize);
if (err)
goto fail;
kernelsys = get_virtual_current_address (ch);
}
if (grub_file_read (file, kernelsys, kernelsyssize)
!= (grub_ssize_t) kernelsyssize)
goto fail;
grub_loader_set (grub_freedos_boot, grub_freedos_unload, 1);
return GRUB_ERR_NONE;
fail:
if (file)
grub_file_close (file);
grub_freedos_unload ();
return grub_errno;
}
static grub_command_t cmd;
GRUB_MOD_INIT(freedos)
{
cmd = grub_register_command ("freedos", grub_cmd_freedos,
0, N_("Load FreeDOS kernel.sys."));
my_mod = mod;
}
GRUB_MOD_FINI(freedos)
{
grub_unregister_command (cmd);
}

View file

@ -39,7 +39,6 @@
GRUB_MOD_LICENSE ("GPLv3+");
#define GRUB_LINUX_CL_OFFSET 0x9000
#define GRUB_LINUX_CL_END_OFFSET 0x90FF
static grub_dl_t my_mod;
@ -49,6 +48,7 @@ static struct grub_relocator *relocator = NULL;
static grub_addr_t grub_linux_real_target;
static char *grub_linux_real_chunk;
static grub_size_t grub_linux16_prot_size;
static grub_size_t maximal_cmdline_size;
static grub_err_t
grub_linux16_boot (void)
@ -128,15 +128,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
setup_sects = lh.setup_sects;
linux_mem_size = 0;
maximal_cmdline_size = 256;
if (lh.header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
&& grub_le_to_cpu16 (lh.version) >= 0x0200)
{
grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL);
lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
if (grub_le_to_cpu16 (lh.version) >= 0x0206)
maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1;
/* Put the real mode part at as a high location as possible. */
grub_linux_real_target = grub_mmap_get_lower ()
- GRUB_LINUX_SETUP_MOVE_SIZE;
- (GRUB_LINUX_CL_OFFSET + maximal_cmdline_size);
/* But it must not exceed the traditional area. */
if (grub_linux_real_target > GRUB_LINUX_OLD_REAL_MODE_ADDR)
grub_linux_real_target = GRUB_LINUX_OLD_REAL_MODE_ADDR;
@ -153,7 +158,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
{
lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_SETUP_MOVE_SIZE);
lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET
+ maximal_cmdline_size);
}
}
else
@ -185,12 +191,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
if (grub_linux_real_target + GRUB_LINUX_SETUP_MOVE_SIZE
if (grub_linux_real_target + GRUB_LINUX_CL_OFFSET + maximal_cmdline_size
> grub_mmap_get_lower ())
{
grub_error (GRUB_ERR_OUT_OF_RANGE,
"too small lower memory (0x%x > 0x%x)",
grub_linux_real_target + GRUB_LINUX_SETUP_MOVE_SIZE,
grub_linux_real_target + GRUB_LINUX_CL_OFFSET
+ maximal_cmdline_size,
(int) grub_mmap_get_lower ());
goto fail;
}
@ -263,7 +270,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
grub_linux_real_target,
GRUB_LINUX_SETUP_MOVE_SIZE);
GRUB_LINUX_CL_OFFSET
+ maximal_cmdline_size);
if (err)
return err;
grub_linux_real_chunk = get_virtual_current_address (ch);
@ -294,7 +302,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_create_loader_cmdline (argc, argv,
(char *)grub_linux_real_chunk
+ GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET
maximal_cmdline_size
- (sizeof (LINUX_IMAGE) - 1));
if (grub_linux_is_bzimage)

View file

@ -27,14 +27,15 @@
#include <grub/mips/relocator.h>
#include <grub/memory.h>
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
GRUB_MOD_LICENSE ("GPLv3+");
/* For frequencies. */
#include <grub/pci.h>
#include <grub/machine/time.h>
#ifdef GRUB_MACHINE_MIPS_LOONGSON
#include <grub/pci.h>
#include <grub/machine/kernel.h>
const char loongson_machtypes[][60] =
@ -53,9 +54,16 @@ static grub_size_t linux_size;
static struct grub_relocator *relocator;
static grub_uint8_t *playground;
static grub_addr_t target_addr, entry_addr;
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
static char *params;
#else
static int linux_argc;
static grub_off_t argv_off, envp_off;
static grub_off_t argv_off;
#ifdef GRUB_MACHINE_MIPS_LOONGSON
static grub_off_t envp_off;
#endif
static grub_off_t rd_addr_arg_off, rd_size_arg_off;
#endif
static int initrd_loaded = 0;
static grub_err_t
@ -63,11 +71,43 @@ grub_linux_boot (void)
{
struct grub_relocator32_state state;
grub_memset (&state, 0, sizeof (state));
/* Boot the kernel. */
state.gpr[1] = entry_addr;
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
{
grub_err_t err;
grub_relocator_chunk_t ch;
grub_uint32_t *memsize;
grub_uint32_t *magic;
char *str;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
((16 << 20) - 264),
grub_strlen (params) + 1 + 8);
if (err)
return err;
memsize = get_virtual_current_address (ch);
magic = memsize + 1;
*memsize = grub_mmap_get_lower ();
*magic = 0x12345678;
str = (char *) (magic + 1);
grub_strcpy (str, params);
}
#endif
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
state.gpr[4] = linux_argc;
state.gpr[5] = target_addr + argv_off;
#ifdef GRUB_MACHINE_MIPS_LOONGSON
state.gpr[6] = target_addr + envp_off;
#else
state.gpr[6] = 0;
#endif
state.gpr[7] = 0;
#endif
state.jumpreg = 1;
grub_relocator32_boot (relocator, state);
@ -80,6 +120,11 @@ grub_linux_unload (void)
grub_relocator_unload (relocator);
grub_dl_unref (my_mod);
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
grub_free (params);
params = 0;
#endif
loaded = 0;
return GRUB_ERR_NONE;
@ -199,12 +244,18 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_elf_t elf = 0;
int i;
int size;
void *extra = NULL;
grub_uint32_t *linux_argv, *linux_envp;
char *linux_args, *linux_envs;
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
int i;
grub_uint32_t *linux_argv;
char *linux_args;
#endif
grub_err_t err;
#ifdef GRUB_MACHINE_MIPS_LOONGSON
char *linux_envs;
grub_uint32_t *linux_envp;
#endif
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
@ -224,6 +275,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_loader_unset ();
loaded = 0;
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
size = 0;
#else
/* For arguments. */
linux_argc = argc;
#ifdef GRUB_MACHINE_MIPS_LOONGSON
@ -256,6 +310,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4)
+ ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4)
+ ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4);
#endif
if (grub_elf_is_elf32 (elf))
err = grub_linux_load32 (elf, &extra, size);
@ -270,6 +325,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (err)
return err;
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
/* Create kernel command line. */
size = grub_loader_cmdline_size(argc, argv);
params = grub_malloc (size + sizeof (LINUX_IMAGE));
if (! params)
{
grub_linux_unload ();
return grub_errno;
}
grub_memcpy (params, LINUX_IMAGE, sizeof (LINUX_IMAGE));
grub_create_loader_cmdline (argc, argv, params + sizeof (LINUX_IMAGE) - 1,
size);
#else
linux_argv = extra;
argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;
extra = linux_argv + (linux_argc + 1 + 2);
@ -321,6 +390,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
extra = linux_args;
#ifdef GRUB_MACHINE_MIPS_LOONGSON
linux_envp = extra;
envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground;
linux_envs = (char *) (linux_envp + 5);
@ -348,8 +418,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ target_addr;
linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
linux_envp[4] = 0;
#endif
#endif
grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
initrd_loaded = 0;
@ -412,6 +483,21 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
return grub_errno;
}
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
{
char *tmp;
tmp = grub_xasprintf ("%s rd_start=0x%" PRIxGRUB_ADDR
" rd_size=0x%" PRIxGRUB_ADDR, params,
initrd_dest, size);
if (!tmp)
{
grub_file_close (file);
return grub_errno;
}
grub_free (params);
params = tmp;
}
#else
grub_snprintf ((char *) playground + rd_addr_arg_off,
sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%llx",
(unsigned long long) initrd_dest);
@ -425,6 +511,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
((grub_uint32_t *) (playground + argv_off))[linux_argc]
= target_addr + rd_size_arg_off;
linux_argc++;
#endif
initrd_loaded = 1;

View file

@ -20,7 +20,7 @@
#include <grub/memory.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/machine/memory.h>
#include <grub/cpu/memory.h>
grub_uint64_t
grub_mmap_get_lower (void)

4
grub-core/modinfo.sh.in Normal file
View file

@ -0,0 +1,4 @@
#!/bin/sh
grub_modinfo_target_cpu=@target_cpu@
grub_modinfo_platform=@platform@

124
grub-core/partmap/dvh.c Normal file
View file

@ -0,0 +1,124 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2006,2007,2011 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/partition.h>
#include <grub/disk.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/dl.h>
#include <grub/symbol.h>
#include <grub/types.h>
#include <grub/err.h>
GRUB_MOD_LICENSE ("GPLv3+");
#define DVH_MAGIC 0x0be5a941
struct grub_dvh_partition_descriptor
{
grub_uint32_t length;
grub_uint32_t start;
grub_uint32_t type;
} __attribute__ ((packed));
struct grub_dvh_block
{
grub_uint32_t magic;
grub_uint8_t unused[308];
struct grub_dvh_partition_descriptor parts[16];
grub_uint32_t checksum;
grub_uint32_t unused2;
} __attribute__ ((packed));
static struct grub_partition_map grub_dvh_partition_map;
/* Verify checksum (true=ok). */
static int
grub_dvh_is_valid (struct grub_dvh_block *label)
{
grub_uint32_t *pos;
grub_uint32_t sum = 0;
for (pos = (grub_uint32_t *) label;
pos < (grub_uint32_t *) (label + 1);
pos++)
sum += *pos;
return ! sum;
}
static grub_err_t
dvh_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk,
const grub_partition_t partition))
{
struct grub_partition p;
struct grub_dvh_block block;
unsigned partnum;
grub_err_t err;
p.partmap = &grub_dvh_partition_map;
err = grub_disk_read (disk, 0, 0, sizeof (struct grub_dvh_block),
&block);
if (err)
return err;
if (DVH_MAGIC != grub_be_to_cpu32 (block.magic))
return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a dvh partition table");
if (! grub_dvh_is_valid (&block))
return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
/* Maybe another error value would be better, because partition
table _is_ recognized but invalid. */
for (partnum = 0; partnum < ARRAY_SIZE (block.parts); partnum++)
{
if (block.parts[partnum].length == 0)
continue;
if (partnum == 10)
continue;
p.start = grub_be_to_cpu32 (block.parts[partnum].start);
p.len = grub_be_to_cpu32 (block.parts[partnum].length);
p.number = p.index = partnum;
if (hook (disk, &p))
break;
}
return grub_errno;
}
/* Partition map type. */
static struct grub_partition_map grub_dvh_partition_map =
{
.name = "dvh",
.iterate = dvh_partition_map_iterate,
};
GRUB_MOD_INIT(part_dvh)
{
grub_partition_map_register (&grub_dvh_partition_map);
}
GRUB_MOD_FINI(part_dvh)
{
grub_partition_map_unregister (&grub_dvh_partition_map);
}

View file

@ -0,0 +1,123 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/arc/arc.h>
#include <grub/arc/console.h>
#include <grub/term.h>
#include <grub/terminfo.h>
/* FIXME: use unicode. */
static int
readkey (struct grub_term_input *term __attribute__ ((unused)))
{
unsigned long count;
char chr;
if (GRUB_ARC_FIRMWARE_VECTOR->get_read_status (GRUB_ARC_STDIN))
return -1;
if (GRUB_ARC_FIRMWARE_VECTOR->read (GRUB_ARC_STDIN, &chr, 1, &count))
return -1;
if (!count)
return -1;
return chr;
}
static void
put (struct grub_term_output *term __attribute__ ((unused)), const int c)
{
unsigned long count;
char chr = c;
GRUB_ARC_FIRMWARE_VECTOR->write (GRUB_ARC_STDOUT, &chr, 1, &count);
}
static struct grub_terminfo_output_state grub_console_terminfo_output;
static grub_err_t
grub_console_init_output (struct grub_term_output *term)
{
struct grub_arc_display_status *info = NULL;
if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length
>= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
&& GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus)
info = GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus (GRUB_ARC_STDOUT);
if (info)
{
grub_console_terminfo_output.width = info->w;
grub_console_terminfo_output.height = info->h;
}
grub_terminfo_output_init (term);
return 0;
}
static struct grub_terminfo_input_state grub_console_terminfo_input =
{
.readkey = readkey
};
static struct grub_terminfo_output_state grub_console_terminfo_output =
{
.put = put,
.width = 80,
.height = 36
};
static struct grub_term_input grub_console_term_input =
{
.name = "console",
.init = grub_terminfo_input_init,
.getkey = grub_terminfo_getkey,
.data = &grub_console_terminfo_input
};
static struct grub_term_output grub_console_term_output =
{
.name = "console",
.init = grub_console_init_output,
.putchar = grub_terminfo_putchar,
.getxy = grub_terminfo_getxy,
.getwh = grub_terminfo_getwh,
.gotoxy = grub_terminfo_gotoxy,
.cls = grub_terminfo_cls,
.setcolorstate = grub_terminfo_setcolorstate,
.setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_console_terminfo_output,
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
void
grub_console_init_early (void)
{
grub_term_register_input ("console", &grub_console_term_input);
grub_term_register_output ("console", &grub_console_term_output);
}
void grub_terminfo_init (void);
void
grub_console_init_lately (void)
{
grub_terminfo_init ();
grub_terminfo_output_register (&grub_console_term_output, "arc");
}

View file

@ -36,6 +36,9 @@
GRUB_MOD_LICENSE ("GPLv3+");
#define ANSI_C0 0x9b
#define ANSI_C0_STR "\x9b"
static struct grub_term_output *terminfo_outputs;
/* Get current terminfo name. */
@ -123,6 +126,20 @@ grub_terminfo_set_current (struct grub_term_output *term,
return grub_errno;
}
if (grub_strcmp ("arc", str) == 0)
{
data->name = grub_strdup ("arc");
data->gotoxy = grub_strdup (ANSI_C0_STR "%i%p1%d;%p2%dH");
data->cls = grub_strdup (ANSI_C0_STR "2J");
data->reverse_video_on = grub_strdup (ANSI_C0_STR "7m");
data->reverse_video_off = grub_strdup (ANSI_C0_STR "0m");
data->cursor_on = 0;
data->cursor_off = 0;
data->setcolor = grub_strdup (ANSI_C0_STR "3%p1%dm"
ANSI_C0_STR "4%p2%dm");
return grub_errno;
}
if (grub_strcmp ("ieee1275", str) == 0)
{
data->name = grub_strdup ("ieee1275");
@ -369,8 +386,6 @@ grub_terminfo_getwh (struct grub_term_output *term)
return (data->width << 8) | data->height;
}
#define ANSI_C0 0x9b
static void
grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
int (*readkey) (struct grub_term_input *term))
@ -430,7 +445,8 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
{'K', GRUB_TERM_KEY_END},
{'P', GRUB_TERM_KEY_DC},
{'?', GRUB_TERM_KEY_PPAGE},
{'/', GRUB_TERM_KEY_NPAGE}
{'/', GRUB_TERM_KEY_NPAGE},
{'@', GRUB_TERM_KEY_INSERT},
};
static struct
@ -445,6 +461,14 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
{'5', GRUB_TERM_KEY_PPAGE},
{'6', GRUB_TERM_KEY_NPAGE}
};
char fx_key[] =
{ 'P', 'Q', 'w', 'x', 't', 'u',
'q', 'r', 'p', 'M', 'A', 'B' };
unsigned fx_code[] =
{ GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3,
GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6,
GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9,
GRUB_TERM_KEY_F10, GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12 };
unsigned i;
if (c == '\e')
@ -465,17 +489,53 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
return;
}
for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
if (four_code_table[i].key == c)
switch (c)
{
case 'O':
CONTINUE_READ;
for (i = 0; i < ARRAY_SIZE (fx_key); i++)
if (fx_key[i] == c)
{
keys[0] = fx_code[i];
*len = 1;
return;
}
return;
case '0':
{
int num = 0;
CONTINUE_READ;
if (c != '~')
if (c != '0' && c != '1')
return;
keys[0] = three_code_table[i].ascii;
num = (c - '0') * 10;
CONTINUE_READ;
if (c < '0' || c > '9')
return;
num += (c - '0');
if (num == 0 || num > 12)
return;
CONTINUE_READ;
if (c != 'q')
return;
keys[0] = fx_code[num - 1];
*len = 1;
return;
}
return;
}
default:
for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
if (four_code_table[i].key == c)
{
CONTINUE_READ;
if (c != '~')
return;
keys[0] = three_code_table[i].ascii;
*len = 1;
return;
}
return;
}
}
#undef CONTINUE_READ
}