diff --git a/repos/base-fiasco/src/core/platform.cc b/repos/base-fiasco/src/core/platform.cc
index 66652379ac..2f7f1e1805 100644
--- a/repos/base-fiasco/src/core/platform.cc
+++ b/repos/base-fiasco/src/core/platform.cc
@@ -321,7 +321,7 @@ void Platform::_setup_irq_alloc() {
 	_irq_alloc.add_range(0, 0x10); }
 
 
-void Platform::_setup_basics()
+static Fiasco::l4_kernel_info_t *get_kip()
 {
 	using namespace Fiasco;
 
@@ -370,14 +370,22 @@ void Platform::_setup_basics()
 		printf("           root "); printf(" esp: %08lx  eip: %08lx\n", kip->root_esp, kip->root_eip);
 	}
 
+	return kip;
+}
+
+void Platform::_setup_basics()
+{
+	using namespace Fiasco;
+
+	l4_kernel_info_t * kip = get_kip();
+
 	/* add KIP as ROM module */
 	_kip_rom = Rom_module((addr_t)kip, L4_PAGESIZE, "l4v2_kip");
 	_rom_fs.insert(&_kip_rom);
 
 	/* update multi-boot info pointer from KIP */
-	void *mb_info_ptr = (void *)kip->user_ptr;
-	_mb_info = Multiboot_info(mb_info_ptr);
-	if (verbose) printf("MBI @ %p\n", mb_info_ptr);
+	addr_t mb_info_addr = kip->user_ptr;
+	if (verbose) printf("MBI @ 0x%lx\n", mb_info_addr);
 
 	/* parse memory descriptors - look for virtual memory configuration */
 	/* XXX we support only one VM region (here and also inside RM) */
@@ -412,8 +420,8 @@ void Platform::_setup_basics()
 	/* remove KIP and MBI area from region and IO_MEM allocator */
 	remove_region(Region((addr_t)kip, (addr_t)kip + L4_PAGESIZE), _region_alloc);
 	remove_region(Region((addr_t)kip, (addr_t)kip + L4_PAGESIZE), _io_mem_alloc);
-	remove_region(Region((addr_t)mb_info_ptr, (addr_t)mb_info_ptr + _mb_info.size()), _region_alloc);
-	remove_region(Region((addr_t)mb_info_ptr, (addr_t)mb_info_ptr + _mb_info.size()), _io_mem_alloc);
+	remove_region(Region(mb_info_addr, mb_info_addr + _mb_info.size()), _region_alloc);
+	remove_region(Region(mb_info_addr, mb_info_addr + _mb_info.size()), _io_mem_alloc);
 
 	/* remove core program image memory from region and IO_MEM allocator */
 	addr_t img_start = (addr_t) &_prog_img_beg;
@@ -459,7 +467,8 @@ void Platform::_setup_rom()
 Platform::Platform() :
 	_ram_alloc(nullptr), _io_mem_alloc(core_mem_alloc()),
 	_io_port_alloc(core_mem_alloc()), _irq_alloc(core_mem_alloc()),
-	_region_alloc(core_mem_alloc())
+	_region_alloc(core_mem_alloc()),
+	_mb_info(get_kip()->user_ptr, true)
 {
 	/*
 	 * We must be single-threaded at this stage and so this is safe.
diff --git a/repos/base-foc/src/core/platform.cc b/repos/base-foc/src/core/platform.cc
index a37f4d7bd7..59fb31ed62 100644
--- a/repos/base-foc/src/core/platform.cc
+++ b/repos/base-foc/src/core/platform.cc
@@ -282,6 +282,10 @@ static Fiasco::l4_kernel_info_t *sigma0_map_kip()
 		return 0;
 
 	l4_addr_t ret = l4_trunc_page(l4_utcb_mr()->mr[0]);
+
+	if (!ret)
+		panic("kip mapping failed");
+
 	return (l4_kernel_info_t*) ret;
 }
 
@@ -352,8 +356,6 @@ void Platform::_setup_basics()
 	using namespace Fiasco;
 
 	kip = sigma0_map_kip();
-	if (!kip)
-		panic("kip mapping failed");
 
 	if (kip->magic != L4_KERNEL_INFO_MAGIC)
 		panic("Sigma0 mapped something but not the KIP");
@@ -373,9 +375,8 @@ void Platform::_setup_basics()
 	_rom_fs.insert(&_kip_rom);
 
 	/* update multi-boot info pointer from KIP */
-	void *mb_info_ptr = (void *)kip->user_ptr;
-	_mb_info = Multiboot_info(mb_info_ptr);
-	if (verbose) printf("MBI @ %p\n", mb_info_ptr);
+	addr_t mb_info_addr = kip->user_ptr;
+	if (verbose) printf("MBI @ %lx\n", mb_info_addr);
 
 	/* parse memory descriptors - look for virtual memory configuration */
 	/* XXX we support only one VM region (here and also inside RM) */
@@ -413,8 +414,8 @@ void Platform::_setup_basics()
 	/* remove KIP and MBI area from region and IO_MEM allocator */
 	remove_region(Region((addr_t)kip, (addr_t)kip + L4_PAGESIZE), _region_alloc);
 	remove_region(Region((addr_t)kip, (addr_t)kip + L4_PAGESIZE), _io_mem_alloc);
-	remove_region(Region((addr_t)mb_info_ptr, (addr_t)mb_info_ptr + _mb_info.size()), _region_alloc);
-	remove_region(Region((addr_t)mb_info_ptr, (addr_t)mb_info_ptr + _mb_info.size()), _io_mem_alloc);
+	remove_region(Region(mb_info_addr, mb_info_addr + _mb_info.size()), _region_alloc);
+	remove_region(Region(mb_info_addr, mb_info_addr + _mb_info.size()), _io_mem_alloc);
 
 	/* remove core program image memory from region and IO_MEM allocator */
 	addr_t img_start = (addr_t) &_prog_img_beg;
@@ -468,6 +469,7 @@ Platform::Platform() :
 	_ram_alloc(nullptr), _io_mem_alloc(core_mem_alloc()),
 	_io_port_alloc(core_mem_alloc()), _irq_alloc(core_mem_alloc()),
 	_region_alloc(core_mem_alloc()), _cap_id_alloc(core_mem_alloc()),
+	_mb_info(sigma0_map_kip()->user_ptr, true),
 	_sigma0(cap_map()->insert(_cap_id_alloc.alloc(), Fiasco::L4_BASE_PAGER_CAP))
 {
 	/*
diff --git a/repos/base-pistachio/src/core/multiboot_info.cc b/repos/base-pistachio/src/core/multiboot_info.cc
index 09bf8e54c8..a30bcb3825 100644
--- a/repos/base-pistachio/src/core/multiboot_info.cc
+++ b/repos/base-pistachio/src/core/multiboot_info.cc
@@ -35,12 +35,6 @@ static const bool verbose = false;
 #define VPRINTF(fmt...) if (verbose) printf(fmt); else {}
 
 
-void Multiboot_info::print_debug()
-{
-	printf("TODO Multiboot_info does not support print_debug.");
-}
-
-
 unsigned Multiboot_info::num_modules()
 {
 	using namespace Pistachio;
@@ -48,8 +42,8 @@ unsigned Multiboot_info::num_modules()
 	unsigned int i = 0;
 	L4_Word_t entries;
 	L4_BootRec_t *rec;
-	for (entries = L4_BootInfo_Entries(_mb_info),
-	     rec = L4_BootInfo_FirstEntry(_mb_info);
+	for (entries = L4_BootInfo_Entries(reinterpret_cast<void *>(Mmio::base)),
+	     rec = L4_BootInfo_FirstEntry(reinterpret_cast<void *>(Mmio::base));
 	     entries > 0;
 	     entries--, rec = L4_Next(rec))
 	{
@@ -71,8 +65,8 @@ Rom_module Multiboot_info::get_module(unsigned num)
 	unsigned int i = 0;
 	L4_Word_t entries;
 	L4_BootRec_t *rec;
-	for (entries = L4_BootInfo_Entries(_mb_info),
-	     rec = L4_BootInfo_FirstEntry(_mb_info);
+	for (entries = L4_BootInfo_Entries(reinterpret_cast<void *>(Mmio::base)),
+	     rec = L4_BootInfo_FirstEntry(reinterpret_cast<void *>(Mmio::base));
 	     entries > 0;
 	     entries--, rec = L4_Next(rec))
 	{
@@ -116,47 +110,3 @@ Rom_module Multiboot_info::get_module(unsigned num)
 	Rom_module ret = Rom_module(start, size, name);
 	return ret;
 }
-
-
-bool Multiboot_info::check_module(unsigned num, addr_t *start, addr_t *end)
-{
-	panic("TODO Who calls check_module?");
-	return false;
-}
-
-
-Multiboot_info::Multiboot_info(void *mb_info)
-: _mb_info(mb_info)
-{
-	using namespace Pistachio;
-
-	if (!L4_BootInfo_Valid(mb_info))
-		panic("Invalid BootInfo.");
-
-	/* some debug info, can probably be removed */
-	unsigned int i;
-	L4_Word_t entries;
-	L4_BootRec_t *rec;
-	for (entries = L4_BootInfo_Entries(mb_info),
-	     rec = L4_BootInfo_FirstEntry(mb_info),
-	     i = 0;
-	     entries > 0;
-	     entries--, i++, rec = L4_Next(rec)) {
-
-		VPRINTF("Entry[%d]\n", i);
-		switch (L4_Type(rec)) {
-		case L4_BootInfo_Module:
-			VPRINTF(" Type: Module\n");
-			VPRINTF(" Cmd : %s\n", L4_Module_Cmdline(rec));
-			break;
-		case L4_BootInfo_SimpleExec:
-			VPRINTF(" Type: SimpleExec (ignored)\n");
-			VPRINTF(" Cmd : %s\n", L4_SimpleExec_Cmdline(rec));
-			break;
-		case L4_BootInfo_EFITables:
-			VPRINTF(" Type: EFITables (ignored)\n"); break;
-		case L4_BootInfo_Multiboot:
-			VPRINTF(" Type: Multiboot (ignored)\n"); break;
-		}
-	}
-}
diff --git a/repos/base-pistachio/src/core/platform.cc b/repos/base-pistachio/src/core/platform.cc
index 43e06e1dae..b11650042b 100644
--- a/repos/base-pistachio/src/core/platform.cc
+++ b/repos/base-pistachio/src/core/platform.cc
@@ -466,15 +466,23 @@ void Platform::_setup_preemption()
 }
 
 
-void Platform::_setup_basics()
+static Pistachio::L4_KernelInterfacePage_t *init_kip()
 {
 	using namespace Pistachio;
 
 	/* completely map program image */
 	addr_t beg = trunc_page((addr_t)&_prog_img_beg);
 	addr_t end = round_page((addr_t)&_prog_img_end);
-	for ( ; beg < end; beg += get_page_size())
-		L4_Sigma0_GetPage(get_sigma0(), L4_Fpage(beg, get_page_size()));
+	for ( ; beg < end; beg += Pistachio::get_page_size())
+		L4_Sigma0_GetPage(get_sigma0(), L4_Fpage(beg, Pistachio::get_page_size()));
+
+	return get_kip();
+}
+
+
+void Platform::_setup_basics()
+{
+	using namespace Pistachio;
 
 	/* store mapping base from received mapping */
 	L4_KernelInterfacePage_t *kip = get_kip();
@@ -515,7 +523,6 @@ void Platform::_setup_basics()
 
 	/* done magic */
 
-	_mb_info = Multiboot_info(mb_info_ptr);
 	if (verbose) printf("MBI @ %p\n", mb_info_ptr);
 
 	/* get UTCB memory */
@@ -627,7 +634,8 @@ Platform_pd *Platform::core_pd()
 Platform::Platform() :
 	_ram_alloc(nullptr), _io_mem_alloc(core_mem_alloc()),
 	_io_port_alloc(core_mem_alloc()), _irq_alloc(core_mem_alloc()),
-	_region_alloc(core_mem_alloc())
+	_region_alloc(core_mem_alloc()),
+	_mb_info(init_kip()->BootInfo)
 {
 	/*
 	 * We must be single-threaded at this stage and so this is safe.
diff --git a/repos/base/src/core/include/multiboot.h b/repos/base/src/core/include/multiboot.h
index c1edb77194..8d7cc29ae2 100644
--- a/repos/base/src/core/include/multiboot.h
+++ b/repos/base/src/core/include/multiboot.h
@@ -1,11 +1,12 @@
-/**
- * \brief  GRUB multi-boot information handling
+/*
+ * \brief  Multiboot handling
  * \author Christian Helmuth
+ * \author Alexander Boettcher
  * \date   2006-05-09
  */
 
 /*
- * Copyright (C) 2006-2013 Genode Labs GmbH
+ * Copyright (C) 2006-2015 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.
@@ -14,56 +15,78 @@
 #ifndef _CORE__INCLUDE__MULTIBOOT_H_
 #define _CORE__INCLUDE__MULTIBOOT_H_
 
+/* base includes */
+#include <util/mmio.h>
+
+/* core includes */
 #include <rom_fs.h>
 
-#include <base/stdint.h>
+namespace Genode { class Multiboot_info; }
 
-namespace Genode {
+class Genode::Multiboot_info : Mmio
+{
+	private:
 
-	class Multiboot_info
-	{
-		private:
+		struct Flags      : Register<0x00, 32> {
+			struct Mem_map : Bitfield<6, 1> { };
+		};
+		struct Mods_count : Register<0x14, 32> { };
+		struct Mods_addr  : Register<0x18, 32> { };
 
-			/* Location of MBI in memory */
-			void *_mb_info;
+		struct Mmap_length: Register<0x2c, 32> { };
+		struct Mmap_addr  : Register<0x30, 32> { };
 
-		public:
+	public:
 
-			/** Standard constructor creates invalid object */
-			Multiboot_info() : _mb_info(0) { }
+		Multiboot_info(addr_t mbi) : Mmio(mbi) { }
+		Multiboot_info(addr_t mbi, bool strip);
 
-			Multiboot_info(void *mb_info);
+		struct Mmap : Genode::Mmio {
+			struct Size   : Register <0x00, 32> { };
+			struct Addr   : Register <0x04, 64> { };
+			struct Length : Register <0x0c, 64> { };
+			struct Type   : Register <0x14,  8> {
+				struct Memory   : Bitfield<0, 1> { };
+				struct Reserved : Bitfield<1, 1> { };
+			};
 
-			/**
-			 * Number of boot modules
-			 */
-			unsigned num_modules();
+			Mmap(addr_t mmap = 0) : Mmio(mmap) { }
+		};
 
-			/**
-			 * Use boot module num
-			 *
-			 * The module is marked as invalid in MBI and cannot be gotten again
-			 */
-			Rom_module get_module(unsigned num);
+		struct Mods : Genode::Mmio {
+			struct Start   : Register <0x00, 32> { };
+			struct End     : Register <0x04, 32> { };
+			struct Cmdline : Register <0x08, 32> { };
+			struct Padding : Register <0x0c, 32> { };
 
-			/**
-			 * Read module info
-			 */
-			bool check_module(unsigned num, addr_t *start, addr_t *end);
+			Mods(addr_t mods) : Mmio(mods) { }
+		};
 
-			/**
-			 * Debugging (may be removed later)
-			 */
-			void print_debug();
+	private:
 
-			/**
-			 * Check validity
-			 */
-			bool valid() { return _mb_info ? true : false; }
+		Mods _get_mod(unsigned i) {
+			Genode::addr_t mods_addr = read<Mods_addr>();
 
-			/* Accessors */
-			size_t size() const { return 0x1000; }
-	};
-}
+			enum { MODS_SIZE_OF = 16 };
+			return Mods(mods_addr + i * MODS_SIZE_OF);
+		}
+
+	public:
+
+		/**
+		 * Number of boot modules
+		 */
+		unsigned num_modules();
+
+		/* Accessors */
+		size_t size() const { return 0x1000; }
+
+		/**
+		 * Use boot module num
+		 *
+		 * The module is marked as invalid in MBI and cannot be gotten again
+		 */
+		Rom_module get_module(unsigned num);
+};
 
 #endif /* _CORE__INCLUDE__MULTIBOOT_H_ */
diff --git a/repos/base/src/core/mb_info.h b/repos/base/src/core/mb_info.h
deleted file mode 100644
index 96e6d62028..0000000000
--- a/repos/base/src/core/mb_info.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * \brief  Multiboot info structure as defined by GRUB
- * \author Christian Helmuth
- * \date   2006-05-09
- *
- * This is a stripped down version. Original code in
- * l4/pkg/l4util/include/ARCH-x86/mb_info.h.
- */
-
-/*
- * 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.
- */
-
-#ifndef _MB_INFO_H_
-#define _MB_INFO_H_
-
-#include <base/stdint.h>
-
-/**
- * Multi-boot module
- */
-typedef struct
-{
-  uint32_t mod_start;  /* starting address of module in memory. */
-  uint32_t mod_end;    /* end address of module in memory. */
-  uint32_t cmdline;    /* module command line */
-  uint32_t pad;        /* padding to take it to 16 bytes */
-} mb_mod_t;
-
-
-/** VBE controller information. */
-typedef struct
-{
-  uint8_t signature[4];
-  uint16_t version;
-  uint32_t oem_string;
-  uint32_t capabilities;
-  uint32_t video_mode;
-  uint16_t total_memory;
-  uint16_t oem_software_rev;
-  uint32_t oem_vendor_name;
-  uint32_t oem_product_name;
-  uint32_t oem_product_rev;
-  uint8_t reserved[222];
-  uint8_t oem_data[256];
-} __attribute__((packed)) mb_vbe_ctrl_t;
-
-
-/** VBE mode information. */
-typedef struct
-{
-  /* all VESA versions */
-  uint16_t mode_attributes;
-  uint8_t win_a_attributes;
-  uint8_t win_b_attributes;
-  uint16_t win_granularity;
-  uint16_t win_size;
-  uint16_t win_a_segment;
-  uint16_t win_b_segment;
-  uint32_t win_func;
-  uint16_t bytes_per_scanline;
-
-  /* >= VESA version 1.2 */
-  uint16_t x_resolution;
-  uint16_t y_resolution;
-  uint8_t x_char_size;
-  uint8_t y_char_size;
-  uint8_t number_of_planes;
-  uint8_t bits_per_pixel;
-  uint8_t number_of_banks;
-  uint8_t memory_model;
-  uint8_t bank_size;
-  uint8_t number_of_image_pages;
-  uint8_t reserved0;
-
-  /* direct color */
-  uint8_t red_mask_size;
-  uint8_t red_field_position;
-  uint8_t green_mask_size;
-  uint8_t green_field_position;
-  uint8_t blue_mask_size;
-  uint8_t blue_field_position;
-  uint8_t reserved_mask_size;
-  uint8_t reserved_field_position;
-  uint8_t direct_color_mode_info;
-
-  /* >= VESA version 2.0 */
-  uint32_t phys_base;
-  uint32_t reserved1;
-  uint16_t reversed2;
-
-  /* >= VESA version 3.0 */
-  uint16_t linear_bytes_per_scanline;
-  uint8_t banked_number_of_image_pages;
-  uint8_t linear_number_of_image_pages;
-  uint8_t linear_red_mask_size;
-  uint8_t linear_red_field_position;
-  uint8_t linear_green_mask_size;
-  uint8_t linear_green_field_position;
-  uint8_t linear_blue_mask_size;
-  uint8_t linear_blue_field_position;
-  uint8_t linear_reserved_mask_size;
-  uint8_t linear_reserved_field_position;
-  uint32_t max_pixel_clock;
-
-  uint8_t reserved3[189];
-} __attribute__ ((packed)) mb_vbe_mode_t;
-
-
-/**
- *  Multi-boot information
- */
-typedef struct
-{
-  uint32_t flags;        /* MultiBoot info version number */
-  uint32_t mem_lower;    /* available memory below 1MB */
-  uint32_t mem_upper;    /* available memory starting from 1MB [kB] */
-  uint32_t boot_device;  /* "root" partition */
-  uint32_t cmdline;      /* Kernel command line */
-  uint32_t mods_count;   /* number of modules */
-  uint32_t mods_addr;    /* module list */
-
-  union
-  {
-    struct
-    {
-      /* (a.out) Kernel symbol table info */
-      uint32_t tabsize;
-      uint32_t strsize;
-      uint32_t addr;
-      uint32_t pad;
-    } a;
-
-    struct
-    {
-      /* (ELF) Kernel section header table */
-      uint32_t num;
-      uint32_t size;
-      uint32_t addr;
-      uint32_t shndx;
-    } e;
-  } syms;
-
-  uint32_t mmap_length;        /* size of memory mapping buffer */
-  uint32_t mmap_addr;          /* address of memory mapping buffer */
-  uint32_t drives_length;      /* size of drive info buffer */
-  uint32_t drives_addr;        /* address of driver info buffer */
-  uint32_t config_table;       /* ROM configuration table */
-  uint32_t boot_loader_name;   /* Boot Loader Name */
-  uint32_t apm_table;          /* APM table */
-  uint32_t vbe_ctrl_info;      /* VESA video contoller info */
-  uint32_t vbe_mode_info;      /* VESA video mode info */
-  uint16_t vbe_mode;           /* VESA video mode number */
-  uint16_t vbe_interface_seg;  /* VESA segment of prot BIOS interface */
-  uint16_t vbe_interface_off;  /* VESA offset of prot BIOS interface */
-  uint16_t vbe_interface_len;  /* VESA lenght of prot BIOS interface */
-} mb_info_t;
-
-/**
- *  Flags to be set in the 'flags' parameter above
- */
-
-/** is the command-line defined? */
-#define MB_CMDLINE           0x00000004
-
-/** Is there video information?  */
-#define MB_VIDEO_INFO        0x00000800
-
-/** If we are multiboot-compliant, this value is present in the eax register */
-#define MB_VALID             0x2BADB002
-
-#endif
diff --git a/repos/base/src/core/multiboot_info.cc b/repos/base/src/core/multiboot_info.cc
index 51e9f4c91e..6c5eb2cf56 100644
--- a/repos/base/src/core/multiboot_info.cc
+++ b/repos/base/src/core/multiboot_info.cc
@@ -11,75 +11,23 @@
  * 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("  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;
-}
+unsigned Multiboot_info::num_modules() { return read<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);
+	if (num >= num_modules()) return Rom_module();
 
-	/* num exceeds number of modules */
-	if (!(num < mbi->mods_count)) return Rom_module();
+	Mods mods = _get_mod(num);
 
+	char *cmdline = reinterpret_cast<char*>(mods.read<Mods::Cmdline>());
 	/* invalid module -- maybe returned earlier */
-	if (!mods[num].cmdline) return Rom_module();
-
-	char *cmdline = reinterpret_cast<char*>(mods[num].cmdline);
+	if (!cmdline) return Rom_module();
 
 	/* skip everything in front of the base name of the file */
 	for (unsigned i = 0; cmdline[i]; i++) {
@@ -94,49 +42,30 @@ Rom_module Multiboot_info::get_module(unsigned num)
 		i = 0;
 	}
 
-	Rom_module ret = Rom_module(mods[num].mod_start,
-	                            mods[num].mod_end - mods[num].mod_start,
+	Rom_module ret = Rom_module(mods.read<Mods::Start>(),
+	                            mods.read<Mods::End>() - mods.read<Mods::Start>(),
 	                            cmdline);
 
 	/* mark module as invalid */
-	mods[num].cmdline = 0;
+	mods.write<Mods::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)
+Multiboot_info::Multiboot_info(addr_t mbi, bool path_strip)
+: Mmio(mbi)
 {
-	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);
+	if (!path_strip)
+		return;
 
 	/* 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();
+	for (unsigned i = 0; i < num_modules(); i++) {
+		Mods mods = _get_mod(i);
+		char *cmdline = reinterpret_cast<char*>(mods.read<Mods::Cmdline>());
+		mods.write<Mods::Cmdline>((addr_t)commandline_to_basename(cmdline));
 	}
 }