/* multiboot.c - boot a multiboot OS image. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* 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/>.
*/
/*
* FIXME: The following features from the Multiboot specification still
* need to be implemented:
* - drives table
* - ROM configuration table
* - SMBIOS tables
* - Networking information
*/
#include <grub/multiboot.h>
GRUB_MOD_LICENSE ("GPLv3+");
#ifdef GRUB_MACHINE_EFI
#endif
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
#else
#endif
static int accepts_video;
static int accepts_ega_text;
static int console_required;
/* Return the length of the Multiboot mmap that will be needed to allocate
our platform's map. */
{
{
count++;
return 0;
}
return count;
}
{
const char *modevar;
if (accepts_video || !GRUB_MACHINE_HAS_VGA_TEXT)
{
else
{
char *tmp;
if (! tmp)
return grub_errno;
}
}
else
return err;
}
static grub_err_t
grub_multiboot_boot (void)
{
/* finish_boot_services is now called from make_mbi */
if (err)
return err;
/* Not reached. */
return GRUB_ERR_NONE;
}
static grub_err_t
grub_multiboot_unload (void)
{
return GRUB_ERR_NONE;
}
#define MULTIBOOT_LOAD_ELF64
#include "multiboot_elfxx.c"
#define MULTIBOOT_LOAD_ELF32
#include "multiboot_elfxx.c"
/* Load ELF32 or ELF64. */
{
if (grub_multiboot_is_elf32 (buffer))
else if (grub_multiboot_is_elf64 (buffer))
}
int console_req)
{
if (!(accepted_consoles
| (GRUB_MACHINE_HAS_VGA_TEXT ? GRUB_MULTIBOOT_CONSOLE_EGA_TEXT : 0))))
{
if (console_required)
return grub_error (GRUB_ERR_BAD_OS,
"OS requires a console but none is available");
accepts_video = 0;
accepts_ega_text = 0;
return GRUB_ERR_NONE;
}
{
char *buf;
else
if (!buf)
return grub_errno;
}
else
return GRUB_ERR_NONE;
}
static grub_err_t
{
if (argc == 0)
grub_print_progress = 1;
if (! file)
return grub_errno;
/* Skip filename. */
if (!grub_multiboot_relocator)
goto fail;
if (err)
goto fail;
fail:
if (file)
if (grub_errno != GRUB_ERR_NONE)
{
}
return grub_errno;
}
static grub_err_t
{
int nounzip = 0;
const char *sizeenv;
if (argc == 0)
{
argv++;
argc--;
nounzip = 1;
}
if (argc == 0)
if (!grub_multiboot_relocator)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"you need to load the multiboot kernel first");
if (nounzip)
else
/* Provide a way for a user to override the guess, just in case
our guess is wrong */
{
}
else if (sizeenv)
{
user_size = 0;
}
grub_print_progress = 1;
if (! file)
return grub_errno;
{
if (user_size > 0)
else
}
else
{
(unsigned long long) user_size,
(unsigned long long) size);
if (err)
{
return err;
}
}
/* If file size is approximate, assume there's no error if the
read_size differs from the size */
{
if (!grub_errno)
argv[0]);
return grub_errno;
}
/* XXX -- Need to handle the case when our guess of the file size was
wrong. In that case, keep reading from the file until the end and
get the real file size, then free the relocator chunk and do the
whole thing all over again, this time with the right size. */
if (file->is_size_approximate)
{
char buf;
if (more > 0)
{
residual = 1;
{
}
if (!grub_errno && more > 0)
else if (grub_errno)
}
if (residual > 0)
{
return grub_error(GRUB_ERR_OUT_OF_MEMORY,
"The module was not fully read because the buffer that was \n"
"preallocated was too small (the full size was unknown at file-open\n"
"time). Set the `multiboot_module_alloc' env var to `%llu' or\n"
"`auto' before the module command",
(unsigned long long)read_size);
}
}
if (err)
{
return err;
}
return GRUB_ERR_NONE;;
}
{
#ifdef GRUB_USE_MULTIBOOT2
0, N_("Load a multiboot 2 kernel."));
0, N_("Load a multiboot 2 module."));
#else
0, N_("Load a multiboot kernel."));
0, N_("Load a multiboot module."));
#endif
}
{
}