2 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>,
4 * Björn Döbel <doebel@os.inf.tu-dresden.de>
5 * economic rights: Technische Universität Dresden (Germany)
7 * This file is part of TUD:OS and distributed under the terms of the
8 * GNU General Public License 2.
9 * Please see the COPYING-GPL-2 file for details.
14 #include "dataspace_annon.h"
15 #include "dataspace_noncont.h"
17 #include "exception.h"
19 #include "name_space.h"
20 #include "dataspace_util.h"
22 #include <l4/cxx/auto_ptr>
23 #include <l4/cxx/iostream>
24 #include <l4/cxx/l4iostream>
25 #include <l4/cxx/exceptions>
26 #include <l4/cxx/ipc_helper>
28 #include <l4/sys/scheduler>
29 #include <l4/sys/utcb.h>
30 #include <l4/sys/kernel_object.h>
31 #include <l4/sys/factory>
32 #include <l4/sys/task>
33 #include <l4/sys/thread>
34 #include <l4/re/error_helper>
38 #include <l4/util/bitops.h>
50 static Dbg info(Dbg::Info);
55 Stack_address = 0xb0000000,
61 __alloc_app_stack(Allocator *a, Moe::Stack *_stack, unsigned long size)
63 cxx::Auto_ptr<Moe::Dataspace> stack(a->alloc(size));
65 _stack->set_local_top(stack->address(size - L4_PAGESIZE).adr<char*>() + L4_PAGESIZE);
66 return stack.release();
69 bool Loader::start(cxx::String const &init_prog, cxx::String const &cmdline)
74 info.printf("Starting: %.*s %.*s\n",
75 init_prog.len(), init_prog.start(), cmdline.len(), cmdline.start());
77 return exec(init_prog, cmdline);
81 class Ldr_task : public App_task
86 l4_umword_t _entry, _stack_ptr;
90 : _entry(0), _stack_ptr(0)
93 void set_entry_data(l4_umword_t entry, l4_umword_t stack_ptr)
94 { _stack_ptr = stack_ptr; _entry = entry; }
97 Moe_app_model::Dataspace
98 Moe_app_model::alloc_ds(unsigned long size) const
100 Dataspace mem =_task->allocator()->alloc(size);
102 chksys(-L4_ENOMEM, "ELF loader could not allocate memory");
106 l4_cap_idx_t Moe_app_model::push_initial_caps(l4_cap_idx_t s)
108 for (Moe::Name_space::Const_iterator i = root_name_space()->begin();
109 i != root_name_space()->end(); ++i)
111 _stack.push(L4Re::Env::Cap_entry((*i).name().name(), s));
118 void Moe_app_model::map_initial_caps(L4::Cap<L4::Task> t, l4_cap_idx_t s)
120 for (Moe::Name_space::Const_iterator i = root_name_space()->begin();
121 i != root_name_space()->end(); ++i)
123 chksys(t->map(L4Re::This_task, (*i).obj()->cap().fpage(L4_CAP_FPAGE_RWS), L4::Cap<void>(s).snd_base()));
128 Moe_app_model::Const_dataspace
129 Moe_app_model::open_file(char const *name)
131 Moe::Dataspace const *f = Boot_fs::open_file(name);
133 chksys(-L4_ENOENT, name);
138 Moe_app_model::prog_attach_ds(l4_addr_t addr, unsigned long size,
139 Const_dataspace ds, unsigned long offset,
140 unsigned flags, char const *what)
142 void *x = _task->rm()->attach((void*)addr, size,
143 Region_handler(ds, L4_INVALID_CAP, offset, flags),
145 if (x == L4_INVALID_PTR)
146 chksys(-L4_ENOMEM, what);
150 Moe_app_model::prog_reserve_area(l4_addr_t *start, unsigned long size, unsigned flags, unsigned char align)
152 l4_addr_t a = _task->rm()->attach_area(*start, size, flags, align);
153 if (a == L4_INVALID_ADDR)
161 Loader::exec(cxx::String const &prog, cxx::String const &args)
163 static Ldr_task _init_task;
165 launch(&_init_task, prog, args);
171 Moe_app_model::copy_ds(Dataspace dst, unsigned long dst_offs,
172 Const_dataspace src, unsigned long src_offs,
175 Dataspace_util::copy(dst, dst_offs, src, src_offs, size);
180 Moe_app_model::local_attach_ds(Const_dataspace ds, unsigned long /*size*/,
181 unsigned long offset) const
183 return (l4_addr_t)ds->address(offset).adr();
187 Moe_app_model::local_detach_ds(l4_addr_t /*addr*/, unsigned long /*size*/) const
192 Moe_app_model::Moe_app_model(App_task *t, cxx::String const &prog,
193 cxx::String const &args)
194 : _task(t), _prog(prog), _args(args)
198 Kip_address = 0xa0000000,
199 Utcb_area_start = 0xb3000000,
200 Default_max_threads = 16,
202 // set default values for utcb area, values may be changed by loader
203 _info.utcbs_start = Utcb_area_start;
204 _info.utcbs_log2size = l4util_log2(Default_max_threads * L4_UTCB_OFFSET);
206 // set default values for the application stack
207 _info.kip = Kip_address;
212 Moe_app_model::Dataspace
213 Moe_app_model::alloc_app_stack()
215 return __alloc_app_stack(_task->allocator(), &_stack, _stack.stack_size());
219 Moe_app_model::init_prog()
223 Utcb_area_start = 0xb3000000,
224 Default_max_threads = 16,
225 Total_max_threads = 256,
228 argv.al = argv.a0 = _stack.push_str(_prog.start(), _prog.len());
230 for (cxx::Pair<cxx::String, cxx::String> a = next_arg(_args);
231 !a.first.empty(); a = next_arg(a.second))
232 argv.al = _stack.push_str(a.first.start(), a.first.len());
234 envp.a0 = envp.al = 0;
238 Allocator *allocator = Allocator::root_allocator();
239 _info.mem_alloc = allocator->obj_cap().fpage();
240 _info.log = L4Re::Env::env()->log().fpage();
241 _info.factory = L4Re::Env::env()->factory().fpage();
242 _info.scheduler = L4Re::Env::env()->scheduler().fpage();
244 _info.ldr_flags = Moe::ldr_flags;
245 _info.l4re_dbg = Moe::l4re_dbg;
247 info.printf("loading '%s'\n", argv.a0);
251 Moe_app_model::get_task_caps(L4::Cap<L4::Factory> *factory,
252 L4::Cap<L4::Task> *task,
253 L4::Cap<L4::Thread> *thread)
255 object_pool.cap_alloc()->alloc(_task);
256 _task->task_cap(object_pool.cap_alloc()->alloc<L4::Task>());
257 _task->thread_cap(object_pool.cap_alloc()->alloc<L4::Thread>());
259 prog_info()->rm = _task->rm()->obj_cap().fpage();
260 prog_info()->parent = _task->obj_cap().fpage();
262 *task = _task->task_cap();
263 *thread = _task->thread_cap();
264 *factory = L4Re::Env::env()->factory();