/**
- * \file bootstrap/server/src/startup.c
+ * \file bootstrap/server/src/startup.cc
* \brief Main functions
*
* \date 09/2004
*/
/*
- * (c) 2005-2009 Technische Universität Dresden
+ * (c) 2005-2009 Author(s)
+ * economic rights: Technische Universität Dresden (Germany)
+ *
* This file is part of TUD:OS and distributed under the terms of the
* GNU General Public License 2.
* Please see the COPYING-GPL-2 file for details.
#include "init_kip.h"
#include "patch.h"
#include "loader_mbi.h"
-#include "startup.h"
-#if defined (ARCH_x86) || defined(ARCH_amd64)
-#include "ARCH-x86/serial.h"
-#endif
+#include "koptions.h"
#if defined (ARCH_ppc32)
#include <l4/drivers/of_if.h>
#undef getchar
+enum { Verbose_load = 0 };
+
static l4util_mb_info_t *mb_info;
/* management of allocated memory regions */
static Region_list regions;
-static Region __regs[MAX_REGION];
+static Region __regs[300];
/* management of conventional memory regions */
static Region_list ram;
-static Region __ram[8];
+static Region __ram[16];
#if defined(ARCH_x86) || defined(ARCH_amd64)
static l4util_mb_vbe_mode_t __mb_vbe;
static l4util_mb_vbe_ctrl_t __mb_ctrl;
#endif
-l4_kip_kernel_uart_info kip_kernel_uart_info;
+L4_kernel_options::Uart kuart;
+unsigned int kuart_flags;
/*
* IMAGE_MODE means that all boot modules are linked together to one
return k;
}
+static
+L4_kernel_options::Options *find_kopts(void *kip)
+{
+ unsigned long a = (unsigned long)kip + sizeof(l4_kernel_info_t);
+
+ // kernel-option directly follow the KIP page
+ a = (a + 4096 - 1) & ~0xfff;
+
+ L4_kernel_options::Options *ko = (L4_kernel_options::Options *)a;
+
+ if (ko->magic != L4_kernel_options::Magic)
+ panic("Could not find kernel options page");
+
+ return ko;
+}
+
const char *get_cmdline(l4util_mb_info_t *mbi)
{
- if (mbi->flags & L4UTIL_MB_CMDLINE)
+ if (mbi && mbi->flags & L4UTIL_MB_CMDLINE)
return L4_CHAR_PTR(mbi->cmdline);
if (*builtin_cmdline)
*
* return pointer after argument, NULL if not found
*/
-static char *
+char *
check_arg(l4util_mb_info_t *mbi, const char *arg)
{
const char *c = get_cmdline(mbi);
/**
* Calculate the maximum memory limit in MB.
*
- * The limit is the highes physical address where conventional RAM is allowed.
- *
- * If available the '-maxmem=xx' command line option is used.
- * If not then the memory is limited to 3 GB IA32 and unlimited on other
- * systems.
+ * The limit is the highest physical address where conventional RAM is allowed.
+ * The memory is limited to 3 GB IA32 and unlimited on other systems.
*/
static
unsigned long
-get_memory_limit(l4util_mb_info_t *mbi)
+get_memory_max_address()
{
- char *c;
+#if defined(ARCH_x86)
+ /* Limit memory, we cannot really handle more right now. In fact, the
+ * problem is roottask. It maps as many superpages/pages as it gets.
+ * After that, the remaining pages are mapped using l4sigma0_map_anypage()
+ * with a receive window of L4_WHOLE_ADDRESS_SPACE. In response Sigma0
+ * could deliver pages beyond the 3GB user space limit. */
+ return 3024UL << 20;
+#endif
+
+ return ~0UL;
+}
+/*
+ * If available the '-maxmem=xx' command line option is used.
+ */
+static
+unsigned long
+get_memory_max_size(l4util_mb_info_t *mbi)
+{
/* maxmem= parameter? */
- if ((c = check_arg(mbi, "-maxmem=")))
+ if (char *c = check_arg(mbi, "-maxmem="))
return strtoul(c + 8, NULL, 10) << 20;
- else
-#if defined(ARCH_x86)
- /* Limit memory, we cannot really handle more right now. In fact, the
- * problem is roottask. It maps as many superpages/pages as it gets.
- * After that, the remaining pages are mapped using l4sigma0_map_anypage()
- * with a receive window of L4_WHOLE_ADDRESS_SPACE. In response Sigma0
- * could deliver pages beyond the 3GB user space limit. */
- return 3024UL << 20;
-#else
- return ~0UL;
-#endif
+
+ return ~0UL;
}
static int
return 0;
}
+static
+void
+print_e820_map(l4util_mb_info_t *mbi)
+{
+#ifndef ARCH_arm
+ printf(" Bootloader MMAP%s\n", mbi->flags & L4UTIL_MB_MEM_MAP
+ ? ":" : " not available.");
+#endif
+
+ if (mbi->flags & L4UTIL_MB_MEM_MAP)
+ {
+ l4util_mb_addr_range_t *mmap;
+ l4util_mb_for_each_mmap_entry(mmap, mbi)
+ {
+ const char *types[] = { "unknown", "RAM", "reserved", "ACPI",
+ "ACPI NVS", "unusable" };
+ const char *type_str = (mmap->type < (sizeof(types) / sizeof(types[0])))
+ ? types[mmap->type] : types[0];
+
+ printf(" [%9llx, %9llx) %s (%d)\n",
+ (unsigned long long) mmap->addr,
+ (unsigned long long) mmap->addr + (unsigned long long) mmap->size,
+ type_str, (unsigned) mmap->type);
+ }
+ }
+}
+
static void
dump_ram_map(bool show_total = false)
{
for (Region *i = ram.begin(); i < ram.end(); ++i)
{
printf(" RAM: %016llx - %016llx: %lldkB\n",
- i->begin(), i->end(), (i->end() - i->begin() + 1) >> 10);
- sum += i->end() - i->begin() + 1;
+ i->begin(), i->end(), i->size() >> 10);
+ sum += i->size();
}
if (show_total)
printf(" Total RAM: %lldMB\n", sum >> 20);
}
}
-
-/**
- * Move modules to another address.
- *
- * Source and destination regions may overlap.
- */
static void
-move_modules(l4util_mb_info_t *mbi, unsigned long modaddr)
+move_module(l4util_mb_info_t *mbi, int i, Region *from, Region *to,
+ bool overlap_check)
{
- long offset = modaddr - (L4_MB_MOD_PTR(mbi->mods_addr))[0].mod_start;
- unsigned i;
- unsigned dir = offset > 0 ? mbi->mods_count : 1;
-
- if (!offset)
- {
- printf(" => Images in place\n");
- return;
- }
+ unsigned long start = from->begin();
+ unsigned long size = from->end() - start + 1;
- printf(" move modules to %lx with offset %lx\n", modaddr, offset);
-
- for (i = dir; i != mbi->mods_count - dir ; offset > 0 ? i-- : i++)
+ if (Verbose_load)
{
- unsigned long start = (L4_MB_MOD_PTR(mbi->mods_addr))[i-1].mod_start;
- unsigned long end = (L4_MB_MOD_PTR(mbi->mods_addr))[i-1].mod_end;
-
- if (start == end)
- continue;
-
-#ifdef VERBOSE_LOAD
unsigned char c[5];
c[0] = *(unsigned char*)(start + 0);
c[1] = *(unsigned char*)(start + 1);
c[1] = c[1] < 32 ? '.' : c[1];
c[2] = c[2] < 32 ? '.' : c[2];
c[3] = c[3] < 32 ? '.' : c[3];
- printf(" move module %02d { %lx, %lx } (%s) -> { %lx - %lx }\n",
- i, start, end, c, start + offset, end + offset);
+ printf(" moving module %02d { %lx, %llx } (%s) -> { %llx - %llx } [%ld]\n",
+ i, start, from->end(), c, to->begin(), to->end(), size);
for (int a = 0; a < 0x100; a += 4)
- printf("%08lx%s", *(unsigned long *)(start + a), (a % 32 == 28) ? "\n" : " ");
+ printf("%08x%s", *(unsigned *)(start + a), (a % 32 == 28) ? "\n" : " ");
printf("\n");
-#else
- printf(" move module %02d { %lx-%lx } -> { %lx-%lx }\n",
- i, start, end, start + offset, end + offset);
-#endif
+ }
+ else
+ printf(" moving module %02d { %lx-%llx } -> { %llx-%llx } [%ld]\n",
+ i, start, from->end(), to->begin(), to->end(), size);
+
+ if (!ram.contains(*to))
+ panic("Panic: Would move outside of RAM");
- Region *overlap = regions.find(Region(start + offset, end + offset));
+ if (overlap_check)
+ {
+ Region *overlap = regions.find(*to);
if (overlap)
- {
- printf("ERROR: module target [%lx-%lx) overlaps\n", start + offset,
- end + offset);
- overlap->vprint();
- panic("can not move module");
- }
- if (!ram.contains(Region(start + offset, end + offset)))
- panic("Panic: Would move outside of RAM");
- memmove((void *)(start+offset), (void *)start, end-start);
- (L4_MB_MOD_PTR(mbi->mods_addr))[i-1].mod_start += offset;
- (L4_MB_MOD_PTR(mbi->mods_addr))[i-1].mod_end += offset;
+ {
+ printf("ERROR: module target [%llx-%llx) overlaps\n",
+ to->begin(), to->end());
+ overlap->vprint();
+ regions.dump();
+ panic("cannot move module");
+ }
+ }
+ memmove((void *)to->begin(), (void *)start, size);
+ unsigned long x = to->end() + 1;
+ memset((char *)x, 0, l4_round_page(x) - x);
+
+ (L4_MB_MOD_PTR(mbi->mods_addr))[i].mod_start = to->begin();
+ (L4_MB_MOD_PTR(mbi->mods_addr))[i].mod_end = to->end() + 1;
+ from->begin(to->begin());
+ from->end(to->end());
+}
+
+static inline
+unsigned long mbi_mod_start(l4util_mb_info_t *mbi, int i)
+{ return (L4_MB_MOD_PTR(mbi->mods_addr))[i].mod_start; }
+
+static inline
+unsigned long mbi_mod_end(l4util_mb_info_t *mbi, int i)
+{ return (L4_MB_MOD_PTR(mbi->mods_addr))[i].mod_end; }
+
+static inline
+unsigned long mbi_mod_size(l4util_mb_info_t *mbi, int i)
+{ return mbi_mod_end(mbi, i) - mbi_mod_start(mbi, i); }
+
+/**
+ * Move modules to another address.
+ *
+ * Source and destination regions may overlap.
+ */
+static void
+move_modules(l4util_mb_info_t *mbi, unsigned long modaddr)
+{
+ printf(" Moving up to %d modules behind %lx\n", mbi->mods_count, modaddr);
+
+ Region *ramr = ram.find(Region(modaddr, modaddr));
+ Region module_area(modaddr, ramr->end(), "ram for modules");
+
+ unsigned long firstmodulestart = ~0UL, lastmoduleend = 0;
+ for (unsigned i = 0; i < mbi->mods_count; ++i)
+ {
+ if (lastmoduleend < mbi_mod_end(mbi, i))
+ lastmoduleend = mbi_mod_end(mbi, i);
+ if (firstmodulestart > mbi_mod_start(mbi, i))
+ firstmodulestart = mbi_mod_start(mbi, i);
+ }
+ lastmoduleend = l4_round_page(lastmoduleend);
+ if (firstmodulestart < modaddr)
+ {
+ Region s(lastmoduleend, ramr->end());
+ unsigned long sz = modaddr - firstmodulestart;
+ lastmoduleend = regions.find_free(s, sz, L4_PAGESHIFT) + sz;
+ }
+
+ for (unsigned i = 0; i < mbi->mods_count; ++i)
+ {
+ unsigned long start = mbi_mod_start(mbi, i);
+ unsigned long end = mbi_mod_end(mbi, i);
+ unsigned long size = mbi_mod_size(mbi, i);
+
+ if (start == end)
+ continue;
+
+ Region from(start, end - 1);
+ Region *this_module = regions.find(from);
+ assert(this_module->begin() == from.begin()
+ && this_module->end() == from.end());
+
+ if (i < 3)
+ {
+ if (start < lastmoduleend)
+ {
+ Region to(lastmoduleend, lastmoduleend + (end - start) - 1);
+ if (module_area.contains(to))
+ {
+ move_module(mbi, i, this_module, &to, true);
+ lastmoduleend = l4_round_page(this_module->end());
+ }
+ }
+ continue;
+ }
+
+ if (start >= modaddr)
+ continue;
+
+ unsigned long long to = regions.find_free(module_area, size, L4_PAGESHIFT);
+ assert(to);
+
+ Region m_to = Region(to, to + size - 1);
+ move_module(mbi, i, this_module, &m_to, true);
+ }
+
+ // now everything is behind modaddr -> pull close to modaddr now
+ // this is optional but avoids holes and gives more consecutive memory
+
+ if (Verbose_load)
+ printf(" Compactifying\n");
+
+ regions.sort();
+ unsigned long lastend = modaddr;
+
+ // Now check whether modaddr is ok or if some non-modules are still above
+ // modaddr, so that we need to have lastend higher
+ {
+ unsigned long end_last_pre_module = 0;
+ bool seen_modules = false;
+
+ for (Region *i = regions.begin(); i < regions.end(); ++i)
+ {
+ if (strcmp(i->name(), ".Module"))
+ {
+ unsigned long mod_end = l4_round_page(i->end());
+ if (!seen_modules && end_last_pre_module < mod_end)
+ end_last_pre_module = mod_end;
+ }
+ else
+ seen_modules = true;
+ }
+
+ if (end_last_pre_module > lastend)
+ lastend = end_last_pre_module;
+ }
+
+ if (Verbose_load)
+ printf(" Moving modules down to %lx\n", lastend);
+
+ for (Region *i = regions.begin(); i < regions.end(); ++i)
+ {
+ if (i->begin() < modaddr)
+ continue;
+
+ // find in mbi
+ unsigned mi = 0;
+ for (; mi < mbi->mods_count; ++mi)
+ if (i->begin() == mbi_mod_start(mbi, mi))
+ break;
+
+ if (mi < 3 || mbi->mods_count == mi)
+ continue;
+
+ unsigned long start = mbi_mod_start(mbi, mi);
+ unsigned long end = mbi_mod_end(mbi, mi);
+
+ if (start > lastend)
+ {
+ Region to(lastend, end - 1 - (start - lastend));
+ move_module(mbi, mi, i, &to, false);
+ end = i->end();
+ }
+ lastend = l4_round_page(end);
}
}
".bootstrap", Region::Boot));
}
+/**
+ * Add memory used by MBI to the allocated memory regions.
+ */
+static void
+reserve_mbi_memory(l4util_mb_info_t *mbi)
+{
+ regions.add(Region::n((unsigned long)mbi,
+ (unsigned long)mbi + sizeof(*mbi),
+ ".mbi", Region::Boot));
+
+ if (mbi->flags & L4UTIL_MB_CMDLINE)
+ regions.add(Region::n((unsigned long)mbi->cmdline,
+ (unsigned long)mbi->cmdline
+ + strlen(L4_CONST_CHAR_PTR(mbi->cmdline)),
+ ".mbi", Region::Boot));
+
+ l4util_mb_mod_t *mb_mod = (l4util_mb_mod_t*)(unsigned long)mbi->mods_addr;
+ regions.add(Region::n((unsigned long)mb_mod,
+ (unsigned long)&mb_mod[mbi->mods_count],
+ ".mbi", Region::Boot));
+
+ for (unsigned i = 0; i < mbi->mods_count; ++i)
+ regions.add(Region::n(mb_mod[i].cmdline,
+ (unsigned long)mb_mod[i].cmdline
+ + strlen(L4_CONST_CHAR_PTR(mb_mod[i].cmdline)),
+ ".mbi", Region::Boot));
+
+ regions.optimize();
+}
/**
* Add the memory containing the boot modules to the allocated regions.
static void
add_boot_modules_region(l4util_mb_info_t *mbi)
{
- regions.add(
- Region::n((L4_MB_MOD_PTR(mbi->mods_addr))[0].mod_start,
- (L4_MB_MOD_PTR(mbi->mods_addr))[mbi->mods_count-1].mod_end,
- ".Modules Memory", Region::Root));
+ for (unsigned int i = 0; i < mbi->mods_count; ++i)
+ regions.add(Region(mbi_mod_start(mbi, i), mbi_mod_end(mbi, i) - 1,
+ ".Module", Region::Root));
}
-
/**
* Add all sections of the given ELF binary to the allocated regions.
* Actually does not load the ELF binary (see load_elf_module()).
l4_addr_t entry;
int r;
const char *error_msg;
- l4util_mb_mod_t *mb_mod = (l4util_mb_mod_t*)mbi->mods_addr;
+ l4util_mb_mod_t *mb_mod = (l4util_mb_mod_t*)(unsigned long)mbi->mods_addr;
assert(module < mbi->mods_count);
if (r)
{
-#ifdef VERBOSE_LOAD
- int i;
- printf("\n%p: ", exec_task.mod_start);
- for (i = 0; i < 16; ++i)
- {
- printf("%02x", *(unsigned char *)exec_task.mod_start);
- if (i % 4 == 3)
- printf(" ");
- }
- printf(" ");
- for (i = 0; i < 16; ++i)
+ if (Verbose_load)
{
- unsigned char c = *(unsigned char *)exec_task.mod_start;
- printf("%c", c < 32 ? '.' : c);
- }
-#endif
- panic("\n\nThis is an invalid binary, fix it.");
+ printf("\n%p: ", exec_task.mod_start);
+ for (int i = 0; i < 4; ++i)
+ printf("%08x ", *((unsigned *)exec_task.mod_start + i));
+ printf(" ");
+ for (int i = 0; i < 16; ++i)
+ {
+ unsigned char c = *(unsigned char *)((char *)exec_task.mod_start + i);
+ printf("%c", c < 32 ? '.' : c);
+ }
+ }
+ panic("\n\nThis is an invalid binary, fix it (%s).", error_msg);
}
}
/**
* Simple linear memory allocator.
*
- * Allocate size bytes startting from *ptr and set *ptr to *ptr + size.
+ * Allocate size bytes starting from *ptr and set *ptr to *ptr + size.
*/
static inline void*
lin_alloc(l4_size_t size, char **ptr)
/**
* Duplicate the given command line.
*
- * This function is use for relocating the multi-boot info.
- * The new location is *ptr and *ptr is incemented by the size of the
+ * This function is used for relocating the multi-boot info.
+ * The new location is *ptr and *ptr is incremented by the size of the
* string (basically like lin_alloc() does).
*
* This function also implements the mechanism to replace the command line
- * of a module from the bootstrap comand line.
+ * of a module from the bootstrap command line.
*/
static
char *dup_cmdline(l4util_mb_info_t *mbi, unsigned mod_nr, char **ptr,
}
-static
-void
-print_e820_map(l4util_mb_info_t *mbi)
-{
-#ifndef ARCH_arm
- printf(" Bootloader MMAP%s\n", mbi->flags & L4UTIL_MB_MEM_MAP
- ? ":" : " not available.");
-#endif
-
- if (mbi->flags & L4UTIL_MB_MEM_MAP)
- {
- l4util_mb_addr_range_t *mmap;
- l4util_mb_for_each_mmap_entry(mmap, mbi)
- {
- const char *types[] = { "unknown", "RAM", "reserved", "ACPI",
- "ACPI NVS", "unusable" };
- const char *type_str = (mmap->type < (sizeof(types) / sizeof(types[0])))
- ? types[mmap->type] : types[0];
-
- printf(" [%9llx, %9llx) %s (%d)\n",
- (unsigned long long) mmap->addr,
- (unsigned long long) mmap->addr + (unsigned long long) mmap->size,
- type_str, (unsigned) mmap->type);
- }
- }
-}
-
/**
- * Relocate and compact the multi-boot infomation (MBI).
+ * Relocate and compact the multi-boot information (MBI).
*
* This function relocates the MBI into the first 4MB of physical memory.
* Substructures such as module information, the VESA information, and
* During relocation of command lines they may be substituted according
* to '-arg=' options from the bootstrap command line.
*
- * The memory map is discared and not relocated, because everything after
- * bootstrap has to use the KIP memory desriptors.
+ * The memory map is discarded and not relocated, because everything after
+ * bootstrap has to use the KIP memory descriptors.
*/
static
l4util_mb_info_t *
/* copy command lines of modules */
for (unsigned i = 0; i < dst_mbi->mods_count; i++)
{
- char *n = dup_cmdline(src_mbi, i, &p, (char const *)(mods[i].cmdline));
+ char *n = dup_cmdline(src_mbi, i, &p, (char const *)(unsigned long)mods[i].cmdline);
if (n)
mods[i].cmdline = (l4_addr_t) n;
}
*end = (l4_addr_t)p;
- printf(" Relocated mbi to [%p-%p]\n", mbi_start, (void*)(*end));
+ printf(" Relocated mbi to [%p-%p]\n", mbi_start, (void *)(*end));
regions.add(Region::n((unsigned long)mbi_start,
((unsigned long)*end) + 0xfe,
".Multiboot info", Region::Root),
extern l4util_mb_mod_t _modules_mbi_start[];
extern l4util_mb_mod_t _modules_mbi_end[];
+extern char _mbi_cmdline[];
/**
* Create the basic multi-boot structure in IMAGE_MODE
#endif /* IMAGE_MODE */
-void
-init_pc_serial(l4util_mb_info_t *mbi)
-{
-#if defined(ARCH_x86) || defined(ARCH_amd64)
- const char *s;
- int comport = -1;
-
- if ((s = check_arg(mbi, "-comport")))
- comport = strtoul(s + 9, 0, 0);
-
- if (check_arg(mbi, "-serial"))
- {
- if (0)
- {
- extern unsigned long search_pci_serial_devs(bool scan_only);
- unsigned long port;
- if (comport == -1
- && (port = search_pci_serial_devs(false)))
- comport = port;
- }
-
- if (comport == -1)
- comport = 1;
-
- com_cons_init(comport);
- }
-#else
- (void)mbi;
-#endif
-
-}
-
-#ifdef ARCH_arm
-#ifndef IMAGE_MODE
-// check that our is_precious_ram function can work ok
-#error For ARM, IMAGE_MODE must always be enabled
-#endif
-
-/* Occupied RAM at the point we are scannig it */
+/* Occupied RAM at the point we are scanning it */
static int
is_precious_ram(unsigned long addr)
{
extern int _start, _end;
- unsigned i, c = _module_info_end - _module_info_start;
if ((unsigned long)&_start <= addr && addr <= (unsigned long)&_end)
return 1;
+#ifdef IMAGE_MODE
+ unsigned i, c = _module_info_end - _module_info_start;
if ((unsigned long)_module_info_start <= addr
&& addr <= (unsigned long)_module_info_end)
return 1;
for (i = 0; i < c; ++i)
if (_module_info_start[i].start <= addr
- && _module_info_start[i].start + _module_info_start[i].size_uncompressed <= addr)
+ && addr < _module_info_start[i].start + _module_info_start[i].size_uncompressed)
return 1;
+#endif
return 0;
}
return max_scan_size_mb;
}
-#endif
/**
* \brief Startup, started from crt0.S
boot_info_t boot_info;
l4util_mb_mod_t *mb_mod;
- /* fire up serial port if specificed on the command line */
- init_pc_serial(mbi);
-
if (!Platform_base::platform)
{
// will we ever see this?
;
}
+#ifdef LOADER_MBI
+ loader_mbi_add_cmdline(_mbi_cmdline);
+ mbi = loader_mbi();
+#endif
+
+ if (check_arg(mbi, "-wait"))
+ {
+ puts("\nL4 Bootstrapper is waiting for key input to continue...");
+ if (getchar() == -1)
+ puts(" ...no key input available.");
+ else
+ puts(" ...going on.");
+ }
+
puts("\nL4 Bootstrapper");
- puts(" Build: #" BUILD_NR " " BUILD_DATE);
+ puts(" Build: #" BUILD_NR " " BUILD_DATE
+#ifdef ARCH_x86
+ ", x86-32"
+#endif
+#ifdef ARCH_amd64
+ ", x86-64"
+#endif
+#ifdef __VERSION__
+ ", " __VERSION__
+#endif
+ );
- regions.init(__regs, sizeof(__regs)/sizeof(__regs[0]), "regions");
- ram.init(__ram, sizeof(__ram)/sizeof(__ram[0]), "RAM",
- get_memory_limit(mbi));
+ regions.init(__regs, sizeof(__regs) / sizeof(__regs[0]), "regions");
+ ram.init(__ram, sizeof(__ram) / sizeof(__ram[0]), "RAM",
+ get_memory_max_size(mbi), get_memory_max_address());
#ifdef ARCH_amd64
// add the page-table on which we're running in 64bit mode
#ifdef REALMODE_LOADING
/* create synthetic multi boot info */
- mbi = init_loader_mbi(realmode_si);
+ mbi = init_loader_mbi_x86_realmode(realmode_si);
+ (void)flag;
#else
(void)realmode_si;
assert(flag == L4UTIL_MB_VALID); /* we need to be multiboot-booted */
#endif
#elif defined(ARCH_arm)
- l4util_mb_info_t my_mbi;
- memset(&my_mbi, 0, sizeof(my_mbi));
- mbi = &my_mbi;
+ mbi = loader_mbi();
(void)realmode_si;
(void)flag;
#elif defined(ARCH_ppc32)
+ mbi = loader_mbi();
+
(void)realmode_si;
(void)flag;
- l4util_mb_info_t my_mbi;
L4_drivers::Of_if of_if;
printf(" Detecting ram size ...\n");
unsigned long ram_size = of_if.detect_ramsize();
printf(" Total memory size is %luMB\n", ram_size / (1024 * 1024));
- /* setup mbi and detect OF devices */
- memset(&my_mbi, 0, sizeof(my_mbi));
- mbi = &my_mbi;
+ /* detect OF devices */
unsigned long drives_addr, drives_length;
if (of_if.detect_devices(&drives_addr, &drives_length))
}
ram.add(Region::n(0x0, ram_size, ".ram", Region::Ram));
+#elif defined(ARCH_sparc)
+ mbi = loader_mbi();
+
+ (void)realmode_si;
+ (void)flag;
#else
#error Unknown arch!
#endif
roottask = 0;
if (const char *s = check_arg(mbi, "-modaddr"))
- _mod_addr = strtoul(s + 9, 0, 0);
+ _mod_addr = RAM_BASE + strtoul(s + 9, 0, 0);
+
+ _mod_addr = l4_round_page(_mod_addr);
#ifdef IMAGE_MODE
construct_mbi(mbi);
#endif
+ reserve_mbi_memory(mbi);
+
/* move vbe and ctrl structures to a known location, it might be in the
* way when moving modules around */
#if defined(ARCH_x86) || defined(ARCH_amd64)
}
#endif
- if (_mod_addr)
- move_modules(mbi, _mod_addr);
-
/* We need at least two boot modules */
assert(mbi->flags & L4UTIL_MB_MODS);
/* We have at least the L4 kernel and the first user task */
/* we're just a GRUB-booted kernel! */
add_boot_modules_region(mbi);
+ if (_mod_addr)
+ move_modules(mbi, _mod_addr);
+
if (const char *s = get_cmdline(mbi))
{
/* patch modules with content given at command line */
patch_module(&s, mbi);
}
-
add_elf_regions(mbi, kernel_module, Region::Kernel);
if (sigma0)
if (roottask)
add_elf_regions(mbi, roottask_module, Region::Root);
-
/* copy Multiboot data structures, we still need to a safe place
* before playing with memory we don't own and starting L4 */
mb_info = relocate_mbi(mbi, &boot_info.mbi_low, &boot_info.mbi_high);
if (!mb_info)
panic("could not copy multiboot info to memory below 4MB");
- mb_mod = (l4util_mb_mod_t*)mb_info->mods_addr;
+ mb_mod = (l4util_mb_mod_t *)(unsigned long)mb_info->mods_addr;
/* --- Shouldn't touch original Multiboot parameters after here. -- */
fill_mem(fill_value);
}
+ L4_kernel_options::Options *lko = find_kopts(l4i);
+ kcmdline_parse(L4_CONST_CHAR_PTR(mb_mod[kernel_module].cmdline), lko);
+ lko->uart = kuart;
+ lko->flags |= kuart_flags;
+
+
/* setup the L4 kernel info page before booting the L4 microkernel:
* patch ourselves into the booter task addresses */
unsigned long api_version = get_api_version(l4i);
case 0x03: // Version X.0 and X.1
case 0x87: // Fiasco
init_kip_v2(l4i, &boot_info, mb_info, &ram, ®ions);
- //init_kip_kuart_info(l4i, &kip_kernel_uart_info);
break;
case 0x84:
case 0x04:
startup_func f = (startup_func)boot_info.kernel_start;
of_if.boot_finish();
f(&kernel_mbi, of_if.get_prom());
+
+#elif defined(ARCH_sparc)
+
+ printf("ENTER THE KERNEL!\n");
+ asm volatile("or %%g0,%0,%%g2\n\t"
+ "jmpl %%g2,%%g0\n\t"
+ "nop\n\t" : : "r"(boot_info.kernel_start));
+
#else
#error "How to enter the kernel?"
if (mem_addr + mem_size > exec_task->end)
exec_task->end = mem_addr + mem_size;
-#ifdef VERBOSE_LOAD
- printf(" [%p-%p]\n", (void *) mem_addr, (void *) (mem_addr + mem_size));
-#endif
+ if (Verbose_load)
+ printf(" [%p-%p]\n", (void *) mem_addr, (void *) (mem_addr + mem_size));
if (!ram.contains(Region::n(mem_addr, mem_addr + mem_size)))
{