------------------------------------------------------------------------
I don't want to use libloader because I'm trying to create a new process with dynamically-generated assembly (and alter it while the process is running), so I can't really output an ELF binary.
On 08/18/2014 08:50, Björn Döbel wrote:
The dataspace that prog_attach_ds() is called with is allocated by the ELF loader in libloader/include/elf.
reserve_utcb_area() is supposed to not attach a real dataspace but reserve a virtual memory area that will not be used by the new application's RM to attach any other memory, because this is where the UTCBs will later be mapped to by the kernel iirc.
I'm pretty sure I need to do this myself, since any calls to map() are causing the program to freeze (could this be because the task doesn't have its UTCB allocated yet?). I'm also not sure what to use for the destination offset of the L4::Task::map() call, so that might be the issue.
At this point your best way to do so is to use the L4::Task::map() operation on the capability of your newly created task.
How do I specify what point in the target the memory maps to? It looks like the L4::Dataspace::map() would work, but without being able to map the capability, I can't really check.
Thanks!
- Noah Zentzis
On Thu Aug 14, 2014 at 01:22:31 -0700, Noah Zentzis wrote:
I don't want to use libloader because I'm trying to create a new process with dynamically-generated assembly (and alter it while the process is running), so I can't really output an ELF binary.
On 08/18/2014 08:50, Björn Döbel wrote:
The dataspace that prog_attach_ds() is called with is allocated by the ELF loader in libloader/include/elf.
reserve_utcb_area() is supposed to not attach a real dataspace but reserve a virtual memory area that will not be used by the new application's RM to attach any other memory, because this is where the UTCBs will later be mapped to by the kernel iirc.
I'm pretty sure I need to do this myself, since any calls to map() are causing the program to freeze (could this be because the task doesn't have its UTCB allocated yet?). I'm also not sure what to use for the destination offset of the L4::Task::map() call, so that might be the issue.
At this point your best way to do so is to use the L4::Task::map() operation on the capability of your newly created task.
How do I specify what point in the target the memory maps to? It looks like the L4::Dataspace::map() would work, but without being able to map the capability, I can't really check.
Typical arguments for L4::Task::map for memory are (omitting cache attributes etc.): l4_msgtag_t t; t = dst_task->map(src_task, l4_fpage(src_address, L4_PAGESHIFT, L4_FPAGE_RWX), dst_address); if (l4_error(t)) printf("error: %d\n", l4_error(t)); dst_task and src_task are L4::CapL4::Task types and src_address and dst_address are unsigned longs with the virtual address for each task. L4_PAGESHIFT: Map one page, increase for more. Alternative for L4_FPAGE_RWX is L4_FPAGE_RX. For L4::task::map you do not need any cooperation from dst_task. Mapping caps works similarly: t = dst_task->map(src_task, l4_obj_fpage(src_cap, 0, L4_FPAGE_RW), l4_map_obj_control(dst_cap, L4_MAP_ITEM_MAP));
When a programs runs it will also generate pagefault IPCs to the pager which must be replied with the proper mapper. For that the pager cap must be setup in the target, with a task->map call. So now I do not know how exactly you want to proceed, so I hope this info is helpful.
Adam
On 08/14/2014 03:01 PM, Adam Lackorzynski wrote:
Typical arguments for L4::Task::map for memory are (omitting cache attributes etc.): l4_msgtag_t t; t = dst_task->map(src_task, l4_fpage(src_address, L4_PAGESHIFT, L4_FPAGE_RWX), dst_address); if (l4_error(t)) printf("error: %d\n", l4_error(t)); For L4::task::map you do not need any cooperation from dst_task. Mapping caps works similarly: t = dst_task->map(src_task, l4_obj_fpage(src_cap, 0, L4_FPAGE_RW), l4_map_obj_control(dst_cap, L4_MAP_ITEM_MAP));
When a programs runs it will also generate pagefault IPCs to the pager which must be replied with the proper mapper. For that the pager cap must be setup in the target, with a task->map call.
I might be missing a step when setting up my task, but trying to map capabilities in the same way that libloader does seems to cause the parent process to freeze:
printf("This message is printed\n"); task->map(L4Re::This_task, env->mem_alloc().fpage(), env->mem_alloc().snd_base()); printf("This message is never printed\n");
Do I need to set up the UTCB beforehand or do some other kind of setup before mapping capabilities? I see the prog_attach_utcb_area() function in libloader, but can't figure out how it ever gets called or whether I actually need to do so. Also, libloader's start_prog() function seems to perform the mapping immediately after creating the task and thread, so I'm confused about why L4::Task::map() keeps freezing the parent process.
- Noah Zentzis
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
printf("This message is printed\n"); task->map(L4Re::This_task, env->mem_alloc().fpage(), env->mem_alloc().snd_base()); printf("This message is never printed\n");
env->mem_alloc() only gives you the memory allocator. You will have to call env->mem_alloc().alloc() to actually allocate a dataspace. I'm afraid your call hangs, because L4Re tries to translate the .fpage() call into an IPC to the memory allocator, which does not reply because it is no idea what you want from it.
Also, do not call the allocator twice within the function call, because then you would obtain two different dataspaces and this is not what you want here. Better do
L4:Cap<Dataspace> x = L4Re::Util::cap_alloc.allocL4::Dataspace(); long alloc = L4Re::Env::env()->mem_alloc.alloc(size, x); if (!x.is_valid()) { // handle error }
Do I need to set up the UTCB beforehand or do some other kind of setup before mapping capabilities?
No.
Bjoern
l4-hackers@os.inf.tu-dresden.de