Hi Paul,

On Sun Apr 10, 2022 at 18:58:10 +0200, Paul Boddie wrote:
> I finally got round to experimenting with L4Re again, but in attempting to 
> investigate task creation, I seem to have some difficulties understanding the 
> mechanism by which tasks are typically created and how the l4_task_map 
> function might be used in the process.
> 
> After looking at lots of different files in the L4Re distribution, my 
> understanding of the basic mechanism is as follows:
> 
> 1. Some memory is reserved for the UTCB of a new task, perhaps using the 
> l4re_ma_alloc_align function (or equivalent) to obtain a dataspace.

No, for UTCBs there's a dedicated call l4_task_add_ku_mem in case one
needs more UTCB memory than has been initially created with
l4_factory_create_task().

> 2. A task is created using l4_factory_create_task, indicating the UTCB 
> flexpage, with this being defined as...
> 
>   l4_factory_create_task(l4re_env()->factory, new_task,
>       l4_fpage(utcb_start, utcb_log2size, L4_FPAGE_RW))

Yes. Here the flexpage defines where memory usable for UTCBs shall be
created.
 
> 3. A thread is created using l4_factory_create_thread.
> 
>   l4_factory_create_thread(l4re_env()->factory, new_thread)
> 
> 4. The thread attributes are set using the l4_thread_control API.
> 
> 5. The l4_thread_ex_regs function is used to set the instruction pointer 
> (program counter) and stack pointer of the thread.
> 
> 6. The l4_scheduler_run_thread function is used to initiate the thread.

All yes.
 
> The expectation is that the thread will immediately fault because there is no 
> memory mapped at the instruction pointer location. However, it seems to me 
> that it should be possible to use l4_task_map to make a memory region 
> available within the task's address space, although I don't ever see this 
> function used in L4Re for anything.
> 
> (The C++ API makes it difficult to perform ad-hoc searches for such low-level 
> primitives, in my view, so perhaps I am missing use of the equivalent 
> methods.)

Indeed. L4::Task::map is used, for example to map some initial
capabilities, and typically not memory.
 
> Tentatively, I would imagine that something like this might work:
> 
>   l4_task_map(new_task, L4RE_THIS_TASK_CAP,
>               l4_fpage(program_start, program_log2size, L4_FPAGE_RX),
>               task_program_start)
> 
> Here, the program payload would be loaded into the creating task at 
> program_start, but the new task would be receiving the payload at 
> task_program_start, with the configured instruction pointer location 
> occurring 
> within the receive window (after task_program_start, in other words).

Yes, this would work.

> There are, of course, many other considerations around creating tasks, which 
> I 
> have noted from looking at the different packages (libloader, l4re_kernel, 
> moe, ned), and I am aware that a few other things need to be done to start a 
> task such as...
> 
> * Defining capability selectors and mapping appropriate capabilities to the 
> new task.
> 
> * Creating a stack for the task and populating it with arguments and 
> environment information.
> 
> * Defining a suitable pager and exception handler, with this usually being 
> provided by the l4re binary, as I understand it.

Yes, this all needs to be done.
 
> Also, when actually dealing with program loading generally, I realise that 
> the 
> ELF binary needs to be interpreted and the appropriate regions associated 
> with 
> different parts of memory, this typically being handled by the region mapper/
> manager in L4Re. And there is also the matter of dynamic library loading.

Yes, indeed.
 
> But here, I am just attempting to establish the basic mechanism when a task 
> starts up. Unfortunately, the only discussion I found was this (after some 
> initial discussion about a related topic):
> 
> http://os.inf.tu-dresden.de/pipermail/l4-hackers/2014/015366.html
> 
> There are various examples in Subversion (maybe somewhere in the Git 
> repositories, too) that create tasks or threads, but I don't find them 
> particularly helpful, apparently being oriented towards very specific 
> applications. A previous example was referenced in the above thread for the 
> older L4Env system (or maybe an even earlier system):
> 
> http://os.inf.tu-dresden.de/pipermail/l4-hackers/2000/000384.html
> 
> As for why I would be wondering about such things - a question inevitably 
> asked in the first thread referenced above - I firstly want to be able to 
> understand the mechanism involved, but I also want to be able to integrate 
> work I have been doing on file paging into task creation.

I think you described it very well with your steps listed above. Also,
l4util has a l4util_create_thread() function that lists all the steps
needed to create a thread in an existing task.
 
> Although I can probably do this by customising the "app model" normally used 
> by the different loaders, it seems that I would need to construct an 
> alternative l4re binary, which is rather cumbersome and perhaps a weakness of 
> the abstractions that are provided, these being rather oriented towards 
> obtaining dataspaces via the namespace API which I don't want to have to 
> support in my filesystem.

In case you want to use other abstractions you probably need to adapt
l4re to use them such that they fit together.
 
> In any case, I wonder if there are any resources that describe the use of 
> l4_task_map and the details of the program environment within tasks.

l4_task_map() has documentation: 
https://l4re.org/doc/group__l4__task__api.html#ga8ed2ff7ba204de7c01311c22412a2063
and is a direct API to the kernel for mapping resources, defined by
l4sys. At this level, there is not really a definition of how a program
environment looks like. However, as Fiasco needs to supply its initial
programs some capabilities, those are defined
(https://l4re.org/doc/group__l4__cap__api.html#gaa7801b63edba351bad9ea8026432b5c4).
What moe and ned do, is similar, but not necessarily the same, as they
provide a more powerful interface to this
(https://l4re.org/doc/group__api__l4re__env.html) and also provide all
the functionality normal programs enjoy, like argument lists,
environment variables, etc.




Adam

_______________________________________________
l4-hackers mailing list
l4-hackers@os.inf.tu-dresden.de
https://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers

Reply via email to