]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/moe/server/src/loader.cc
update
[l4.git] / l4 / pkg / moe / server / src / loader.cc
1 /*
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)
6  *
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.
10  */
11 #include "boot_fs.h"
12 #include "loader.h"
13 #include "globals.h"
14 #include "dataspace_annon.h"
15 #include "dataspace_noncont.h"
16 #include "debug.h"
17 #include "exception.h"
18 #include "app_task.h"
19 #include "name_space.h"
20 #include "dataspace_util.h"
21
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>
27
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>
35
36 #include <l4/re/env>
37
38 #include <l4/util/bitops.h>
39
40 #include <cctype>
41 #include "args.h"
42
43
44 using L4::Cap;
45 using L4Re::chksys;
46
47 using Moe::Stack;
48 using Moe::Boot_fs;
49
50 static Dbg info(Dbg::Info);
51
52 enum
53 {
54   Stack_size        = 0x8000,
55   Stack_address     = 0xb0000000,
56 };
57
58
59 static
60 Moe::Dataspace *
61 __alloc_app_stack(Allocator *a, Moe::Stack *_stack, unsigned long size)
62 {
63   cxx::Auto_ptr<Moe::Dataspace> stack(a->alloc(size));
64
65   _stack->set_local_top(stack->address(size - L4_PAGESIZE).adr<char*>() + L4_PAGESIZE);
66   return stack.release();
67 }
68
69 bool Loader::start(cxx::String const &init_prog, cxx::String const &cmdline)
70 {
71   Dbg info(Dbg::Info);
72   Dbg ldr(Dbg::Loader);
73
74   info.printf("Starting: %.*s %.*s\n",
75               init_prog.len(), init_prog.start(), cmdline.len(), cmdline.start());
76
77   return exec(init_prog, cmdline);
78 }
79
80
81 class Ldr_task : public App_task
82 {
83 public:
84
85 private:
86   l4_umword_t _entry, _stack_ptr;
87
88 public:
89   Ldr_task()
90   : _entry(0), _stack_ptr(0)
91   {}
92
93   void set_entry_data(l4_umword_t entry, l4_umword_t stack_ptr)
94   { _stack_ptr = stack_ptr; _entry = entry; }
95 };
96
97 Moe_app_model::Dataspace
98 Moe_app_model::alloc_ds(unsigned long size) const
99 {
100   Dataspace mem =_task->allocator()->alloc(size);
101   if (!mem)
102     chksys(-L4_ENOMEM, "ELF loader could not allocate memory");
103   return mem;
104 }
105
106 l4_cap_idx_t Moe_app_model::push_initial_caps(l4_cap_idx_t s)
107 {
108   for (Moe::Name_space::Const_iterator i = root_name_space()->begin();
109        i != root_name_space()->end(); ++i)
110     {
111       _stack.push(L4Re::Env::Cap_entry((*i).name().name(), s));
112       s += L4_CAP_OFFSET;
113     }
114
115   return s;
116 }
117
118 void Moe_app_model::map_initial_caps(L4::Cap<L4::Task> t, l4_cap_idx_t s)
119 {
120   for (Moe::Name_space::Const_iterator i = root_name_space()->begin();
121        i != root_name_space()->end(); ++i)
122     {
123       chksys(t->map(L4Re::This_task, (*i).obj()->cap().fpage(L4_CAP_FPAGE_RWS), L4::Cap<void>(s).snd_base()));
124       s += L4_CAP_OFFSET;
125     }
126 }
127
128 Moe_app_model::Const_dataspace
129 Moe_app_model::open_file(char const *name)
130 {
131   Moe::Dataspace const *f = Boot_fs::open_file(name);
132   if (!f)
133     chksys(-L4_ENOENT, name);
134   return f;
135 }
136
137 void
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)
141 {
142    void *x = _task->rm()->attach((void*)addr, size,
143                                  Region_handler(ds, L4_INVALID_CAP, offset, flags),
144                        flags);
145   if (x == L4_INVALID_PTR)
146     chksys(-L4_ENOMEM, what);
147 }
148
149 int
150 Moe_app_model::prog_reserve_area(l4_addr_t *start, unsigned long size, unsigned flags, unsigned char align)
151 {
152   l4_addr_t a = _task->rm()->attach_area(*start, size, flags, align);
153   if (a == L4_INVALID_ADDR)
154     return -L4_ENOMEM;
155
156   *start = a;
157   return 0;
158 }
159
160 bool
161 Loader::exec(cxx::String const &prog, cxx::String const &args)
162 {
163   static Ldr_task _init_task;
164
165   launch(&_init_task, prog, args);
166   return 0;
167 }
168
169
170 void
171 Moe_app_model::copy_ds(Dataspace dst, unsigned long dst_offs,
172                        Const_dataspace src, unsigned long src_offs,
173                        unsigned long size)
174 {
175   Dataspace_util::copy(dst, dst_offs, src, src_offs, size);
176 }
177
178
179 l4_addr_t
180 Moe_app_model::local_attach_ds(Const_dataspace ds, unsigned long /*size*/,
181                                unsigned long offset) const
182 {
183   return (l4_addr_t)ds->address(offset).adr();
184 }
185
186 void
187 Moe_app_model::local_detach_ds(l4_addr_t /*addr*/, unsigned long /*size*/) const
188 {
189 }
190
191
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)
195 {
196   enum
197   {
198     Kip_address            = 0xa0000000,
199     Utcb_area_start        = 0xb3000000,
200     Default_max_threads    = 16,
201   };
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);
205
206   // set default values for the application stack
207   _info.kip = Kip_address;
208
209 }
210
211
212 Moe_app_model::Dataspace
213 Moe_app_model::alloc_app_stack()
214 {
215   return __alloc_app_stack(_task->allocator(), &_stack, _stack.stack_size());
216 }
217
218 void
219 Moe_app_model::init_prog()
220 {
221   enum
222   {
223     Utcb_area_start        = 0xb3000000,
224     Default_max_threads    = 16,
225     Total_max_threads      = 256,
226   };
227
228   argv.al = argv.a0 = _stack.push_str(_prog.start(), _prog.len());
229
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());
233
234   envp.a0 = envp.al = 0;
235
236   Dbg info(Dbg::Info);
237
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();
243
244   _info.ldr_flags = Moe::ldr_flags;
245   _info.l4re_dbg = Moe::l4re_dbg;
246
247   info.printf("loading '%s'\n", argv.a0);
248 }
249
250 void
251 Moe_app_model::get_task_caps(L4::Cap<L4::Factory> *factory,
252                              L4::Cap<L4::Task> *task,
253                              L4::Cap<L4::Thread> *thread)
254 {
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>());
258
259   prog_info()->rm = _task->rm()->obj_cap().fpage();
260   prog_info()->parent = _task->obj_cap().fpage();
261
262   *task = _task->task_cap();
263   *thread = _task->thread_cap();
264   *factory = L4Re::Env::env()->factory();
265 }
266