merge mainline to ia64

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-01-03 00:04:39 +01:00
commit 0f35c665e6
595 changed files with 62746 additions and 9109 deletions

View file

@ -40,7 +40,7 @@ grub_register_command_prio (const char *name,
cmd->summary = (summary) ? summary : "";
cmd->description = description;
cmd->flags = GRUB_COMMAND_FLAG_BOTH;
cmd->flags = 0;
cmd->prio = prio;
grub_prio_list_insert (GRUB_AS_PRIO_LIST_P (&grub_command_list),

View file

@ -178,9 +178,12 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
void
grub_register_core_commands (void)
{
grub_register_command ("set", grub_core_cmd_set,
N_("[ENVVAR=VALUE]"),
N_("Set an environment variable."));
grub_command_t cmd;
cmd = grub_register_command ("set", grub_core_cmd_set,
N_("[ENVVAR=VALUE]"),
N_("Set an environment variable."));
if (cmd)
cmd->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
grub_register_command ("unset", grub_core_cmd_unset,
N_("ENVVAR"),
N_("Remove an environment variable."));

View file

@ -103,7 +103,7 @@ grub_device_iterate (int (*hook) (const char *name))
return 0;
}
if (dev->disk && dev->disk->has_partitions)
if (dev->disk)
{
struct part_ent *p;
int ret = 0;
@ -135,28 +135,28 @@ grub_device_iterate (int (*hook) (const char *name))
int iterate_partition (grub_disk_t disk, const grub_partition_t partition)
{
char *partition_name;
struct part_ent *p;
partition_name = grub_partition_get_name (partition);
if (! partition_name)
return 1;
char *part_name;
p = grub_malloc (sizeof (*p));
if (!p)
{
grub_free (partition_name);
return 1;
}
p->name = grub_xasprintf ("%s,%s", disk->name, partition_name);
if (!p->name)
part_name = grub_partition_get_name (partition);
if (!part_name)
{
grub_free (p);
return 1;
}
p->name = grub_xasprintf ("%s,%s", disk->name, part_name);
grub_free (part_name);
if (!p->name)
{
grub_free (partition_name);
grub_free (p);
return 1;
}
grub_free (partition_name);
p->next = ents;
ents = p;

View file

@ -248,10 +248,6 @@ grub_disk_open (const char *name)
if (! disk)
return 0;
disk->name = grub_strdup (name);
if (! disk->name)
goto fail;
p = find_part_sep (name);
if (p)
{
@ -263,7 +259,13 @@ grub_disk_open (const char *name)
grub_memcpy (raw, name, len);
raw[len] = '\0';
disk->name = grub_strdup (raw);
}
else
disk->name = grub_strdup (name);
if (! disk->name)
goto fail;
for (dev = grub_disk_dev_list; dev; dev = dev->next)
{
@ -281,12 +283,6 @@ grub_disk_open (const char *name)
goto fail;
}
if (p && ! disk->has_partitions)
{
grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk");
goto fail;
}
disk->dev = dev;
if (p)

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

@ -25,26 +25,13 @@
#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
#define BYTES_TO_PAGES(bytes) ((bytes) >> 12)
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
#define PAGES_TO_BYTES(pages) ((pages) << 12)
/* The size of a memory map obtained from the firmware. This must be
a multiplier of 4KB. */
#define MEMORY_MAP_SIZE 0x3000
/* Maintain the list of allocated pages. */
struct allocated_page
{
grub_efi_physical_address_t addr;
grub_efi_uint64_t num_pages;
};
#define ALLOCATED_PAGES_SIZE 0x1000
#define MAX_ALLOCATED_PAGES \
(ALLOCATED_PAGES_SIZE / sizeof (struct allocated_page))
static struct allocated_page *allocated_pages = 0;
/* The minimum and maximum heap size for GRUB itself. */
#define MIN_HEAP_SIZE 0x100000
#define MAX_HEAP_SIZE (1600 * 0x100000)
@ -102,22 +89,6 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
return 0;
}
if (allocated_pages)
{
unsigned i;
for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
if (allocated_pages[i].addr == 0)
{
allocated_pages[i].addr = address;
allocated_pages[i].num_pages = pages;
break;
}
if (i == MAX_ALLOCATED_PAGES)
grub_fatal ("too many page allocations");
}
return (void *) ((grub_addr_t) address);
}
@ -128,20 +99,6 @@ grub_efi_free_pages (grub_efi_physical_address_t address,
{
grub_efi_boot_services_t *b;
if (allocated_pages
&& ((grub_efi_physical_address_t) ((grub_addr_t) allocated_pages)
!= address))
{
unsigned i;
for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
if (allocated_pages[i].addr == address)
{
allocated_pages[i].addr = 0;
break;
}
}
b = grub_efi_system_table->boot_services;
efi_call_2 (b->free_pages, address, pages);
}
@ -422,14 +379,6 @@ grub_efi_mm_init (void)
grub_efi_uint64_t required_pages;
int mm_status;
/* First of all, allocate pages to maintain allocations. */
allocated_pages
= grub_efi_allocate_pages (0, BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
if (! allocated_pages)
grub_fatal ("cannot allocate memory");
grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
/* Prepare a memory region to store two memory maps. */
memory_map = grub_efi_allocate_pages (0,
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
@ -447,6 +396,9 @@ grub_efi_mm_init (void)
((grub_efi_physical_address_t) ((grub_addr_t) memory_map),
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
/* Freeing/allocating operations may increase memory map size. */
map_size += desc_size * 32;
memory_map = grub_efi_allocate_pages (0, 2 * BYTES_TO_PAGES (map_size));
if (! memory_map)
grub_fatal ("cannot allocate memory");
@ -499,24 +451,3 @@ grub_efi_mm_init (void)
grub_efi_free_pages ((grub_addr_t) memory_map,
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
}
void
grub_efi_mm_fini (void)
{
if (allocated_pages)
{
unsigned i;
for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
{
struct allocated_page *p;
p = allocated_pages + i;
if (p->addr != 0)
grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages);
}
grub_efi_free_pages ((grub_addr_t) allocated_pages,
BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
}
}

View file

@ -21,7 +21,6 @@
#include <grub/elf.h>
#include <grub/elfload.h>
#include <grub/file.h>
#include <grub/gzio.h>
#include <grub/misc.h>
#include <grub/mm.h>
@ -95,7 +94,7 @@ grub_elf_open (const char *name)
grub_file_t file;
grub_elf_t elf;
file = grub_gzfile_open (name, 1);
file = grub_file_open (name);
if (! file)
return 0;
@ -172,11 +171,12 @@ grub_elf32_phdr_iterate (grub_elf_t elf,
/* Calculate the amount of memory spanned by the segments. */
grub_size_t
grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
grub_elf32_size (grub_elf_t elf, Elf32_Addr *base, grub_uint32_t *max_align)
{
Elf32_Addr segments_start = (Elf32_Addr) -1;
Elf32_Addr segments_end = 0;
int nr_phdrs = 0;
grub_uint32_t curr_align = 1;
/* Run through the program headers to calculate the total memory size we
* should claim. */
@ -193,6 +193,8 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
segments_start = phdr->p_paddr;
if (phdr->p_paddr + phdr->p_memsz > segments_end)
segments_end = phdr->p_paddr + phdr->p_memsz;
if (curr_align < phdr->p_align)
curr_align = phdr->p_align;
return 0;
}
@ -216,7 +218,8 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
if (base)
*base = segments_start;
if (max_align)
*max_align = curr_align;
return segments_end - segments_start;
}
@ -291,7 +294,6 @@ grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook,
return err;
}
/* 64-bit */
@ -358,16 +360,17 @@ grub_elf64_phdr_iterate (grub_elf_t elf,
/* Calculate the amount of memory spanned by the segments. */
grub_size_t
grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
grub_elf64_size (grub_elf_t elf, Elf64_Addr *base, grub_uint64_t *max_align)
{
Elf64_Addr segments_start = (Elf64_Addr) -1;
Elf64_Addr segments_end = 0;
int nr_phdrs = 0;
grub_uint64_t curr_align = 1;
/* Run through the program headers to calculate the total memory size we
* should claim. */
auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg);
int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)),
int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)),
Elf64_Phdr *phdr,
void *_arg __attribute__ ((unused)))
{
@ -379,6 +382,8 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
segments_start = phdr->p_paddr;
if (phdr->p_paddr + phdr->p_memsz > segments_end)
segments_end = phdr->p_paddr + phdr->p_memsz;
if (curr_align < phdr->p_align)
curr_align = phdr->p_align;
return 0;
}
@ -402,11 +407,11 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
if (base)
*base = segments_start;
if (max_align)
*max_align = curr_align;
return segments_end - segments_start;
}
/* Load every loadable segment into memory specified by `_load_hook'. */
grub_err_t
grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook,

View file

@ -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"
#elif defined(__ia64__)

View file

@ -18,6 +18,7 @@
*/
#include <config.h>
#include <config-util.h>
/* For compatibility. */
#ifndef A_NORMAL
@ -37,6 +38,8 @@
# include <ncurses.h>
#elif defined(HAVE_CURSES_H)
# include <curses.h>
#else
#error What the hell?
#endif
static int grub_console_attr = A_NORMAL;
@ -102,63 +105,32 @@ grub_ncurses_setcolorstate (struct grub_term_output *term,
}
}
static int saved_char = ERR;
static int
grub_ncurses_checkkey (struct grub_term_input *term __attribute__ ((unused)))
{
int c;
/* Check for SAVED_CHAR. This should not be true, because this
means checkkey is called twice continuously. */
if (saved_char != ERR)
return saved_char;
wtimeout (stdscr, 100);
c = getch ();
/* If C is not ERR, then put it back in the input queue. */
if (c != ERR)
{
saved_char = c;
return c;
}
return -1;
}
static int
grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused)))
{
int c;
/* If checkkey has already got a character, then return it. */
if (saved_char != ERR)
{
c = saved_char;
saved_char = ERR;
}
else
{
wtimeout (stdscr, -1);
c = getch ();
}
wtimeout (stdscr, 100);
c = getch ();
switch (c)
{
case ERR:
return -1;
case KEY_LEFT:
c = GRUB_TERM_LEFT;
c = GRUB_TERM_KEY_LEFT;
break;
case KEY_RIGHT:
c = GRUB_TERM_RIGHT;
c = GRUB_TERM_KEY_RIGHT;
break;
case KEY_UP:
c = GRUB_TERM_UP;
c = GRUB_TERM_KEY_UP;
break;
case KEY_DOWN:
c = GRUB_TERM_DOWN;
c = GRUB_TERM_KEY_DOWN;
break;
case KEY_IC:
@ -166,30 +138,30 @@ grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused)))
break;
case KEY_DC:
c = GRUB_TERM_DC;
c = GRUB_TERM_KEY_DC;
break;
case KEY_BACKSPACE:
/* XXX: For some reason ncurses on xterm does not return
KEY_BACKSPACE. */
case 127:
c = GRUB_TERM_BACKSPACE;
c = '\b';
break;
case KEY_HOME:
c = GRUB_TERM_HOME;
c = GRUB_TERM_KEY_HOME;
break;
case KEY_END:
c = GRUB_TERM_END;
c = GRUB_TERM_KEY_END;
break;
case KEY_NPAGE:
c = GRUB_TERM_NPAGE;
c = GRUB_TERM_KEY_NPAGE;
break;
case KEY_PPAGE:
c = GRUB_TERM_PPAGE;
c = GRUB_TERM_KEY_PPAGE;
break;
}
@ -288,7 +260,6 @@ grub_ncurses_fini (struct grub_term_output *term __attribute__ ((unused)))
static struct grub_term_input grub_ncurses_term_input =
{
.name = "console",
.checkkey = grub_ncurses_checkkey,
.getkey = grub_ncurses_getkey,
};

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)
@ -56,5 +57,24 @@ void grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)),
*tramp = 0;
*got = 0;
}
#endif
#ifdef GRUB_LINKER_HAVE_INIT
void
grub_arch_dl_init_linker (void)
{
}
#endif
void
grub_emu_post_init (void)
{
grub_lvm_fini ();
grub_mdraid09_fini ();
grub_mdraid1x_fini ();
grub_raid_fini ();
grub_raid_init ();
grub_mdraid09_init ();
grub_mdraid1x_init ();
grub_lvm_init ();
}

View file

@ -189,31 +189,40 @@ find_root_device_from_libzfs (const char *dir)
{
zpool_handle_t *zpool;
libzfs_handle_t *libzfs;
nvlist_t *nvlist;
nvlist_t **nvlist_array;
nvlist_t *config, *vdev_tree;
nvlist_t **children, **path;
unsigned int nvlist_count;
unsigned int i;
libzfs = grub_get_libzfs_handle ();
if (! libzfs)
return NULL;
zpool = zpool_open (libzfs, poolname);
nvlist = zpool_get_config (zpool, NULL);
config = zpool_get_config (zpool, NULL);
if (nvlist_lookup_nvlist (nvlist, "vdev_tree", &nvlist) != 0)
if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0)
error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")");
if (nvlist_lookup_nvlist_array (nvlist, "children", &nvlist_array, &nvlist_count) != 0)
if (nvlist_lookup_nvlist_array (vdev_tree, "children", &children, &nvlist_count) != 0)
error (1, errno, "nvlist_lookup_nvlist_array (\"children\")");
assert (nvlist_count > 0);
do
while (nvlist_lookup_nvlist_array (children[0], "children",
&children, &nvlist_count) == 0)
assert (nvlist_count > 0);
for (i = 0; i < nvlist_count; i++)
{
assert (nvlist_count > 0);
} while (nvlist_lookup_nvlist_array (nvlist_array[0], "children",
&nvlist_array, &nvlist_count) == 0);
if (nvlist_lookup_string (children[i], "path", &device) != 0)
error (1, errno, "nvlist_lookup_string (\"path\")");
if (nvlist_lookup_string (nvlist_array[0], "path", &device) != 0)
error (1, errno, "nvlist_lookup_string (\"path\")");
struct stat st;
if (stat (device, &st) == 0)
break;
device = NULL;
}
zpool_close (zpool);
}
@ -228,8 +237,8 @@ find_root_device_from_libzfs (const char *dir)
#ifdef __MINGW32__
static char *
find_root_device (const char *dir __attribute__ ((unused)),
char *
grub_find_device (const char *dir __attribute__ ((unused)),
dev_t dev __attribute__ ((unused)))
{
return 0;
@ -237,13 +246,22 @@ find_root_device (const char *dir __attribute__ ((unused)),
#elif ! defined(__CYGWIN__)
static char *
find_root_device (const char *dir, dev_t dev)
char *
grub_find_device (const char *dir, dev_t dev)
{
DIR *dp;
char *saved_cwd;
struct dirent *ent;
if (! dir)
{
#ifdef __CYGWIN__
return NULL;
#else
dir = "/dev";
#endif
}
dp = opendir (dir);
if (! dp)
return 0;
@ -292,7 +310,7 @@ find_root_device (const char *dir, dev_t dev)
/* Find it recursively. */
char *res;
res = find_root_device (ent->d_name, dev);
res = grub_find_device (ent->d_name, dev);
if (res)
{
@ -402,8 +420,8 @@ get_bootsec_serial (const char *os_dev, int mbr)
return serial;
}
static char *
find_cygwin_root_device (const char *path, dev_t dev)
char *
grub_find_device (const char *path, dev_t dev)
{
/* No root device for /cygdrive. */
if (dev == (DEV_CYGDRIVE_MAJOR << 16))
@ -424,7 +442,7 @@ find_cygwin_root_device (const char *path, dev_t dev)
/* Cygwin returns the partition serial number in stat.st_dev.
This is never identical to the device number of the emulated
/dev/sdXN device, so above find_root_device () does not work.
/dev/sdXN device, so above grub_find_device () does not work.
Search the partition with the same serial in boot sector instead. */
char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia. */
int d;
@ -529,12 +547,12 @@ grub_guess_root_device (const char *dir)
#ifdef __CYGWIN__
/* Cygwin specific function. */
os_dev = find_cygwin_root_device (dir, st.st_dev);
os_dev = grub_find_device (dir, st.st_dev);
#else
/* This might be truly slow, but is there any better way? */
os_dev = find_root_device ("/dev", st.st_dev);
os_dev = grub_find_device ("/dev", st.st_dev);
#endif
#endif /* !__GNU__ */
@ -564,6 +582,8 @@ grub_util_is_dmraid (const char *os_dev)
return 1;
else if (! strncmp (os_dev, "/dev/mapper/sil_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/ddf1_", 17))
return 1;
return 0;
}
@ -572,6 +592,10 @@ int
grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
{
#ifdef __linux__
/* User explicitly claims that this drive is visible by BIOS. */
if (grub_util_biosdisk_is_present (os_dev))
return GRUB_DEV_ABSTRACTION_NONE;
/* Check for LVM. */
if (!strncmp (os_dev, "/dev/mapper/", 12)
&& ! grub_util_is_dmraid (os_dev)

View file

@ -1,7 +1,7 @@
/* hostdisk.c - emulate biosdisk */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -102,13 +102,22 @@ struct hd_geometry
# include <libdevmapper.h>
#endif
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
# define HAVE_DIOCGDINFO
# include <sys/ioctl.h>
# include <sys/disklabel.h> /* struct disklabel */
#else /* !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) */
# undef HAVE_DIOCGDINFO
#endif /* defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */
#if defined(__NetBSD__)
# ifdef HAVE_GETRAWPARTITION
# include <util.h> /* getrawpartition */
# endif /* HAVE_GETRAWPARTITION */
# include <sys/fdio.h>
# ifndef FLOPPY_MAJOR
# define FLOPPY_MAJOR 2
# endif /* ! FLOPPY_MAJOR */
# ifndef RAW_FLOPPY_MAJOR
# define RAW_FLOPPY_MAJOR 9
# endif /* ! RAW_FLOPPY_MAJOR */
@ -221,7 +230,6 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"no mapping exists for `%s'", name);
disk->has_partitions = 1;
disk->id = drive;
disk->data = data = xmalloc (sizeof (struct grub_util_biosdisk_data));
data->dev = NULL;
@ -329,17 +337,17 @@ device_is_mapped (const char *dev)
}
#endif /* HAVE_DEVICE_MAPPER */
#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__)
#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
static grub_disk_addr_t
find_partition_start (const char *dev)
{
int fd;
# if !defined(__NetBSD__)
# if !defined(HAVE_DIOCGDINFO)
struct hd_geometry hdg;
# else /* defined(__NetBSD__) */
# else /* defined(HAVE_DIOCGDINFO) */
struct disklabel label;
int p_index;
# endif /* !defined(__NetBSD__) */
# endif /* !defined(HAVE_DIOCGDINFO) */
# ifdef HAVE_DEVICE_MAPPER
if (grub_device_mapper_supported () && device_is_mapped (dev)) {
@ -413,36 +421,38 @@ devmapper_fail:
if (fd == -1)
{
grub_error (GRUB_ERR_BAD_DEVICE,
# if !defined(__NetBSD__)
# if !defined(HAVE_DIOCGDINFO)
"cannot open `%s' while attempting to get disk geometry", dev);
# else /* defined(__NetBSD__) */
# else /* defined(HAVE_DIOCGDINFO) */
"cannot open `%s' while attempting to get disk label", dev);
# endif /* !defined(__NetBSD__) */
# endif /* !defined(HAVE_DIOCGDINFO) */
return 0;
}
# if !defined(__NetBSD__)
# if !defined(HAVE_DIOCGDINFO)
if (ioctl (fd, HDIO_GETGEO, &hdg))
# else /* defined(__NetBSD__) */
# else /* defined(HAVE_DIOCGDINFO) */
# if defined(__NetBSD__)
configure_device_driver (fd);
# endif /* defined(__NetBSD__) */
if (ioctl (fd, DIOCGDINFO, &label) == -1)
# endif /* !defined(__NetBSD__) */
# endif /* !defined(HAVE_DIOCGDINFO) */
{
grub_error (GRUB_ERR_BAD_DEVICE,
# if !defined(__NetBSD__)
# if !defined(HAVE_DIOCGDINFO)
"cannot get disk geometry of `%s'", dev);
# else /* defined(__NetBSD__) */
# else /* defined(HAVE_DIOCGDINFO) */
"cannot get disk label of `%s'", dev);
# endif /* !defined(__NetBSD__) */
# endif /* !defined(HAVE_DIOCGDINFO) */
close (fd);
return 0;
}
close (fd);
# if !defined(__NetBSD__)
# if !defined(HAVE_DIOCGDINFO)
return hdg.start;
# else /* defined(__NetBSD__) */
# else /* defined(HAVE_DIOCGDINFO) */
p_index = dev[strlen(dev) - 1] - 'a';
if (p_index >= label.d_npartitions)
@ -452,9 +462,9 @@ devmapper_fail:
return 0;
}
return (grub_disk_addr_t) label.d_partitions[p_index].p_offset;
# endif /* !defined(__NetBSD__) */
# endif /* !defined(HAVE_DIOCGDINFO) */
}
#endif /* __linux__ || __CYGWIN__ */
#endif /* __linux__ || __CYGWIN__ || HAVE_DIOCGDINFO */
#ifdef __linux__
/* Cache of partition start sectors for each disk. */
@ -956,13 +966,16 @@ read_device_map (const char *dev_map)
#ifdef __linux__
/* On Linux, the devfs uses symbolic links horribly, and that
confuses the interface very much, so use realpath to expand
symbolic links. */
map[drive].device = xmalloc (PATH_MAX);
if (! realpath (p, map[drive].device))
grub_util_error ("cannot get the real path of `%s'", p);
#else
map[drive].device = xstrdup (p);
symbolic links. Leave /dev/mapper/ alone, though. */
if (strncmp (p, "/dev/mapper/", 12) != 0)
{
map[drive].device = xmalloc (PATH_MAX);
if (! realpath (p, map[drive].device))
grub_util_error ("cannot get the real path of `%s'", p);
}
else
#endif
map[drive].device = xstrdup (p);
}
fclose (fp);
@ -994,8 +1007,7 @@ grub_util_biosdisk_fini (void)
/*
* Note: we do not use the new partition naming scheme as dos_part does not
* necessarily correspond to an msdos partition. See e.g. the FreeBSD code
* in function grub_util_biosdisk_get_grub_dev.
* necessarily correspond to an msdos partition.
*/
static char *
make_device_name (int drive, int dos_part, int bsd_part)
@ -1117,6 +1129,16 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
return path;
}
if (strncmp ("md", p, 2) == 0
&& p[2] >= '0' && p[2] <= '9')
{
char *ptr = p + 2;
while (*ptr >= '0' && *ptr <= '9')
ptr++;
*ptr = 0;
return path;
}
/* If this is an IDE, SCSI or Virtio disk. */
if (strncmp ("vdisk", p, 5) == 0
&& p[5] >= 'a' && p[5] <= 'z')
@ -1130,36 +1152,42 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|| strncmp ("sd", p, 2) == 0)
&& p[2] >= 'a' && p[2] <= 'z')
{
/* /dev/[hsv]d[a-z][0-9]* */
p[3] = '\0';
char *pp = p + 2;
while (*pp >= 'a' && *pp <= 'z')
pp++;
/* /dev/[hsv]d[a-z]+[0-9]* */
*pp = '\0';
return path;
}
/* If this is a Xen virtual block device. */
if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z')
{
/* /dev/xvd[a-z][0-9]* */
p[4] = '\0';
char *pp = p + 3;
while (*pp >= 'a' && *pp <= 'z')
pp++;
/* /dev/xvd[a-z]+[0-9]* */
*pp = '\0';
return path;
}
#ifdef HAVE_DEVICE_MAPPER
/* If this is a DM-RAID device. */
if ((strncmp ("mapper/", p, 7) == 0))
/* If this is a DM-RAID device.
Compare os_dev rather than path here, since nodes under
/dev/mapper/ are often symlinks. */
if ((strncmp ("/dev/mapper/", os_dev, 12) == 0))
{
static struct dm_tree *tree = NULL;
struct dm_tree *tree;
uint32_t maj, min;
struct dm_tree_node *node, *child;
struct dm_tree_node *node = NULL, *child;
void *handle;
const char *node_uuid, *mapper_name, *child_uuid, *child_name;
if (! tree)
tree = dm_tree_create ();
const char *node_uuid, *mapper_name = NULL, *child_uuid, *child_name;
tree = dm_tree_create ();
if (! tree)
{
grub_dprintf ("hostdisk", "dm_tree_create failed\n");
return NULL;
goto devmapper_out;
}
maj = major (st->st_rdev);
@ -1167,29 +1195,30 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
if (! dm_tree_add_dev (tree, maj, min))
{
grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n");
return NULL;
goto devmapper_out;
}
node = dm_tree_find_node (tree, maj, min);
if (! node)
{
grub_dprintf ("hostdisk", "dm_tree_find_node failed\n");
return NULL;
goto devmapper_out;
}
node_uuid = dm_tree_node_get_uuid (node);
if (! node_uuid)
{
grub_dprintf ("hostdisk", "%s has no DM uuid\n", path);
return NULL;
node = NULL;
goto devmapper_out;
}
else if (strncmp (node_uuid, "DMRAID-", 7) != 0)
{
grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path);
return NULL;
node = NULL;
goto devmapper_out;
}
handle = NULL;
mapper_name = NULL;
/* Counter-intuitively, device-mapper refers to the disk-like
device containing a DM-RAID partition device as a "child" of
the partition device. */
@ -1219,17 +1248,20 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
mapper_name = child_name;
devmapper_out:
if (! mapper_name)
if (! mapper_name && node)
{
/* This is a DM-RAID disk, not a partition. */
mapper_name = dm_tree_node_get_name (node);
if (! mapper_name)
{
grub_dprintf ("hostdisk", "%s has no DM name\n", path);
return NULL;
}
grub_dprintf ("hostdisk", "%s has no DM name\n", path);
}
return xasprintf ("/dev/mapper/%s", mapper_name);
if (tree)
dm_tree_free (tree);
free (path);
if (mapper_name)
return xasprintf ("/dev/mapper/%s", mapper_name);
else
return NULL;
}
#endif /* HAVE_DEVICE_MAPPER */
}
@ -1333,13 +1365,37 @@ device_is_wholedisk (const char *os_dev)
}
#endif /* defined(__NetBSD__) */
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
static int
find_system_device (const char *os_dev, struct stat *st)
device_is_wholedisk (const char *os_dev)
{
const char *p;
if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0)
return 0;
for (p = os_dev + sizeof ("/dev/") - 1; *p; ++p)
if (grub_isdigit (*p))
{
if (strchr (p, 's'))
return 0;
break;
}
return 1;
}
#endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */
static int
find_system_device (const char *os_dev, struct stat *st, int convert, int add)
{
unsigned int i;
char *os_disk;
os_disk = convert_system_partition_to_system_disk (os_dev, st);
if (convert)
os_disk = convert_system_partition_to_system_disk (os_dev, st);
else
os_disk = xstrdup (os_dev);
if (! os_disk)
return -1;
@ -1352,6 +1408,9 @@ find_system_device (const char *os_dev, struct stat *st)
return i;
}
if (!add)
return -1;
if (i == ARRAY_SIZE (map))
grub_util_error (_("device count exceeds limit"));
@ -1361,6 +1420,17 @@ find_system_device (const char *os_dev, struct stat *st)
return i;
}
int
grub_util_biosdisk_is_present (const char *os_dev)
{
struct stat st;
if (stat (os_dev, &st) < 0)
return 0;
return find_system_device (os_dev, &st, 1, 0) != -1;
}
char *
grub_util_biosdisk_get_grub_dev (const char *os_dev)
{
@ -1373,7 +1443,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return 0;
}
drive = find_system_device (os_dev, &st);
drive = find_system_device (os_dev, &st, 1, 1);
if (drive < 0)
{
grub_error (GRUB_ERR_UNKNOWN_DEVICE,
@ -1392,7 +1462,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
#endif
return make_device_name (drive, -1, -1);
#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__)
#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
/* Linux counts partitions uniformly, whether a BSD partition or a DOS
partition, so mapping them to GRUB devices is not trivial.
Here, get the start sector of a partition by HDIO_GETGEO, and
@ -1402,8 +1472,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
does not count the extended partition and missing primary
partitions. Use same method as on Linux here.
For NetBSD, proceed as for Linux, except that the start sector is
obtained from the disk label. */
For NetBSD and FreeBSD, proceed as for Linux, except that the start
sector is obtained from the disk label. */
{
char *name, *partname;
grub_disk_t disk;
@ -1431,13 +1501,13 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
name = make_device_name (drive, -1, -1);
# if !defined(__NetBSD__)
# if !defined(HAVE_DIOCGDINFO)
if (MAJOR (st.st_rdev) == FLOPPY_MAJOR)
return name;
# else /* defined(__NetBSD__) */
# else /* defined(HAVE_DIOCGDINFO) */
/* Since os_dev and convert_system_partition_to_system_disk (os_dev) are
* different, we know that os_dev cannot be a floppy device. */
# endif /* !defined(__NetBSD__) */
# endif /* !defined(HAVE_DIOCGDINFO) */
start = find_partition_start (os_dev);
if (grub_errno != GRUB_ERR_NONE)
@ -1456,7 +1526,32 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
free (name);
if (! disk)
return 0;
{
/* We already know that the partition exists. Given that we already
checked the device map above, we can only get
GRUB_ERR_UNKNOWN_DEVICE at this point if the disk does not exist.
This can happen on Xen, where disk images in the host can be
assigned to devices that have partition-like names in the guest
but are really more like disks. */
if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE)
{
grub_util_warn
("disk does not exist, so falling back to partition device %s",
os_dev);
drive = find_system_device (os_dev, &st, 0, 1);
if (drive < 0)
{
grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"no mapping exists for `%s'", os_dev);
return 0;
}
return make_device_name (drive, -1, -1);
}
else
return 0;
}
partname = NULL;
grub_partition_iterate (disk, find_partition);
@ -1506,41 +1601,6 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return make_device_name (drive, dos_part, bsd_part);
}
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
/* FreeBSD uses "/dev/[a-z]+[0-9]+([sp][0-9]+[a-z]?)?". */
{
int dos_part = -1;
int bsd_part = -1;
if (strncmp ("/dev/", os_dev, 5) == 0)
{
const char *p;
char *q;
long int n;
for (p = os_dev + 5; *p; ++p)
if (grub_isdigit(*p))
{
p = strpbrk (p, "sp"); /* msdos or apple (or ... ?) partition map */
if (p)
{
p++;
n = strtol (p, &q, 10);
if (p != q && n != GRUB_LONG_MIN && n != GRUB_LONG_MAX)
{
dos_part = (int) n - 1;
if (*q >= 'a' && *q <= 'g')
bsd_part = *q - 'a';
}
}
break;
}
}
return make_device_name (drive, dos_part, bsd_part);
}
#else
# warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly."
return make_device_name (drive, -1, -1);
@ -1552,3 +1612,38 @@ grub_util_biosdisk_get_osdev (grub_disk_t disk)
{
return map[disk->id].device;
}
int
grub_util_biosdisk_is_floppy (grub_disk_t disk)
{
struct stat st;
int fd;
fd = open (map[disk->id].device, O_RDONLY);
/* Shouldn't happen. */
if (fd == -1)
return 0;
/* Shouldn't happen either. */
if (fstat (fd, &st) < 0)
return 0;
#if defined(__NetBSD__)
if (major(st.st_rdev) == RAW_FLOPPY_MAJOR)
return 1;
#endif
#if defined(FLOPPY_MAJOR)
if (major(st.st_rdev) == FLOPPY_MAJOR)
#else
/* Some kernels (e.g. kFreeBSD) don't have a static major number
for floppies, but they still use a "fd[0-9]" pathname. */
if (map[disk->id].device[5] == 'f'
&& map[disk->id].device[6] == 'd'
&& map[disk->id].device[7] >= '0'
&& map[disk->id].device[7] <= '9')
#endif
return 1;
return 0;
}

View file

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

View file

@ -21,7 +21,6 @@
#include <stdlib.h>
#include <setjmp.h>
#include <sys/stat.h>
#include <getopt.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
@ -190,13 +189,16 @@ main (int argc, char *argv[])
grub_emu_init ();
grub_console_init ();
grub_host_init ();
grub_hostfs_init ();
/* XXX: This is a bit unportable. */
grub_util_biosdisk_init (dev_map);
grub_init_all ();
grub_hostfs_init ();
grub_emu_post_init ();
/* Make sure that there is a root device. */
if (! root_dev)
{

View file

@ -16,6 +16,7 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <config.h>
#include <errno.h>
@ -61,6 +62,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
@ -151,7 +161,7 @@ vasprintf (char **buf, const char *fmt, va_list ap)
/* Should be large enough. */
*buf = xmalloc (512);
return vsprintf (*buf, fmt, ap);
return vsnprintf (*buf, 512, fmt, ap);
}
#endif
@ -165,7 +175,7 @@ asprintf (char **buf, const char *fmt, ...)
va_list ap;
va_start (ap, fmt);
status = vasprintf (*buf, fmt, ap);
status = vasprintf (buf, fmt, ap);
va_end (ap);
return status;
@ -282,18 +292,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)
@ -372,6 +416,10 @@ grub_make_system_path_relative_to_its_root (const char *path)
{
free (buf);
free (buf2);
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
if (poolfs)
return xasprintf ("/%s/@", poolfs);
#endif
return xstrdup ("");
}
else

View file

@ -16,6 +16,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/mm.h>

View file

@ -27,6 +27,7 @@
grub_err_t grub_errno;
char grub_errmsg[GRUB_MAX_ERRMSG];
int grub_err_printed_errors;
static struct
{
@ -122,7 +123,10 @@ grub_print_error (void)
do
{
if (grub_errno != GRUB_ERR_NONE)
grub_err_printf (_("error: %s.\n"), grub_errmsg);
{
grub_err_printf (_("error: %s.\n"), grub_errmsg);
grub_err_printed_errors++;
}
}
while (grub_error_pop ());

View file

@ -24,6 +24,9 @@
#include <grub/fs.h>
#include <grub/device.h>
grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX];
grub_file_filter_t grub_file_filters_enabled[GRUB_FILE_FILTER_MAX];
/* Get the device part of the filename NAME. It is enclosed by parentheses. */
char *
grub_file_get_device_name (const char *name)
@ -54,14 +57,15 @@ grub_file_get_device_name (const char *name)
grub_file_t
grub_file_open (const char *name)
{
grub_device_t device;
grub_file_t file = 0;
grub_device_t device = 0;
grub_file_t file = 0, last_file = 0;
char *device_name;
char *file_name;
grub_file_filter_id_t filter;
device_name = grub_file_get_device_name (name);
if (grub_errno)
return 0;
goto fail;
/* Get the file part of NAME. */
file_name = grub_strchr (name, ')');
@ -94,6 +98,19 @@ grub_file_open (const char *name)
if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE)
goto fail;
for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters_enabled);
filter++)
if (grub_file_filters_enabled[filter])
{
last_file = file;
file = grub_file_filters_enabled[filter] (file);
}
if (!file)
grub_file_close (last_file);
grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
sizeof (grub_file_filters_enabled));
return file;
fail:
@ -104,6 +121,9 @@ grub_file_open (const char *name)
grub_free (file);
grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
sizeof (grub_file_filters_enabled));
return 0;
}

View file

@ -21,6 +21,7 @@
#include <grub/machine/time.h>
#include <grub/machine/memory.h>
#include <grub/machine/console.h>
#include <grub/offsets.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/dl.h>
@ -64,8 +65,10 @@ grub_machine_init (void)
/* Initialize the console as early as possible. */
grub_vga_text_init ();
auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t,
grub_memory_type_t);
int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size,
grub_memory_type_t type)
{
#if GRUB_CPU_SIZEOF_VOID_P == 4
/* Restrict ourselves to 32-bit memory space. */
@ -75,7 +78,7 @@ grub_machine_init (void)
size = GRUB_ULONG_MAX - addr;
#endif
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
if (type != GRUB_MEMORY_AVAILABLE)
return 0;
/* Avoid the lower memory. */

View file

@ -17,6 +17,7 @@
*/
#include <grub/machine/memory.h>
#include <grub/machine/lbio.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/misc.h>
@ -74,7 +75,7 @@ signature_found:
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
mem_region_t mem_region;

View file

@ -17,6 +17,8 @@
*/
#include <grub/symbol.h>
/* For stack parameters. */
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
#include <grub/cpu/linux.h>
#include <grub/offsets.h>

View file

@ -17,7 +17,7 @@
*/
#include <grub/symbol.h>
#include <grub/machine/memory.h>
#include <grub/offsets.h>
#include <grub/cpu/linux.h>
#include <multiboot.h>
#include <multiboot2.h>

View file

@ -22,8 +22,6 @@
#include <grub/err.h>
#include <grub/misc.h>
grub_size_t grub_lower_mem, grub_upper_mem;
/* A pointer to the MBI in its initial location. */
struct multiboot_info *startup_multiboot_info;
@ -56,21 +54,10 @@ grub_machine_mmap_init ()
}
grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length);
kern_multiboot_info.mmap_addr = (grub_uint32_t) mmap_entries;
if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEMORY) == 0)
{
grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE;
grub_upper_mem = 0;
}
else
{
grub_lower_mem = kern_multiboot_info.mem_lower * 1024;
grub_upper_mem = kern_multiboot_info.mem_upper * 1024;
}
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
struct multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr;

View file

@ -19,7 +19,7 @@
#include <grub/kernel.h>
#include <grub/mm.h>
#include <grub/machine/boot.h>
#include <grub/machine/init.h>
#include <grub/i386/floppy.h>
#include <grub/machine/memory.h>
#include <grub/machine/console.h>
#include <grub/machine/kernel.h>
@ -171,11 +171,6 @@ grub_machine_init (void)
if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
grub_fatal ("too small memory");
#if 0
/* Turn on Gate A20 to access >1MB. */
grub_gate_a20 (1);
#endif
/* FIXME: This prevents loader/i386/linux.c from using low memory. When our
heap implements support for requesting a chunk in low memory, this should
no longer be a problem. */
@ -186,8 +181,10 @@ grub_machine_init (void)
grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
#endif
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
grub_memory_type_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
grub_memory_type_t type)
{
/* Avoid the lower memory. */
if (addr < 0x100000)
@ -200,7 +197,7 @@ grub_machine_init (void)
}
/* Ignore >4GB. */
if (addr <= 0xFFFFFFFF && type == GRUB_MACHINE_MEMORY_AVAILABLE)
if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE)
{
grub_size_t len;

View file

@ -77,69 +77,6 @@
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if 0
DbgOut:
pushf
pushl %ebp
pushl %edi
pushl %esi
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
call _DebugPrint
popl %eax
popl %ebx
popl %ecx
popl %edx
popl %esi
popl %edi
popl %ebp
popf
ret
/*
* int LzmaDecodeProperties(CLzmaProperties *propsRes,
* const unsigned char *propsData,
* int size);
*/
_LzmaDecodePropertiesA:
movb (%edx), %dl
xorl %ecx, %ecx
1:
cmpb $45, %dl
jb 2f
incl %ecx
subb $45, %dl
jmp 1b
2:
movl %ecx, 8(%eax) /* pb */
xorl %ecx, %ecx
1:
cmpb $9, %dl
jb 2f
incl %ecx
subb $9, %dl
2:
movl %ecx, 4(%eax) /* lp */
movb %dl, %cl
movl %ecx, (%eax) /* lc */
#endif
#ifndef ASM_FILE
xorl %eax, %eax
#endif
ret
#define out_size 8(%ebp)
#define now_pos -4(%ebp)

View file

@ -16,13 +16,26 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/machine/init.h>
#include <grub/machine/int.h>
#include <grub/machine/memory.h>
#include <grub/machine/int.h>
#include <grub/err.h>
#include <grub/types.h>
#include <grub/misc.h>
struct grub_machine_mmap_entry
{
grub_uint32_t size;
grub_uint64_t addr;
grub_uint64_t len;
#define GRUB_MACHINE_MEMORY_AVAILABLE 1
#define GRUB_MACHINE_MEMORY_RESERVED 2
#define GRUB_MACHINE_MEMORY_ACPI 3
#define GRUB_MACHINE_MEMORY_NVS 4
#define GRUB_MACHINE_MEMORY_BADRAM 5
grub_uint32_t type;
} __attribute__((packed));
/*
* grub_get_ext_memsize() : return the extended memory size in KB.
* BIOS call "INT 15H, AH=88H" to get extended memory size
@ -110,7 +123,7 @@ grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
grub_uint32_t cont;
struct grub_machine_mmap_entry *entry
@ -125,9 +138,9 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
do
{
if (hook (entry->addr, entry->len,
/* Multiboot mmaps have been defined to match with the E820 definition.
/* GRUB mmaps have been defined to match with the E820 definition.
Therefore, we can just pass type through. */
entry->type))
((entry->type <= GRUB_MACHINE_MEMORY_BADRAM) && (entry->type >= GRUB_MACHINE_MEMORY_AVAILABLE)) ? entry->type : GRUB_MEMORY_RESERVED))
break;
if (! cont)
@ -144,11 +157,12 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
if (eisa_mmap)
{
if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, GRUB_MACHINE_MEMORY_AVAILABLE) == 0)
hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE);
if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10,
GRUB_MEMORY_AVAILABLE) == 0)
hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE);
}
else
hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MACHINE_MEMORY_AVAILABLE);
hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MEMORY_AVAILABLE);
}
return 0;

View file

@ -100,6 +100,8 @@ VARIABLE(grub_install_dos_part)
.long 0xFFFFFFFF
VARIABLE(grub_install_bsd_part)
.long 0xFFFFFFFF
reed_solomon_redundancy:
.long 0
#ifdef APPLE_CC
bss_start:
@ -107,7 +109,56 @@ bss_start:
bss_end:
.long 0
#endif
/*
* This is the area for all of the special variables.
*/
VARIABLE(grub_boot_drive)
.byte 0
/* the real mode code continues... */
LOCAL (codestart):
cli /* we're not safe here! */
/* set up %ds, %ss, and %es */
xorw %ax, %ax
movw %ax, %ds
movw %ax, %ss
movw %ax, %es
/* set up the real mode/BIOS stack */
movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp
movl %ebp, %esp
sti /* we're safe again */
/* save the boot drive */
ADDR32 movb %dl, EXT_C(grub_boot_drive)
/* reset disk system (%ah = 0) */
int $0x13
/* transition to protected mode */
DATA32 call real_to_prot
/* The ".code32" directive takes GAS out of 16-bit mode. */
.code32
incl %eax
call grub_gate_a20
movl EXT_C(grub_compressed_size), %edx
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx
movl reed_solomon_redundancy, %ecx
leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax
call EXT_C (grub_reed_solomon_recover)
jmp post_reed_solomon
#include <rs_decoder.S>
.text
. = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART
/*
* Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
* This uses the a.out kludge to load raw binary to the area starting at 1MB,
@ -171,38 +222,9 @@ multiboot_trampoline:
movb $0xFF, %dh
/* enter the usual booting */
call prot_to_real
.code16
jmp LOCAL (codestart)
/* the real mode code continues... */
LOCAL (codestart):
cli /* we're not safe here! */
/* set up %ds, %ss, and %es */
xorw %ax, %ax
movw %ax, %ds
movw %ax, %ss
movw %ax, %es
/* set up the real mode/BIOS stack */
movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp
movl %ebp, %esp
sti /* we're safe again */
/* save the boot drive */
ADDR32 movb %dl, EXT_C(grub_boot_drive)
/* reset disk system (%ah = 0) */
int $0x13
/* transition to protected mode */
DATA32 call real_to_prot
/* The ".code32" directive takes GAS out of 16-bit mode. */
.code32
incl %eax
call EXT_C(grub_gate_a20)
post_reed_solomon:
#ifdef ENABLE_LZMA
movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
@ -271,15 +293,6 @@ LOCAL (codestart):
*/
call EXT_C(grub_main)
/*
* This is the area for all of the special variables.
*/
VARIABLE(grub_boot_drive)
.byte 0
.p2align 2 /* force 4-byte alignment */
#include "../realmode.S"
/*
@ -292,7 +305,7 @@ VARIABLE(grub_boot_drive)
* It also eats any keystrokes in the keyboard buffer. :-(
*/
FUNCTION(grub_gate_a20)
grub_gate_a20:
movl %eax, %edx
gate_a20_test_current_state:
@ -478,7 +491,7 @@ FUNCTION(grub_chainloader_real_boot)
/* Turn off Gate A20 */
xorl %eax, %eax
call EXT_C(grub_gate_a20)
call grub_gate_a20
/* set up to pass boot drive */
popl %edx
@ -576,64 +589,32 @@ FUNCTION(grub_console_putchar)
ret
LOCAL(bypass_table):
.word 0x011b, 0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r'
.word 0x1c00 | '\n'
LOCAL(bypass_table_end):
/*
* int grub_console_getkey (void)
* if there is a character pending, return it; otherwise return -1
* BIOS call "INT 16H Function 01H" to check whether a character is pending
* Call with %ah = 0x1
* Return:
* If key waiting to be input:
* %ah = keyboard scan code
* %al = ASCII character
* Zero flag = clear
* else
* Zero flag = set
* BIOS call "INT 16H Function 00H" to read character from keyboard
* Call with %ah = 0x0
* Return: %ah = keyboard scan code
* %al = ASCII character
*/
/* this table is used in translate_keycode below */
LOCAL (translation_table):
.word GRUB_CONSOLE_KEY_LEFT, GRUB_TERM_LEFT
.word GRUB_CONSOLE_KEY_RIGHT, GRUB_TERM_RIGHT
.word GRUB_CONSOLE_KEY_UP, GRUB_TERM_UP
.word GRUB_CONSOLE_KEY_DOWN, GRUB_TERM_DOWN
.word GRUB_CONSOLE_KEY_HOME, GRUB_TERM_HOME
.word GRUB_CONSOLE_KEY_END, GRUB_TERM_END
.word GRUB_CONSOLE_KEY_DC, GRUB_TERM_DC
.word GRUB_CONSOLE_KEY_BACKSPACE, GRUB_TERM_BACKSPACE
.word GRUB_CONSOLE_KEY_PPAGE, GRUB_TERM_PPAGE
.word GRUB_CONSOLE_KEY_NPAGE, GRUB_TERM_NPAGE
.word 0
/*
* translate_keycode translates the key code %dx to an ascii code.
*/
.code16
translate_keycode:
pushw %bx
pushw %si
#ifdef __APPLE__
movw $(ABS(LOCAL (translation_table)) - 0x10000), %si
#else
movw $ABS(LOCAL (translation_table)), %si
#endif
1: lodsw
/* check if this is the end */
testw %ax, %ax
jz 2f
/* load the ascii code into %ax */
movw %ax, %bx
lodsw
/* check if this matches the key code */
cmpw %bx, %dx
jne 1b
/* translate %dx, if successful */
movw %ax, %dx
2: popw %si
popw %bx
ret
.code32
FUNCTION(grub_console_getkey)
pushl %ebp
pushl %edi
call prot_to_real
.code16
@ -645,70 +626,56 @@ FUNCTION(grub_console_getkey)
* INT 16/AH = 1 before calling INT 16/AH = 0.
*/
1:
movb $1, %ah
int $0x16
jnz 2f
hlt
jmp 1b
2:
jz notpending
movb $0, %ah
int $0x16
xorl %edx, %edx
movw %ax, %dx /* real_to_prot uses %eax */
call translate_keycode
DATA32 call real_to_prot
.code32
movw %dx, %ax
popl %ebp
ret
/*
* int grub_console_checkkey (void)
* if there is a character pending, return it; otherwise return -1
* BIOS call "INT 16H Function 01H" to check whether a character is pending
* Call with %ah = 0x1
* Return:
* If key waiting to be input:
* %ah = keyboard scan code
* %al = ASCII character
* Zero flag = clear
* else
* Zero flag = set
*/
FUNCTION(grub_console_checkkey)
pushl %ebp
xorl %edx, %edx
call prot_to_real /* enter real mode */
.code16
movb $0x1, %ah
int $0x16
jz notpending
movw %ax, %dx
DATA32 jmp pending
notpending:
decl %edx
pending:
DATA32 call real_to_prot
.code32
movl $0xff, %eax
testl %eax, %edx
jz 1f
andl %edx, %eax
cmpl $0x20, %eax
jae 2f
movl %edx, %eax
leal LOCAL(bypass_table), %edi
movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) >> 1), %ecx
repne scasw
jz 3f
andl $0xff, %eax
addl $(('a' - 1) | GRUB_TERM_CTRL), %eax
jmp 2f
3:
andl $0xff, %eax
jmp 2f
1: movl %edx, %eax
shrl $8, %eax
orl $GRUB_TERM_EXTENDED, %eax
2:
popl %edi
popl %ebp
ret
notpending:
.code16
DATA32 call real_to_prot
.code32
#if GRUB_TERM_NO_KEY != 0
#error Fix this asm code
#endif
jmp 2b
/*
* grub_uint16_t grub_console_getxy (void)
@ -852,6 +819,10 @@ FUNCTION(grub_console_setcursor)
DATA32 call real_to_prot
.code32
cmp %cl, %ch
jb 3f
movw $0x0d0e, %cx
3:
movw %cx, console_cursor_shape
1:
/* set %cx to the designated cursor shape */

View file

@ -16,12 +16,14 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/i386/memory.h>
#include <grub/machine/memory.h>
#include <grub/machine/boot.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/cmos.h>
#include <grub/offsets.h>
#define QEMU_CMOS_MEMSIZE_HIGH 0x35
#define QEMU_CMOS_MEMSIZE_LOW 0x34
@ -60,38 +62,38 @@ grub_machine_mmap_init ()
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
if (hook (0x0,
(grub_addr_t) _start,
GRUB_MACHINE_MEMORY_AVAILABLE))
GRUB_MEMORY_AVAILABLE))
return 1;
if (hook ((grub_addr_t) _end,
0xa0000 - (grub_addr_t) _end,
GRUB_MACHINE_MEMORY_AVAILABLE))
GRUB_MEMORY_AVAILABLE))
return 1;
if (hook (GRUB_MEMORY_MACHINE_UPPER,
0x100000 - GRUB_MEMORY_MACHINE_UPPER,
GRUB_MACHINE_MEMORY_RESERVED))
GRUB_MEMORY_RESERVED))
return 1;
/* Everything else is free. */
if (hook (0x100000,
min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000,
GRUB_MACHINE_MEMORY_AVAILABLE))
GRUB_MEMORY_AVAILABLE))
return 1;
/* Protect boot.img, which contains the gdt. It is mapped at the top of memory
(it is also mapped below 0x100000, but we already reserved that area). */
if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE,
GRUB_BOOT_MACHINE_SIZE,
GRUB_MACHINE_MEMORY_RESERVED))
GRUB_MEMORY_RESERVED))
return 1;
if (above_4g != 0 && hook (0x100000000ULL, above_4g,
GRUB_MACHINE_MEMORY_AVAILABLE))
GRUB_MEMORY_AVAILABLE))
return 1;
return 0;

View file

@ -18,6 +18,8 @@
#include <config.h>
#include <grub/symbol.h>
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
#include <grub/machine/kernel.h>

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

@ -32,6 +32,7 @@
#include <grub/ieee1275/ofdisk.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/offsets.h>
#include <grub/memory.h>
/* The minimal heap size we can live with. */
#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024)
@ -126,8 +127,10 @@ static void grub_claim_heap (void)
{
unsigned long total = 0;
auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type);
int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type)
auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len,
grub_memory_type_t type);
int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len,
grub_memory_type_t type)
{
if (type != 1)
return 0;
@ -189,31 +192,6 @@ static void grub_claim_heap (void)
grub_machine_mmap_iterate (heap_init);
}
#ifdef __i386__
grub_uint32_t grub_upper_mem;
/* We need to call this before grub_claim_memory. */
static void
grub_get_extended_memory (void)
{
auto int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type);
int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type)
{
if (type == 1 && addr == 0x100000)
{
grub_upper_mem = len;
return 1;
}
return 0;
}
grub_machine_mmap_iterate (find_ext_mem);
}
#endif
static grub_uint64_t ieee1275_get_time_ms (void);
void
@ -225,9 +203,6 @@ grub_machine_init (void)
grub_ieee1275_init ();
grub_console_init_early ();
#ifdef __i386__
grub_get_extended_memory ();
#endif
grub_claim_heap ();
grub_console_init_lately ();
grub_ofdisk_init ();

View file

@ -16,12 +16,12 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/machine/memory.h>
#include <grub/memory.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/types.h>
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
grub_ieee1275_phandle_t root;
grub_ieee1275_phandle_t memory;
@ -66,7 +66,7 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
if (size_cells == 2)
size = (size << 32) | available[i++];
if (hook (address, size, GRUB_MACHINE_MEMORY_AVAILABLE))
if (hook (address, size, GRUB_MEMORY_AVAILABLE))
break;
}

View file

@ -423,3 +423,47 @@ grub_reboot (void)
for (;;) ;
}
#endif
/* Resolve aliases. */
char *
grub_ieee1275_canonicalise_devname (const char *path)
{
struct canon_args
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t path;
grub_ieee1275_cell_t buf;
grub_ieee1275_cell_t inlen;
grub_ieee1275_cell_t outlen;
}
args;
char *buf = NULL;
grub_size_t bufsize = 64;
int i;
for (i = 0; i < 2; i++)
{
grub_free (buf);
buf = grub_malloc (bufsize);
if (!buf)
return NULL;
INIT_IEEE1275_COMMON (&args.common, "canon", 3, 1);
args.path = (grub_ieee1275_cell_t) path;
args.buf = (grub_ieee1275_cell_t) buf;
args.inlen = (grub_ieee1275_cell_t) (bufsize - 1);
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
return 0;
if (args.outlen > bufsize - 1)
{
bufsize = args.outlen + 2;
continue;
}
return buf;
}
/* Shouldn't reach here. */
grub_free (buf);
return NULL;
}

View file

@ -1,6 +1,9 @@
#include <grub/symbol.h>
.set noreorder
.set nomacro
FUNCTION (grub_cpu_flush_cache)
FUNCTION (grub_arch_sync_caches)
#include "cache_flush.S"

View file

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

View file

@ -51,11 +51,8 @@ grub_reboot (void)
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint64_t,
grub_uint32_t))
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
hook (0, RAMSIZE,
GRUB_MACHINE_MEMORY_AVAILABLE);
hook (0, RAMSIZE, GRUB_MEMORY_AVAILABLE);
return GRUB_ERR_NONE;
}

View file

@ -22,128 +22,23 @@
#include <grub/machine/memory.h>
#include <grub/offsets.h>
#define BASE_ADDR 8
.extern __bss_start
.extern _end
#define BASE_ADDR 8
.globl __start, _start, start
.set noreorder
.set nomacro
__start:
_start:
start:
bal codestart
base:
. = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
compressed_size:
.long 0
. = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
start:
.extern __bss_start
.extern _end
bal cont
nop
. = _start + GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE
total_module_size:
.long 0
. = _start + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE
kernel_image_size:
.long 0
codestart:
/* Save our base. */
move $s0, $ra
/* Parse arguments. Has to be done before relocation.
So need to do it in asm. */
#ifdef GRUB_MACHINE_MIPS_YEELOONG
move $s2, $zero
move $s3, $zero
move $s4, $zero
move $s5, $zero
/* $a2 has the environment. */
addiu $t0, $a2, 1
beq $t0, $zero, argdone
move $t0, $a2
argcont:
lw $t1, 0($t0)
beq $t1, $zero, argdone
#define DO_PARSE(str, reg) \
addiu $t2, $s0, (str-base);\
bal parsestr;\
beq $v0, $zero, 1f;\
move reg, $v0;\
b 2f;\
1:
DO_PARSE (busclockstr, $s2)
DO_PARSE (cpuclockstr, $s3)
DO_PARSE (memsizestr, $s4)
DO_PARSE (highmemsizestr, $s5)
2:
addiu $t0, $t0, 4
b argcont
parsestr:
move $v0, $zero
move $t3, $t1
3:
lb $t4, 0($t2)
lb $t5, 0($t3)
addiu $t2, $t2, 1
addiu $t3, $t3, 1
beq $t5, $zero, 1f
beq $t5, $t4, 3b
bne $t4, $zero, 1f
addiu $t3, $t3, 0xffff
digcont:
lb $t5, 0($t3)
/* Substract '0' from digit. */
addiu $t5, $t5, 0xffd0
bltz $t5, 1f
addiu $t4, $t5, 0xfff7
bgtz $t4, 1f
/* Multiply $v0 by 10 with bitshifts. */
sll $v0, $v0, 1
sll $t4, $v0, 2
addu $v0, $v0, $t4
addu $v0, $v0, $t5
addiu $t3, $t3, 1
b digcont
1:
jr $ra
busclockstr: .asciiz "busclock="
cpuclockstr: .asciiz "cpuclock="
memsizestr: .asciiz "memsize="
highmemsizestr: .asciiz "highmemsize="
.p2align 2
argdone:
#endif
/* Decompress the payload. */
addiu $a0, $s0, GRUB_KERNEL_MACHINE_RAW_SIZE - BASE_ADDR
lui $a1, %hi(compressed)
addiu $a1, %lo(compressed)
lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
move $s1, $a1
/* $a0 contains source compressed address, $a1 is destination,
$a2 is compressed size. FIXME: put LZMA here. Don't clober $s0,
$s1, $s2, $s3, $s4 and $s5.
On return $v0 contains uncompressed size.
*/
move $v0, $a2
reloccont:
lb $t4, 0($a0)
sb $t4, 0($a1)
addiu $a1,$a1,1
addiu $a0,$a0,1
addiu $a2, 0xffff
bne $a2, $0, reloccont
move $a0, $s1
move $a1, $v0
#include "cache_flush.S"
lui $t1, %hi(cont)
addiu $t1, %lo(cont)
jr $t1
. = _start + GRUB_KERNEL_MACHINE_RAW_SIZE
compressed:
. = _start + GRUB_KERNEL_MACHINE_PREFIX
VARIABLE(grub_prefix)
@ -166,6 +61,8 @@ VARIABLE (grub_arch_highmemsize)
.long 0
#endif
cont:
/* Save our base. */
move $s0, $ra
#ifdef GRUB_MACHINE_MIPS_YEELOONG
lui $t1, %hi(grub_arch_busclock)
@ -177,15 +74,13 @@ cont:
#endif
/* Move the modules out of BSS. */
lui $t1, %hi(_start)
addiu $t1, %lo(_start)
lw $t2, (GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0)
addu $t2, $t1, $t2
lui $t2, %hi(__bss_start)
addiu $t2, %lo(__bss_start)
lui $t1, %hi(_end)
addiu $t1, %lo(_end)
addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1)
li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1)
addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
nor $t3, $t3, $0
and $t1, $t1, $t3
@ -194,33 +89,38 @@ cont:
/* Backward copy. */
add $t1, $t1, $t3
add $t2, $t2, $t3
addiu $t1, $t1, 0xffff
addiu $t2, $t2, 0xffff
addiu $t1, $t1, -1
addiu $t2, $t2, -1
/* $t2 is source. $t1 is destination. $t3 is size. */
modulesmovcont:
beq $t3, $0, modulesmovdone
nop
lb $t4, 0($t2)
sb $t4, 0($t1)
addiu $t1,$t1,0xffff
addiu $t2,$t2,0xffff
addiu $t3, 0xffff
bne $t3, $0, modulesmovcont
addiu $t2, $t2, -1
addiu $t1, $t1, -1
b modulesmovcont
addiu $t3, $t3, -1
modulesmovdone:
/* Clean BSS. */
lui $t1, %hi(__bss_start)
addiu $t1, %lo(__bss_start)
addiu $t1, $t1, %lo(__bss_start)
lui $t2, %hi(_end)
addiu $t2, %lo(_end)
addiu $t2, $t2, %lo(_end)
bsscont:
sb $0,0($t1)
addiu $t1,$t1,1
sltu $t3,$t1,$t2
addiu $t1, $t1, 1
sltu $t3, $t1, $t2
bne $t3, $0, bsscont
nop
li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH
lui $t1, %hi(grub_main)
addiu $t1, %lo(grub_main)
lui $sp, %hi(GRUB_MACHINE_MEMORY_STACK_HIGH)
jr $t1
addiu $sp, $sp, %lo(GRUB_MACHINE_MEMORY_STACK_HIGH)

View file

@ -26,6 +26,7 @@
#include <grub/time.h>
#include <grub/machine/kernel.h>
#include <grub/machine/memory.h>
#include <grub/memory.h>
#include <grub/mips/loongson.h>
#include <grub/cs5536.h>
#include <grub/term.h>
@ -39,6 +40,7 @@ extern void grub_gfxterm_init (void);
extern void grub_at_keyboard_init (void);
extern void grub_serial_init (void);
extern void grub_terminfo_init (void);
extern void grub_keylayouts_init (void);
/* FIXME: use interrupt to count high. */
grub_uint64_t
@ -57,14 +59,12 @@ grub_get_rtc (void)
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint64_t,
grub_uint32_t))
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20,
GRUB_MACHINE_MEMORY_AVAILABLE);
GRUB_MEMORY_AVAILABLE);
hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20,
GRUB_MACHINE_MEMORY_AVAILABLE);
GRUB_MEMORY_AVAILABLE);
return GRUB_ERR_NONE;
}
@ -205,6 +205,7 @@ grub_machine_init (void)
grub_font_init ();
grub_gfxterm_init ();
grub_keylayouts_init ();
grub_at_keyboard_init ();
grub_terminfo_init ();
@ -222,6 +223,8 @@ grub_halt (void)
grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG)
& ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG);
grub_millisleep (1500);
grub_printf ("Shutdown failed\n");
grub_refresh ();
while (1);
@ -238,6 +241,8 @@ grub_reboot (void)
{
grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT);
grub_millisleep (1500);
grub_printf ("Reboot failed\n");
grub_refresh ();
while (1);

View file

@ -196,6 +196,8 @@ grub_vprintf (const char *fmt, va_list args)
grub_size_t s;
static char buf[PREALLOC_SIZE + 1];
char *curbuf = buf;
va_list ap2;
va_copy (ap2, args);
s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, args);
if (s > PREALLOC_SIZE)
@ -210,7 +212,7 @@ grub_vprintf (const char *fmt, va_list args)
buf[PREALLOC_SIZE] = 0;
}
else
s = grub_vsnprintf_real (curbuf, s, fmt, args);
s = grub_vsnprintf_real (curbuf, s, fmt, ap2);
}
grub_xputs (curbuf);
@ -947,11 +949,13 @@ grub_xvasprintf (const char *fmt, va_list ap)
while (1)
{
va_list ap2;
va_copy (ap2, ap);
ret = grub_malloc (as + 1);
if (!ret)
return NULL;
s = grub_vsnprintf_real (ret, as, fmt, ap);
s = grub_vsnprintf_real (ret, as, fmt, ap2);
if (s <= as)
return ret;
@ -995,7 +999,7 @@ grub_abort (void)
void abort (void) __attribute__ ((alias ("grub_abort")));
#endif
#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU)
#if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU)
/* Some gcc versions generate a call to this function
in trampolines for nested functions. */
void __enable_execute_stack (void *addr __attribute__ ((unused)))
@ -1003,7 +1007,7 @@ void __enable_execute_stack (void *addr __attribute__ ((unused)))
}
#endif
#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL)
#if NEED_REGISTER_FRAME_INFO && !defined(GRUB_UTIL)
void __register_frame_info (void)
{
}

View file

@ -39,7 +39,7 @@ grub_rescue_read_line (char **line, int cont)
grub_printf ((cont) ? "> " : "grub rescue> ");
grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE);
while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r')
while ((c = grub_getkey ()) != '\n' && c != '\r')
{
if (grub_isprint (c))
{

View file

@ -61,9 +61,11 @@ codestart:
/* Save ieee1275 stack for future use by booter. */
mov %o6, %o1
/* Our future stack. */
sethi %hi(GRUB_KERNEL_MACHINE_STACK_SIZE - 2047), %o5
or %o5, %lo(GRUB_KERNEL_MACHINE_STACK_SIZE - 2047), %o5
sethi %hi(GRUB_KERNEL_MACHINE_STACK_SIZE), %o5
or %o5, %lo(GRUB_KERNEL_MACHINE_STACK_SIZE), %o5
add %o3, %o5, %o6
and %o6, ~0xff, %o6
sub %o6, 2047, %o6
sub %o2, 4, %o2
sub %o3, 4, %o3

View file

@ -78,65 +78,48 @@ grub_xputs_dumb (const char *str)
void (*grub_xputs) (const char *str) = grub_xputs_dumb;
int
grub_getkey (void)
{
grub_term_input_t term;
grub_refresh ();
while (1)
{
if (grub_term_poll_usb)
grub_term_poll_usb ();
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey (term);
if (key != -1)
return term->getkey (term);
}
grub_cpu_idle ();
}
}
static int pending_key = GRUB_TERM_NO_KEY;
int
grub_checkkey (void)
{
grub_term_input_t term;
if (pending_key != GRUB_TERM_NO_KEY)
return pending_key;
if (grub_term_poll_usb)
grub_term_poll_usb ();
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey (term);
if (key != -1)
return key;
pending_key = term->getkey (term);
if (pending_key != GRUB_TERM_NO_KEY)
return pending_key;
}
return -1;
}
int
grub_getkeystatus (void)
grub_getkey (void)
{
int status = 0;
grub_term_input_t term;
int ret;
if (grub_term_poll_usb)
grub_term_poll_usb ();
grub_refresh ();
FOR_ACTIVE_TERM_INPUTS(term)
{
if (term->getkeystatus)
status |= term->getkeystatus (term);
}
return status;
grub_checkkey ();
while (pending_key == GRUB_TERM_NO_KEY)
{
grub_cpu_idle ();
grub_checkkey ();
}
ret = pending_key;
pending_key = GRUB_TERM_NO_KEY;
return ret;
}
void
grub_refresh (void)
{