3local
L4 = require
"L4";
5local l =
L4.Loader.new({mem =
L4.Env.user_factory});
11 Utility function to merge several lua tables
13 \param ... one or more tables
15 \note Later tables are given more priority when merging
17 \return a
new combined table
19function table_override(...)
21 for _, tab in ipairs({...})
do
22 for k, v in pairs(tab)
do
30 Creates a
new scheduler proxy at moe.
32 \param prio Base priority of the threads running in the scheduler proxy
33 \param cpu_mask First of a list of CPU masks
for the first 64 CPUs to use
for
35 \param ... more CPU masks
37 \return created scheduler
40 return
L4.Env.user_factory:create(
L4.Proto.Scheduler, prio + 10, prio,
45 Start IO service with the given options
47 \param[in,out] busses table of vBus names as keys. Uses io config
48 `<name>.vbus` to fill vBus `<name>`.
49 \param cmdline io command line parameters
50 \param opts Option table for loader.start function, e.g. scheduler
51 or ext_caps. Entries from ext_caps have precedence over
52 default caps created by this function.
54 After this function returns the created vBusses are located in the table
58 if opts == nil then opts = {} end
60 if opts.caps ~= nil then
61 print(
"Warning: use opts.ext_caps to pass custom/additional capabilities.")
64 if opts.scheduler == nil then
65 print(
"IO started with base priority. Risk of priority related deadlocks! "
66 ..
"Provide an opts.scheduler entry.")
70 sigma0 =
L4.cast(
L4.Proto.
Factory,
L4.Env.sigma0):create(
L4.Proto.Sigma0);
77 for k, v in pairs(busses)
do
78 if caps[k] ~= nil then
79 print(
"Warning: overwriting caps." .. k ..
" with vbus of same name.")
81 local c = l:new_channel();
84 files = files ..
" rom/" .. k ..
".vbus";
87 opts.caps = table_override(caps, opts.caps or {}, opts.ext_caps or {})
88 opts.log = opts.log or {
"io",
"red" }
90 return l:start(opts,
"rom/io " .. cmdline .. files)
94 Create scheduler proxy and add it into the `opts` table under
97 \param[in,out] opts option table
98 \param prio thread priority (or `nil`)
99 \param cpus cpu mask (or `nil`)
100 \param ... more CPU masks
102 There are four possibilities
for values of prio and cpus:
104 \li No prio and no cpus: No scheduler proxy created.
105 \li A prio, but no cpus: Create a scheduler proxy with only a priority limit.
106 \li No Prio, but cpus: Create a scheduler proxy with
default prio and cpus
108 \li A prio and cpus: Create a scheduler proxy with given limits.
111 if cpus == nil and prio == nil then
116 -- Default to zero to use the
L4Re Default_thread_prio
120 local sched =
new_sched(prio, cpus, ...);
121 opts[
"scheduler"] = sched;
125 Start virtio network application.
127 \deprecated This function exists for backwards compatiblity reasons and calls
130 \param[in,out] ports table with port names as keys
131 \param prio priority for started thread
132 \param cpus cpu mask for started thread
133 \param switch_type Selects application to start. Either `switch` or `p2p`
134 \param ext_caps Extra capabilities to pass to the started application
136 The switch_type `switch` can take additional arguments to create a port at the
137 switch. To pass these arguments for a specific port, pass a table as value for
138 a key in the ports table.
144 switch_type = switch_type,
152 Start virtio network application.
154 \param options A table of parameters
156 The following keys are supported in the `options` table:
158 | table key | value |
159 | ------------ | ---------------------------------------------------------------- |
160 | `ports` | table with port names as keys |
161 | `scheduler` | scheduler (e.g. created with
new_sched) |
162 | `switch_type`| selects application to start. Either `
switch` or `p2p` |
163 | `ext_caps` | Extra capabilities to pass to the started application |
164 | `svr_cap` | cap slot to be used
for the server
interface |
165 | `port_limit` | the maximum number of dynamic ports the switch shall support |
167 The switch_type `switch` can take additional arguments to create a port at the
168 switch. To pass these arguments for a specific port, pass a table as value for
169 a key in the ports table.
171 \note The `svr_cap` capability requires server rights, use
":svr()".
174 local ports = options.ports;
175 local scheduler = options.scheduler;
176 local switch_type = options.switch_type;
177 local ext_caps = options.ext_caps;
178 local svr_cap = options.svr_cap;
179 local port_limit = options.port_limit;
181 if svr_cap and port_limit == nil then
182 print(
"Warning: start_virtio_switch_tbl(): 'svr_cap' defined, but no "..
183 "'port_limit' set. The svr_cap will not support dynamic port "..
187 if port_limit and svr_cap == nil then
188 error(
"start_virtio_switch_tbl(): 'port_limit' set, but no 'svr_cap'. "..
189 "This is not supported")
195 switch = svr_cap:svr()
197 switch = l:new_channel()
201 log = {
"switch",
"Blue" },
202 caps = table_override({ svr =
switch:svr() }, ext_caps or {});
206 opts[
"scheduler"] = scheduler;
209 if switch_type ==
"switch" then
210 local port_count = 0;
211 for k, v in pairs(ports)
do
212 port_count = port_count + 1;
215 port_count = port_count + port_limit
218 svr = l:start(opts,
"rom/l4vio_switch -v -p " .. port_count );
220 for k, extra_opts in pairs(ports)
do
221 if type(extra_opts) ~=
"table" then
225 ports[k] =
L4.cast(
L4.Proto.
Factory,
switch):create(
229 table.unpack(extra_opts)
233 svr = l:start(opts,
"rom/l4vio_net_p2p");
235 for k, v in pairs(ports)
do
236 ports[k] =
L4.cast(
L4.Proto.
Factory,
switch):create(0,
"ds-max=4");
246 \param options A table of parameters
248 The following keys are supported in the `options` table:
250 | table key | value |
251 | ----------- | ---------------------------------------------------------------- |
252 | `bootargs` | command line
for guest kernel |
253 | `cpus` | cpu mask |
254 | `ext_args` | additional arguments to pass to UVMM |
255 | `fdt` | file name of the device tree |
256 | `
id` | an integer identifying the VM |
257 | `jdb` | jdb capability |
258 | `kernel` | file name of the guest kernel binary |
259 | `mem` | RAM size in MiB \e or dataspace cap
for guest memory. |
260 | `mem_align` | alignment
for the guest memory in bits. Ignored
if mem is a cap. |
261 | `mon` | monitor application file name |
262 | `net` | a virtio cap, e.g.
for network |
263 | `prio` | thread priority |
264 | `ram_base` | start of guest memory |
265 | `rd` | file name of the ramdisk |
266 | `scheduler` | a scheduler cap. If used, prio and cpus are ignored. |
267 | `vbus` | the vBus to attach to the VM |
270 local nr = options.id;
272 local vbus = options.vbus;
273 local vnet = options.net;
274 local prio = options.prio;
275 local cpus = options.cpus;
276 local scheduler = options.scheduler;
277 local nonidentmem = options.nonidentmem;
280 if L4.Info.arch() ==
"arm" then
282 elseif
L4.Info.arch() ==
"arm64" then
285 align = options.mem_align or align;
289 if type(options.fdt) ~=
"table" then
290 options.fdt = { options.fdt }
292 for _,v in ipairs(options.fdt) do
293 cmdline[
#cmdline+1] = "-d" .. v;
297 if options.bootargs then
298 cmdline[#cmdline+1] =
"-c" .. options.bootargs;
302 cmdline[#cmdline+1] =
"-r" .. options.rd;
305 if options.kernel then
306 cmdline[#cmdline+1] =
"-k" .. options.kernel;
309 if options.ram_base then
310 cmdline[#cmdline+1] =
"-b" .. options.ram_base;
313 if L4.Info.arch() ==
"arm" or
L4.Info.arch() ==
"arm64" then
314 if not options.nonidentmem then
315 cmdline[#cmdline+1] =
"-i";
319 local keyb_shortcut = nil;
321 keyb_shortcut =
"key=" .. nr;
325 if type(options.mem) ==
"userdata" then
326 -- User gave us a cap. Using
this as dataspace
for guest RAM.
328 elseif type(options.mem) ==
"number" then
329 -- User gave us a number. Using
this as size
for a
new Dataspace.
330 size_mb = options.mem
331 elseif type(options.mem) ==
"string" then
332 print(
"start_vm: mem parameter '" .. options.mem ..
"' is of type string, "
333 ..
"please use integer.");
334 size_mb = tonumber(options.mem)
336 -- User did not give us any valid value.
341 local mem_flags =
L4.Mem_alloc_flags.Continuous
342 |
L4.Mem_alloc_flags.Pinned
343 |
L4.Mem_alloc_flags.Super_pages;
345 vm_ram =
L4.Env.user_factory:create(
L4.Proto.Dataspace,
346 size_mb * 1024 * 1024,
347 mem_flags, align):m(
"rw");
357 caps[
"jdb"] =
L4.Env.jdb
360 if options.ext_args then
361 for _,v in ipairs(options.ext_args) do
362 cmdline[
#cmdline+1] = v
367 log = options.log or l.log_fab:create(
L4.Proto.Log,
"vm" .. nr,
"w",
369 caps = table_override(caps, options.ext_caps or {});
373 opts[
"scheduler"] = scheduler;
378 if type(options.mon) ==
'string' then
379 -- assume
'mon' is the name of a server binary which implements the uvmm
381 mon = l:new_channel()
384 scheduler = opts.scheduler;
385 log = l.log_fab:create(
L4.Proto.Log,
"mon" .. nr),
386 caps = { mon = mon:svr() }
387 },
"rom/" .. options.mon)
389 opts.caps[
"mon"] = mon
390 elseif options.mon ~=
false then
391 opts.caps[
"mon"] = l.log_fab:create(
L4.Proto.Log,
"mon" .. nr,
"g");
394 return l:startv(opts,
"rom/uvmm", table.unpack(cmdline));
C++ Factory interface, see Factory for the C interface.
L4 low-level kernel interface.
start_virtio_switch_tbl( options)
new_sched( prio, cpu_mask, ...)
start_virtio_switch( ports, prio, cpus, switch_type, ext_caps)
set_sched( opts, prio, cpus, ...)
start_io( busses, cmdline, opts)