/* * \brief Startup code for L4Linux. * \author Stefan Kalkowski * \date 2011-04-11 */ /* * Copyright (C) 2011-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. */ /* Genode includes */ #include #include #include #include #include #include #include #include /* L4lx includes */ #include namespace Fiasco { #include #include #include #include #include } extern void* _prog_img_end; /* binary end in virtual memory */ extern void* _prog_img_beg; /* binary start in virtual memory */ extern void* l4lx_kinfo; /* pointer to the KIP */ extern "C" int linux_main(int argc, char **argv); /* l4linux entry function */ static const bool DEBUG = false; static void parse_cmdline(char*** cmd, int *num) { using namespace Genode; enum { MAX_CMDLINE_LEN = 256, MAX_ARGS = 128 }; static char arg_str[MAX_CMDLINE_LEN]; static char* words[MAX_ARGS]; try { config()->xml_node().attribute("args").value(arg_str, sizeof(arg_str)); } catch(...) { PWRN("Couldn't parse commandline from config!"); arg_str[0] = 0; } if (DEBUG) PDBG("Read the following commandline from config: %s", arg_str); unsigned i = 1; words[0] = (char*) "vmlinux"; for (char* start = &arg_str[0], *ptr = start; i < MAX_ARGS; ptr++) { if (*ptr != 0 && *ptr != ' ') continue; words[i] = start; *ptr++ = 0; start = ptr; words[++i] = 0; if (*ptr == 0) break; for (; *ptr == ' '; ptr++) ; } *cmd = words; *num = i; } static void map_kip() { using namespace Genode; /* Open the KIP special file and keep it open */ Genode::Rom_connection kip_rom("kip"); kip_rom.on_destruction(Genode::Rom_connection::KEEP_OPEN); /* Attach and register dataspace */ l4lx_kinfo = L4lx::Env::env()->rm()->attach(kip_rom.dataspace(), "KIP"); /* map it right now */ Fiasco::l4_touch_ro(l4lx_kinfo, L4_PAGESIZE); } static void prepare_l4re_env() { using namespace Fiasco; Genode::Foc_cpu_session_client cpu(Genode::env()->cpu_session_cap()); Genode::Thread_capability main_thread = Genode::Thread_base::myself()->cap(); static Genode::Native_capability main_thread_cap = cpu.native_cap(main_thread); l4re_env_t *env = l4re_env(); env->first_free_utcb = (l4_addr_t)l4_utcb() + L4_UTCB_OFFSET; env->utcb_area = l4_fpage((l4_addr_t)l4_utcb(), Genode::log2(L4_UTCB_OFFSET * L4lx::THREAD_MAX), L4_CAP_FPAGE_RW); env->factory = L4_INVALID_CAP; env->scheduler = L4_BASE_SCHEDULER_CAP; env->mem_alloc = L4_INVALID_CAP; env->log = L4_INVALID_CAP; env->main_thread = main_thread_cap.dst(); env->rm = Fiasco::THREAD_AREA_BASE + Fiasco::THREAD_PAGER_CAP; } static void register_reserved_areas() { using namespace Genode; size_t bin_sz = (addr_t)&_prog_img_end - (addr_t)&_prog_img_beg; L4lx::Env::env()->rm()->reserve_range((addr_t)&_prog_img_beg, bin_sz, "Binary"); L4lx::Env::env()->rm()->reserve_range(Thread_base::stack_area_virtual_base(), Thread_base::stack_area_virtual_size(), "Stack Area"); } int main(int, char**) { int cmd_num = 0; char** cmdline = 0; PINF("Booting L4Linux ..."); register_reserved_areas(); map_kip(); prepare_l4re_env(); parse_cmdline(&cmdline, &cmd_num); if (DEBUG) L4lx::Env::env()->rm()->dump(); return linux_main(cmd_num, cmdline); }