144 lines
4.1 KiB
C++
144 lines
4.1 KiB
C++
/**
|
|
* \brief GRUB multi-boot information handling
|
|
* \author Christian Helmuth
|
|
* \date 2006-05-10
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2006-2013 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
#include <base/printf.h>
|
|
#include <multiboot.h>
|
|
#include <util/misc_math.h>
|
|
|
|
using namespace Genode;
|
|
|
|
namespace Mb_info {
|
|
#include "mb_info.h"
|
|
}
|
|
|
|
|
|
static const bool verbose = false;
|
|
|
|
|
|
void Multiboot_info::print_debug()
|
|
{
|
|
Mb_info::mb_info_t *mbi = (Mb_info::mb_info_t *)_mb_info;
|
|
|
|
printf(" flags = %x %s\n", mbi->flags,
|
|
mbi->flags & MB_CMDLINE ? "CMDLINE" : "");
|
|
printf(" mem_lower = %xu\n", mbi->mem_lower);
|
|
printf(" mem_upper = %xu\n", mbi->mem_upper);
|
|
printf(" boot_device = %x\n", mbi->boot_device);
|
|
// printf(" cmdline = %08p \"%s\"\n", mbi->cmdline, (char *)mbi->cmdline);
|
|
printf(" mods_count = %d\n", mbi->mods_count);
|
|
printf(" mods_addr = %xu\n", mbi->mods_addr);
|
|
|
|
unsigned i = 0;
|
|
Mb_info::mb_mod_t *mods = reinterpret_cast<Mb_info::mb_mod_t*>(mbi->mods_addr);
|
|
for (i = 0; i < mbi->mods_count; i++)
|
|
printf(" mod[%02d] [%xu,%xu) %s\n", i,
|
|
mods[i].mod_start, (mods[i].mod_end),
|
|
reinterpret_cast<char*>(mods[i].cmdline));
|
|
|
|
printf(" mmap_length = %x\n", mbi->mmap_length);
|
|
printf(" mmap_addr = %x\n", mbi->mmap_addr);
|
|
printf(" drives_length = %x\n", mbi->drives_length);
|
|
printf(" drives_addr = %x\n", mbi->drives_addr);
|
|
printf(" config_table = %x\n", mbi->config_table);
|
|
printf(" boot_loader_name = %x\n", mbi->boot_loader_name);
|
|
printf(" apm_table = %x\n", mbi->apm_table);
|
|
printf(" vbe_ctrl_info = %xu\n", mbi->vbe_ctrl_info);
|
|
printf(" vbe_mode_info = %xu\n", mbi->vbe_mode_info);
|
|
printf(" vbe_mode = %x\n", mbi->vbe_mode);
|
|
printf(" vbe_interface_seg = %x\n", mbi->vbe_interface_seg);
|
|
printf(" vbe_interface_off = %x\n", mbi->vbe_interface_off);
|
|
printf(" vbe_interface_len = %x\n", mbi->vbe_interface_len);
|
|
}
|
|
|
|
|
|
unsigned Multiboot_info::num_modules()
|
|
{
|
|
Mb_info::mb_info_t *mbi = (Mb_info::mb_info_t *)_mb_info;
|
|
|
|
return mbi->mods_count;
|
|
}
|
|
|
|
|
|
Rom_module Multiboot_info::get_module(unsigned num)
|
|
{
|
|
Mb_info::mb_info_t *mbi = reinterpret_cast<Mb_info::mb_info_t*>(_mb_info);
|
|
Mb_info::mb_mod_t *mods = reinterpret_cast<Mb_info::mb_mod_t*>(mbi->mods_addr);
|
|
|
|
/* num exceeds number of modules */
|
|
if (!(num < mbi->mods_count)) return Rom_module();
|
|
|
|
/* invalid module -- maybe returned earlier */
|
|
if (!mods[num].cmdline) return Rom_module();
|
|
|
|
char *cmdline = reinterpret_cast<char*>(mods[num].cmdline);
|
|
|
|
/* skip everything in front of the base name of the file */
|
|
for (unsigned i = 0; cmdline[i]; i++) {
|
|
|
|
if (cmdline[i] != '/') continue;
|
|
|
|
/*
|
|
* If we detect the end of a directory name, take the
|
|
* next character as the start of the command line
|
|
*/
|
|
cmdline = cmdline + i + 1;
|
|
i = 0;
|
|
}
|
|
|
|
Rom_module ret = Rom_module(mods[num].mod_start,
|
|
mods[num].mod_end - mods[num].mod_start,
|
|
cmdline);
|
|
|
|
/* mark module as invalid */
|
|
mods[num].cmdline = 0;
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
bool Multiboot_info::check_module(unsigned num, addr_t *start, addr_t *end)
|
|
{
|
|
Mb_info::mb_info_t *mbi = reinterpret_cast<Mb_info::mb_info_t*>(_mb_info);
|
|
Mb_info::mb_mod_t *mods = reinterpret_cast<Mb_info::mb_mod_t*>(mbi->mods_addr);
|
|
|
|
/* num exceeds number of modules */
|
|
if (!(num < mbi->mods_count)) return false;
|
|
|
|
*start = mods[num].mod_start;
|
|
*end = mods[num].mod_end;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
Multiboot_info::Multiboot_info(void *mb_info)
|
|
: _mb_info(mb_info)
|
|
{
|
|
Mb_info::mb_info_t *mbi = reinterpret_cast<Mb_info::mb_info_t*>(_mb_info);
|
|
Mb_info::mb_mod_t *mods = reinterpret_cast<Mb_info::mb_mod_t*>(mbi->mods_addr);
|
|
|
|
/* strip path and arguments from module name */
|
|
for (unsigned i = 0; i < mbi->mods_count; i++) {
|
|
char *cmdline = reinterpret_cast<char*>(mods[i].cmdline);
|
|
mods[i].cmdline = (addr_t)commandline_to_basename(cmdline);
|
|
}
|
|
|
|
if (verbose) {
|
|
printf("Multi-boot info with %d modules @ %p.\n",
|
|
mbi->mods_count, _mb_info);
|
|
print_debug();
|
|
}
|
|
}
|