Hello hackers,
I'm trying to run Fiasco.OC in secure world and Linux in non-secure world on i.MX6Q. For this I'm using the TrustZone example (pkg/examples/sys/vm-tz). To secure world I have given 128MB RAM starting from 0x10000000 and I modified the example to give NS world 256MB starting from 0x20000000. I've replaced atags with dtb of my board and it is copied to NS side like kernel and initrd.
At first I encountered runtime exception, which I fixed by implementing following to arm_em_tz builds Thread::arch_ext_vcpu_enabled() { return true; }
Now I'm having problems at early stages of NS boot, where Linux kernel is checking for the dtb magic. The code loads the dtb magic from the address I'm giving in r2 register (0x21000000), but the magic value usually have one byte or all of them incorrect.
I've used JDB to dump the area of dtb after hitting that error and it shows the dtb magic properly. So for some reason the NS-world gets mangled value. Any idea what might be causing this?
Thanks, Markku
On Tue Dec 23, 2014 at 15:39:09 +0200, Markku Ahvenjärvi wrote:
I'm trying to run Fiasco.OC in secure world and Linux in non-secure world on i.MX6Q. For this I'm using the TrustZone example (pkg/examples/sys/vm-tz). To secure world I have given 128MB RAM starting from 0x10000000 and I modified the example to give NS world 256MB starting from 0x20000000. I've replaced atags with dtb of my board and it is copied to NS side like kernel and initrd.
At first I encountered runtime exception, which I fixed by implementing following to arm_em_tz builds Thread::arch_ext_vcpu_enabled() { return true; }
Now I'm having problems at early stages of NS boot, where Linux kernel is checking for the dtb magic. The code loads the dtb magic from the address I'm giving in r2 register (0x21000000), but the magic value usually have one byte or all of them incorrect.
I've used JDB to dump the area of dtb after hitting that error and it shows the dtb magic properly. So for some reason the NS-world gets mangled value. Any idea what might be causing this?
Sounds like a caching issue.
Adam
On 05.01.2015 01:22, Adam Lackorzynski wrote:
On Tue Dec 23, 2014 at 15:39:09 +0200, Markku Ahvenjärvi wrote:
I'm trying to run Fiasco.OC in secure world and Linux in non-secure world on i.MX6Q. For this I'm using the TrustZone example (pkg/examples/sys/vm-tz). To secure world I have given 128MB RAM starting from 0x10000000 and I modified the example to give NS world 256MB starting from 0x20000000. I've replaced atags with dtb of my board and it is copied to NS side like kernel and initrd.
At first I encountered runtime exception, which I fixed by implementing following to arm_em_tz builds Thread::arch_ext_vcpu_enabled() { return true; }
Now I'm having problems at early stages of NS boot, where Linux kernel is checking for the dtb magic. The code loads the dtb magic from the address I'm giving in r2 register (0x21000000), but the magic value usually have one byte or all of them incorrect.
I've used JDB to dump the area of dtb after hitting that error and it shows the dtb magic properly. So for some reason the NS-world gets mangled value. Any idea what might be causing this?
Sounds like a caching issue.
Adam
Hello,
Yes, I was assuming that it is caching issue. The copyblob-function in the example cleans cache by calling l4_cache_clean_data, so the data should be in RAM.
Linux kernel expects D-cache and MMU to be disabled on boot up, how is it done in TrustZone? By initializing banked cp15 registers?
Can you point where these are done? I'm using 20140928 snapshot.
Thanks, Markku
On Mon Jan 05, 2015 at 16:30:42 +0200, Markku Ahvenjärvi wrote:
On 05.01.2015 01:22, Adam Lackorzynski wrote:
On Tue Dec 23, 2014 at 15:39:09 +0200, Markku Ahvenjärvi wrote:
I'm trying to run Fiasco.OC in secure world and Linux in non-secure world on i.MX6Q. For this I'm using the TrustZone example (pkg/examples/sys/vm-tz). To secure world I have given 128MB RAM starting from 0x10000000 and I modified the example to give NS world 256MB starting from 0x20000000. I've replaced atags with dtb of my board and it is copied to NS side like kernel and initrd.
At first I encountered runtime exception, which I fixed by implementing following to arm_em_tz builds Thread::arch_ext_vcpu_enabled() { return true; }
Now I'm having problems at early stages of NS boot, where Linux kernel is checking for the dtb magic. The code loads the dtb magic from the address I'm giving in r2 register (0x21000000), but the magic value usually have one byte or all of them incorrect.
I've used JDB to dump the area of dtb after hitting that error and it shows the dtb magic properly. So for some reason the NS-world gets mangled value. Any idea what might be causing this?
Sounds like a caching issue.
Adam
Yes, I was assuming that it is caching issue. The copyblob-function in the example cleans cache by calling l4_cache_clean_data, so the data should be in RAM.
Linux kernel expects D-cache and MMU to be disabled on boot up, how is it done in TrustZone? By initializing banked cp15 registers?
Can you point where these are done? I'm using 20140928 snapshot.
I'm not sure I'm getting the question right. Do you mean the non-secure or the secure side? Anyway, yes, cp15 is used independently of the side. It should not be switched on on the ns side initially, right?
Adam
Hello,
is there any Flexpage reference example?
I want to push a buffer, i.e. a pointer and the size of it to another task.
I tried the following, but well...i guess i miss some docu here.
l4_fpage_t fp = l4_fpage ( buffer, size, L4_FPAGE_RW); ioStream << fp;
Thanks again,
ba_f
On Fri Jan 09, 2015 at 19:11:48 +0100, ba_f wrote:
is there any Flexpage reference example?
I want to push a buffer, i.e. a pointer and the size of it to another task.
Put it in:
iostream << L4::Ipc::buf_cp_out(pointer, len);
Get it out:
iostream >> L4::Ipc::buf_cp_in(buf, len_of_buf);
Alternatively L4::Ipc::buf_in(pointer, len) without copying, i.e. you just get the pointer to the data still in the UTCB.
Adam
Hello Hackers,
is it possible to run a bash-script within a l4re-App? Or do i need l4Linux for this.
Let me explain my problem:
I have a l4re-App myServer. I'm testing myServer with another l4re-App, called myClient.
Now, the legacy code provides a regression test, a bash-script setting evironment variables and starting programs. Some of the tests depend on each other. E.g. init_server(); calc();.
What whould be the simplest way to run this script.
Of course all test-programs can already IPC with myServer (by using a lib).
Thanks again,
ba_f
Hi,
is it possible to run a bash-script within a l4re-App? Or do i need l4Linux for this.
To run the Bash script natively on L4Re you will require a console as well as a port of the Bash itself.
Let me explain my problem:
I have a l4re-App myServer. I'm testing myServer with another l4re-App, called myClient.
Now, the legacy code provides a regression test, a bash-script setting evironment variables and starting programs. Some of the tests depend on each other. E.g. init_server(); calc();.
What whould be the simplest way to run this script.
Of course all test-programs can already IPC with myServer (by using a lib).
I think the easiest way would be to transform the test script into a Lua init script. Then you can run the different tests sequentially like this:
t1 = L4.default_ldr:startv(... test 1 setup...); t1:wait()
t2 = L4.default_ldr:startv(... test 2 setup ...); t2:wait()
-> the wait() calls in between make sure that each setup is run only after the previous one terminated.
Hth, Bjoern
Hello Hackers,
the IPC-Stream seems to be limited to 252 objects, for one ios.call().
How can i double that size, so that more objects fit in one IOStream?
Thank U,
ba_f
On Sun Jan 25, 2015 at 14:50:01 +0100, ba_f wrote:
the IPC-Stream seems to be limited to 252 objects, for one ios.call().
Indeed, it is limited.
How can i double that size, so that more objects fit in one IOStream?
The size could be increased by changing both the kernel and user-level constants accordingly, at least up to a certain limit until even more needs to be done. Now, to exchange more data than fits in a UTCB, we usually recommend shared memory. Would that be an option in your case? Another option could be to use multiple IPCs to transmit the data in chunks.
Adam
Am 2015-01-27 01:04, schrieb Adam Lackorzynski:
On Sun Jan 25, 2015 at 14:50:01 +0100, ba_f wrote:
the IPC-Stream seems to be limited to 252 objects, for one ios.call().
Indeed, it is limited.
How can i double that size, so that more objects fit in one IOStream?
The size could be increased by changing both the kernel and user-level constants accordingly, at least up to a certain limit until even more needs to be done. Now, to exchange more data than fits in a UTCB, we usually recommend shared memory. Would that be an option in your case? Another option could be to use multiple IPCs to transmit the data in chunks.
Hello,
Changing kernel constants seems a bit dirty, isn't it?
But tell me some about shared memory, please.
1.) is there an example, anywhere? 2.) Maybe on a further step, i'm planning to adapt my project to TrustZone. How does a communication between TrustZone Worlds work? Is Shared Mem. a better starting point than l4-IPC, when going to TrustZone.
Thanks.
On Tue Jan 27, 2015 at 15:41:28 +0100, ba_f wrote:
Changing kernel constants seems a bit dirty, isn't it?
Yes, it's not recommended.
But tell me some about shared memory, please.
1.) is there an example, anywhere?
There's at least the shmc example for the lib. But in a more simple form it is actually not needed. Have a dataspace, make it available to two tasks, and it's shared memory.
2.) Maybe on a further step, i'm planning to adapt my project to TrustZone. How does a communication between TrustZone Worlds work? Is Shared Mem. a better starting point than l4-IPC, when going to TrustZone.
Depends, shared memory can be one way of doing it and it's reasonable using it. When talking of TZ it's about data exchange between the two worlds? That would not be "classical IPC" anyway since two independent systems are involved here.
Adam
Am 2015-01-31 00:17, schrieb Adam Lackorzynski:
But tell me some about shared memory, please.
1.) is there an example, anywhere?
There's at least the shmc example for the lib. But in a more simple form it is actually not needed. Have a dataspace, make it available to two tasks, and it's shared memory.
Ok, i prefer using the shmc.h.
But, the example (libs/shmc) runs two threads. I would like to use shared_mem between two tasks.
Is it possible to use shmc.h to share memory between tasks?
I tried to partition 'thread_producer()' and 'thread_consume()' to two Tasks. But as expected, task_client doesn't know the shared_mem which task_server created.
Thanks
On Wed Feb 04, 2015 at 13:28:11 +0100, ba_f wrote:
Am 2015-01-31 00:17, schrieb Adam Lackorzynski:
But tell me some about shared memory, please.
1.) is there an example, anywhere?
There's at least the shmc example for the lib. But in a more simple form it is actually not needed. Have a dataspace, make it available to two tasks, and it's shared memory.
Ok, i prefer using the shmc.h.
But, the example (libs/shmc) runs two threads. I would like to use shared_mem between two tasks.
Is it possible to use shmc.h to share memory between tasks?
Yes.
I tried to partition 'thread_producer()' and 'thread_consume()' to two Tasks. But as expected, task_client doesn't know the shared_mem which task_server created.
The key is the sharing as you already noticed. The sharing goes via the namespace given to l4shmc_create. Give both programs the same namespace (created in ned's script) and they should be able to share.
Adam
Am 2015-02-11 00:10, schrieb Adam Lackorzynski:
On Wed Feb 04, 2015 at 13:28:11 +0100, ba_f wrote:
Am 2015-01-31 00:17, schrieb Adam Lackorzynski:
But tell me some about shared memory, please.
1.) is there an example, anywhere?
There's at least the shmc example for the lib. But in a more simple form it is actually not needed. Have a dataspace, make it available to two tasks, and it's shared memory.
Ok, i prefer using the shmc.h.
But, the example (libs/shmc) runs two threads. I would like to use shared_mem between two tasks.
Is it possible to use shmc.h to share memory between tasks?
Yes.
I tried to partition 'thread_producer()' and 'thread_consume()' to two Tasks. But as expected, task_client doesn't know the shared_mem which task_server created.
The key is the sharing as you already noticed. The sharing goes via the namespace given to l4shmc_create. Give both programs the same namespace (created in ned's script) and they should be able to share.
Adam
Hello after long time,
the ned's script you mentioned is the lua .cfg, isnt it? Giving them the same namespace, doesn't this make them ONE task, ie. share ALL memory? If not, can u give me an example how to share just 4kB, for example?
I've also seen a flexpage example: examples/libs/l4re/streammap/. Is this a nice example for a 4kB Flexpage?
I need to transmit a 4kB buffer and 4kB as response. What is L4's most elegant way to do so?
Thank You.
On Mon May 04, 2015 at 19:23:01 +0200, ba_f wrote:
the ned's script you mentioned is the lua .cfg, isnt it?
yes.
Giving them the same namespace, doesn't this make them ONE task, ie. share ALL memory?
No. They (just) share the namespace, and there could be multiple namespaces which one can share between tasks.
If not, can u give me an example how to share just 4kB, for example?
I've also seen a flexpage example: examples/libs/l4re/streammap/. Is this a nice example for a 4kB Flexpage?
I need to transmit a 4kB buffer and 4kB as response. What is L4's most elegant way to do so?
Elegant depends probably :) One way without much bells and whistles is creating a dataspace in the config script and attaching it on each side: local ds = L4.Env.mem_alloc:create(L4.Proto.Dataspace, 4096);
L4.default_loader:start({ caps = { shmds = ds:m("rw"); }}, "rom/one"); L4.default_loader:start({ caps = { shmds = ds:m("rw"); }}, "rom/two");
Then attach it via L4Re::Rm::attach(). I guess you also want some kind of notification. You could use standard IPC for that, or, better, use Irqs, i.e. two, one for each side. libshmc wraps this, esp. settings this up incl. the notification via Irqs.
Adam
Am 2015-05-10 23:07, schrieb Adam Lackorzynski:
I need to transmit a 4kB buffer and 4kB as response. What is L4's most elegant way to do so?
Elegant depends probably :) One way without much bells and whistles is creating a dataspace in the config script and attaching it on each side: local ds = L4.Env.mem_alloc:create(L4.Proto.Dataspace, 4096);
L4.default_loader:start({ caps = { shmds = ds:m("rw"); }}, "rom/one"); L4.default_loader:start({ caps = { shmds = ds:m("rw"); }}, "rom/two");
Then attach it via L4Re::Rm::attach(). I guess you also want some kind of notification. You could use standard IPC for that, or, better, use Irqs, i.e. two, one for each side. libshmc wraps this, esp. settings this up incl. the notification via Irqs.
Allright, thanks.
But, i still have a question about Flexpages. So my problem with the shared DS is that i have one server but multiple clients.
I could use one DS for each client, but this might waste too much MEM for an embedded system. (I admit, this is a bit of a theoretical problem, since todays embedded systems are so "big" and strong.) I also could use only one DS on the server side, which any client uses, separately. But this solution is not an option if there are sensitive data transmitted between client and server.
So is Flexpage the way to go? Is this even the reason why flexpage exists, beside shared mem.
Is Flexpage suitable for 4kB? Do u have an example design? Maybe this one: pkg/examples/libs/l4re/streammap/.
Thanks, ba_f
On Tue May 12, 2015 at 13:30:21 +0200, ba_f wrote:
Am 2015-05-10 23:07, schrieb Adam Lackorzynski:
I need to transmit a 4kB buffer and 4kB as response. What is L4's most elegant way to do so?
Elegant depends probably :) One way without much bells and whistles is creating a dataspace in the config script and attaching it on each side: local ds = L4.Env.mem_alloc:create(L4.Proto.Dataspace, 4096);
L4.default_loader:start({ caps = { shmds = ds:m("rw"); }}, "rom/one"); L4.default_loader:start({ caps = { shmds = ds:m("rw"); }}, "rom/two");
Then attach it via L4Re::Rm::attach(). I guess you also want some kind of notification. You could use standard IPC for that, or, better, use Irqs, i.e. two, one for each side. libshmc wraps this, esp. settings this up incl. the notification via Irqs.
Allright, thanks.
But, i still have a question about Flexpages. So my problem with the shared DS is that i have one server but multiple clients.
I could use one DS for each client, but this might waste too much MEM for an embedded system. (I admit, this is a bit of a theoretical problem, since todays embedded systems are so "big" and strong.) I also could use only one DS on the server side, which any client uses, separately. But this solution is not an option if there are sensitive data transmitted between client and server.
You see the options yourself, good. So if the clients shall not see others clients data, you need to use different shared memories for each client.
So is Flexpage the way to go? Is this even the reason why flexpage exists, beside shared mem.
Flexpages are a base mechanism, e.g. to map memory. For your use-case dataspaces are just fine. Your smallest shared memory is 4kb, whether it's a dataspace or done by hand (mapping pages yourself). Dataspaces implement low-level work (with flexpages) so that we do not need to do it again and again.
Adam
Am 2015-05-10 23:07, schrieb Adam Lackorzynski:
I need to transmit a 4kB buffer and 4kB as response. What is L4's most elegant way to do so?
Elegant depends probably :) One way without much bells and whistles is creating a dataspace in the config script and attaching it on each side: local ds = L4.Env.mem_alloc:create(L4.Proto.Dataspace, 4096);
L4.default_loader:start({ caps = { shmds = ds:m("rw"); }}, "rom/one"); L4.default_loader:start({ caps = { shmds = ds:m("rw"); }}, "rom/two");
Then attach it via L4Re::Rm::attach(). I guess you also want some kind of notification. You could use standard IPC for that, or, better, use Irqs, i.e. two, one for each side. libshmc wraps this, esp. settings this up incl. the notification via Irqs.
Adam
Hi Adam,
i decided not to use libshmc and do it "manually" with Dataspace and IRQ, because i think this comes closest to the communication between TrustZone worlds. It's the best starting point before pushing the project to TrustZone (ie. Normal world Client and Secure Server), isn't it?
Anyway, i need some more help.
i tried this:
L4::CapL4Re::Dataspace ds = L4Re::Env::env()->get_capL4Re::Dataspace("shmds");
l4_addr_t startAddr = 0; if ( L4Re::Env::env()->rm()->attach( &startAddr, 4096, L4Re::Rm::In_area | L4Re::Rm::Eager_map, ds, 0, L4_PAGESHIFT) ) printf("Error");
First, get_capL4Re::Dataspace("shmds") leads to a kernel warning.
KERNEL: Warning: nothing mapped: (Obj_space)
i guess, i dont understand that capability stuff entirely. What causes this warning?
Second, my C++ skills are a bit moderate, unfortunately. So, is this right?
L4Re::Env::env()->rm()->attach( &startAddr, 4096, flags, ds, 0, L4_PAGESHIFT)
Or how to call L4Re::Rm::attach()?
Thanks again, ba_f
Hi ba_f,
On Wed May 20, 2015 at 11:40:27 +0200, ba_f wrote:
i decided not to use libshmc and do it "manually" with Dataspace and IRQ, because i think this comes closest to the communication between TrustZone worlds. It's the best starting point before pushing the project to TrustZone (ie. Normal world Client and Secure Server), isn't it?
Indeed, that really comes closer to that.
Anyway, i need some more help.
i tried this:
L4::CapL4Re::Dataspace ds = L4Re::Env::env()->get_capL4Re::Dataspace("shmds");
l4_addr_t startAddr = 0; if ( L4Re::Env::env()->rm()->attach( &startAddr, 4096, L4Re::Rm::In_area | L4Re::Rm::Eager_map, ds, 0, L4_PAGESHIFT) ) printf("Error");
First, get_capL4Re::Dataspace("shmds") leads to a kernel warning.
KERNEL: Warning: nothing mapped: (Obj_space)
i guess, i dont understand that capability stuff entirely. What causes this warning?
Generally this warning is printed when trying to pass a capability (or memory) around but the source is empty. This is typically a programming error. Secondly I think the warning does not come from the get_cap call. That call just gets the cap from the environment where the program startup has already stored it. "shmds" must be a cap that has been specified in the "caps" table of your program in the lua script.
Second, my C++ skills are a bit moderate, unfortunately. So, is this right?
L4Re::Env::env()->rm()->attach( &startAddr, 4096, flags, ds, 0, L4_PAGESHIFT)
Or how to call L4Re::Rm::attach()?
With flags == L4Re::Rm::Search_addr it should be fine (plus: you can omit the last two parameters). Don't use the In_area, you need to alloc such an area beforehand! Further, you need to add L4Re::Rm::Search_addr, otherwise attach will try to put that memory at 0 (startAddr == 0) which is not good to do.
Adam
Am 2015-05-27 00:11, schrieb Adam Lackorzynski:
Hi ba_f,
On Wed May 20, 2015 at 11:40:27 +0200, ba_f wrote:
i decided not to use libshmc and do it "manually" with Dataspace and IRQ, because i think this comes closest to the communication between TrustZone worlds. It's the best starting point before pushing the project to TrustZone (ie. Normal world Client and Secure Server), isn't it?
Indeed, that really comes closer to that.
Anyway, i need some more help.
First, get_capL4Re::Dataspace("shmds") leads to a kernel warning.
KERNEL: Warning: nothing mapped: (Obj_space)
i guess, i dont understand that capability stuff entirely. What causes this warning?
Generally this warning is printed when trying to pass a capability (or memory) around but the source is empty. This is typically a programming error. Secondly I think the warning does not come from the get_cap call. That call just gets the cap from the environment where the program startup has already stored it. "shmds" must be a cap that has been specified in the "caps" table of your program in the lua script.
Adam
Ok, works now. (The Warning appeared because i did commented out 'server.loop()' and main() did exit with 'return 0').
Anyway, i still have some question about that IRQ, and i would be grateful if u could answer them, too.
I found two examples with IRQ: 'l4/pkg/examples/sys/map_irq' and 'l4/pkg/examples/libs/l4re/c++/shared_ds'. I guess i could easily adapt them.
What makes we wonder, is that both examples make use of 'L4::Ipc::Iostream'. Actually, i dont see any difference between IRQ & IPC, since both are registered servers using L4.default_loader:new_channel(). I guess, IPC is build upon IRQ?
However, you said that IPC is not possible between TrustZone worlds, because each world has a separate microkernel instance. I reason there is no L4.default_loader:new_channel() possible between worlds? Do u have an example design for TZ communication?
Thanks alot, ba_f
Hi,
On 05/27/2015 10:35 PM, ba_f wrote:
Am 2015-05-27 00:11, schrieb Adam Lackorzynski:
Hi ba_f,
On Wed May 20, 2015 at 11:40:27 +0200, ba_f wrote:
i decided not to use libshmc and do it "manually" with Dataspace and IRQ, because i think this comes closest to the communication between TrustZone worlds. It's the best starting point before pushing the project to TrustZone (ie. Normal world Client and Secure Server), isn't it?
Indeed, that really comes closer to that.
Anyway, i need some more help.
First, get_capL4Re::Dataspace("shmds") leads to a kernel warning.
KERNEL: Warning: nothing mapped: (Obj_space)
i guess, i dont understand that capability stuff entirely. What causes this warning?
Generally this warning is printed when trying to pass a capability (or memory) around but the source is empty. This is typically a programming error. Secondly I think the warning does not come from the get_cap call. That call just gets the cap from the environment where the program startup has already stored it. "shmds" must be a cap that has been specified in the "caps" table of your program in the lua script.
Adam
Ok, works now. (The Warning appeared because i did commented out 'server.loop()' and main() did exit with 'return 0').
Anyway, i still have some question about that IRQ, and i would be grateful if u could answer them, too.
I found two examples with IRQ: 'l4/pkg/examples/sys/map_irq' and 'l4/pkg/examples/libs/l4re/c++/shared_ds'. I guess i could easily adapt them.
What makes we wonder, is that both examples make use of 'L4::Ipc::Iostream'. Actually, i dont see any difference between IRQ & IPC, since both are registered servers using L4.default_loader:new_channel().
I think here is a little bit of misconception. L4.default_loader:new_channel() creates a new IPC gate (from Lua) which can be used by threads to send IPC messages. (Virtual) IRQs are a different type of kernel object but the trigger() function eventually maps to IPC. You can read about the different kernel objects here [1]. You should also make yourself familiar with the Factory API which is used to create new kernel objects.
I guess, IPC is build upon IRQ?
However, you said that IPC is not possible between TrustZone worlds, because each world has a separate microkernel instance. I reason there is no L4.default_loader:new_channel() possible between worlds? Do u have an example design for TZ communication?
Your observation is right. Essentially you have to use the 'smc' instruction (secure monitor call) to initiate a mode switch. The exception handler on the secure side then can evaluate the SMC value to determine the service requested.
Matthias.
[1] https://os.inf.tu-dresden.de/L4Re/doc/index.html#l4re_concepts_fiasco_kobjec...
Am 2015-05-28 08:43, schrieb Matthias Lange:
Hi,
On 05/27/2015 10:35 PM, ba_f wrote:
Am 2015-05-27 00:11, schrieb Adam Lackorzynski:
Hi ba_f,
On Wed May 20, 2015 at 11:40:27 +0200, ba_f wrote:
i decided not to use libshmc and do it "manually" with Dataspace and IRQ, because i think this comes closest to the communication between TrustZone worlds. It's the best starting point before pushing the project to TrustZone (ie. Normal world Client and Secure Server), isn't it?
Indeed, that really comes closer to that.
Anyway, i still have some question about that IRQ, and i would be grateful if u could answer them, too.
I found two examples with IRQ: 'l4/pkg/examples/sys/map_irq' and 'l4/pkg/examples/libs/l4re/c++/shared_ds'. I guess i could easily adapt them.
What makes we wonder, is that both examples make use of 'L4::Ipc::Iostream'. Actually, i dont see any difference between IRQ & IPC, since both are registered servers using L4.default_loader:new_channel().
I think here is a little bit of misconception. L4.default_loader:new_channel() creates a new IPC gate (from Lua) which can be used by threads to send IPC messages. (Virtual) IRQs are a different type of kernel object but the trigger() function eventually maps to IPC. You can read about the different kernel objects here [1]. You should also make yourself familiar with the Factory API which is used to create new kernel objects.
I guess, IPC is build upon IRQ?
However, you said that IPC is not possible between TrustZone worlds, because each world has a separate microkernel instance. I reason there is no L4.default_loader:new_channel() possible between worlds? Do u have an example design for TZ communication?
Your observation is right. Essentially you have to use the 'smc' instruction (secure monitor call) to initiate a mode switch. The exception handler on the secure side then can evaluate the SMC value to determine the service requested.
Matthias.
[1] https://os.inf.tu-dresden.de/L4Re/doc/index.html#l4re_concepts_fiasco_kobjec...
Ok,
i found the following thread, making things clearer. http://os.inf.tu-dresden.de/pipermail/l4-hackers/2014/006521.html
In the examples mentioned, IPC is used to transfer the IRQ and DS capabilities from the client to the server, aye?
As i want to go for TrustZone, i dont wanna use IPC. Hence, i have to create a virtual IRQ in Ned's script, so that both Tasks know the IRQ namespace?
If this is any correct, then i miss the right syntax. I tried the following, but failed:
local virtual_smc = L4.Env.Irq:create();
ld:start({ caps = { irq = virtual_smc:svr()},}, "rom/server");
ld:start({ caps = { irq = virtual_smc },}, "rom/client");
Thanks to all of u, ba_f
Hi,
On 05/28/2015 06:24 PM, ba_f wrote:
Am 2015-05-28 08:43, schrieb Matthias Lange:
Hi,
On 05/27/2015 10:35 PM, ba_f wrote:
Am 2015-05-27 00:11, schrieb Adam Lackorzynski:
Hi ba_f,
On Wed May 20, 2015 at 11:40:27 +0200, ba_f wrote:
i decided not to use libshmc and do it "manually" with Dataspace and IRQ, because i think this comes closest to the communication between TrustZone worlds. It's the best starting point before pushing the project to TrustZone (ie. Normal world Client and Secure Server), isn't it?
Indeed, that really comes closer to that.
Anyway, i still have some question about that IRQ, and i would be grateful if u could answer them, too.
I found two examples with IRQ: 'l4/pkg/examples/sys/map_irq' and 'l4/pkg/examples/libs/l4re/c++/shared_ds'. I guess i could easily adapt them.
What makes we wonder, is that both examples make use of 'L4::Ipc::Iostream'. Actually, i dont see any difference between IRQ & IPC, since both are registered servers using L4.default_loader:new_channel().
I think here is a little bit of misconception. L4.default_loader:new_channel() creates a new IPC gate (from Lua) which can be used by threads to send IPC messages. (Virtual) IRQs are a different type of kernel object but the trigger() function eventually maps to IPC. You can read about the different kernel objects here [1]. You should also make yourself familiar with the Factory API which is used to create new kernel objects.
I guess, IPC is build upon IRQ?
However, you said that IPC is not possible between TrustZone worlds, because each world has a separate microkernel instance. I reason there is no L4.default_loader:new_channel() possible between worlds? Do u have an example design for TZ communication?
Your observation is right. Essentially you have to use the 'smc' instruction (secure monitor call) to initiate a mode switch. The exception handler on the secure side then can evaluate the SMC value to determine the service requested.
Matthias.
[1] https://os.inf.tu-dresden.de/L4Re/doc/index.html#l4re_concepts_fiasco_kobjec...
Ok,
i found the following thread, making things clearer. http://os.inf.tu-dresden.de/pipermail/l4-hackers/2014/006521.html
In the examples mentioned, IPC is used to transfer the IRQ and DS capabilities from the client to the server, aye?
Correct.
As i want to go for TrustZone, i dont wanna use IPC. Hence, i have to create a virtual IRQ in Ned's script, so that both Tasks know the IRQ namespace?
No, this is not possible. You run an independent kernel and user land on both the secure and non-secure side. The communication between both worlds is more like a system call interface where the non-secure side prepares a request and then issues the 'smc' instruction. This results in a context switch to the secure side where the kernel "sees" the smc instruction in form of an IRQ.
Matthias.
If this is any correct, then i miss the right syntax. I tried the following, but failed:
local virtual_smc = L4.Env.Irq:create();
ld:start({ caps = { irq = virtual_smc:svr()},}, "rom/server");
ld:start({ caps = { irq = virtual_smc },}, "rom/client");
Thanks to all of u, ba_f
l4-hackers mailing list l4-hackers@os.inf.tu-dresden.de http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers
Am 2015-06-02 12:04, schrieb Matthias Lange:
As i want to go for TrustZone, i dont wanna use IPC. Hence, i have to create a virtual IRQ in Ned's script, so that both Tasks know the IRQ namespace?
No, this is not possible. You run an independent kernel and user land on both the secure and non-secure side. The communication between both worlds is more like a system call interface where the non-secure side prepares a request and then issues the 'smc' instruction. This results in a context switch to the secure side where the kernel "sees" the smc instruction in form of an IRQ.
Matthias.
Ok, thank u.
i guess i'm lost without any TrustZone reference design...
Anyway, one last word about my Ned script, please.
Do i really have to transfer my IRQ over IPC (in no TrustZone design)? At least in /pkg/ned/doc/tutorial.lua there is 'Irq' mentioned as a 'useful constant'. So i guess i can define IRQ in Lua, but i miss correct syntax.
If this is any correct, then i miss the right syntax. I tried the following, but failed:
local virtual_smc = L4.Env.Irq:create();
ld:start({ caps = { irq = virtual_smc:svr()},}, "rom/server");
ld:start({ caps = { irq = virtual_smc },}, "rom/client");
Thanks to all of u, ba_f
greets, ba_f
On Wed Jun 10, 2015 at 14:01:01 +0200, ba_f wrote:
Am 2015-06-02 12:04, schrieb Matthias Lange:
As i want to go for TrustZone, i dont wanna use IPC. Hence, i have to create a virtual IRQ in Ned's script, so that both Tasks know the IRQ namespace?
No, this is not possible. You run an independent kernel and user land on both the secure and non-secure side. The communication between both worlds is more like a system call interface where the non-secure side prepares a request and then issues the 'smc' instruction. This results in a context switch to the secure side where the kernel "sees" the smc instruction in form of an IRQ.
Matthias.
Ok, thank u.
i guess i'm lost without any TrustZone reference design...
Anyway, one last word about my Ned script, please.
Do i really have to transfer my IRQ over IPC (in no TrustZone design)?
Yes. There's one irq, one side triggers it, the other side receives it. Both sides need to have access to the same irq, that's why one has to create it and give access to the other side. And that's what's done with the IPC.
At least in /pkg/ned/doc/tutorial.lua there is 'Irq' mentioned as a 'useful constant'. So i guess i can define IRQ in Lua, but i miss correct syntax.
IRQs are typically not created in the lua script but on the client side and shared with the server. See the map_irq example how it can be done.
Adam
Hello,
is it possible to dlopen() a shared lib?
I'd like to execute a program that is started like this: "Example: ./gen_random -d .libs/libsim.so"
I know how to start a program with arguments. But where could i put my shared lib, and which path should i pass to the executing program?
Thanks,
ba_f
Hi,
On Fri Jun 19, 2015 at 16:15:54 +0200, ba_f wrote:
is it possible to dlopen() a shared lib?
Yes.
I'd like to execute a program that is started like this: "Example: ./gen_random -d .libs/libsim.so"
I know how to start a program with arguments. But where could i put my shared lib, and which path should i pass to the executing program?
All files/modules you put in your modiles.list file entry show up under rom/. So it should be: ./gen_random -d rom/libsim.so
Adam
Am 2015-06-25 21:49, schrieb Adam Lackorzynski:
Hi,
On Fri Jun 19, 2015 at 16:15:54 +0200, ba_f wrote:
is it possible to dlopen() a shared lib?
Yes.
I'd like to execute a program that is started like this: "Example: ./gen_random -d .libs/libsim.so"
I know how to start a program with arguments. But where could i put my shared lib, and which path should i pass to the executing program?
All files/modules you put in your modiles.list file entry show up under rom/. So it should be: ./gen_random -d rom/libsim.so
Adam
Ok, thanks Adam.
Yet, i have another (maybe trivial) question.
How do i build a dynamic(!) shared lib for Fiasco, which is loadable with dlopen()?
I tried to add the -fPIC flag in the lib Makefile, but it didn't work out.
[Makefile]
CPPFLAGS += -fPIC LOADABLE_MODULE=1
include $(L4DIR)/mk/lib.mk [/Makefile]
[c] dl = dlopen(rom/lib.so, RTLD_NOW); if (dl == NULL){ fprintf(stderr, "dlopen failed: %s\n", dlerror()); [/c]
Output is: dlopen failed: (null)
I can assure that dlopen() finds the lib.so, because dlerror() gives an other output when using a different name (e.g. dlopen(rom/crap.so) ).
Greetings,
ba_f
On Mon Jul 06, 2015 at 10:46:21 +0200, ba_f wrote:
Am 2015-06-25 21:49, schrieb Adam Lackorzynski:
Hi,
On Fri Jun 19, 2015 at 16:15:54 +0200, ba_f wrote:
is it possible to dlopen() a shared lib?
Yes.
I'd like to execute a program that is started like this: "Example: ./gen_random -d .libs/libsim.so"
I know how to start a program with arguments. But where could i put my shared lib, and which path should i pass to the executing program?
All files/modules you put in your modiles.list file entry show up under rom/. So it should be: ./gen_random -d rom/libsim.so
Adam
Ok, thanks Adam.
Yet, i have another (maybe trivial) question.
How do i build a dynamic(!) shared lib for Fiasco, which is loadable with dlopen()?
In the Makefile you have the TARGET end with .so, for example: TARGET = libfoo.a libfoo.so will build both the static and shared lib.
[c] dl = dlopen(rom/lib.so, RTLD_NOW); if (dl == NULL){ fprintf(stderr, "dlopen failed: %s\n", dlerror()); [/c]
Output is: dlopen failed: (null)
I can assure that dlopen() finds the lib.so, because dlerror() gives an other output when using a different name (e.g. dlopen(rom/crap.so) ).
Works now?
Adam
l4-hackers@os.inf.tu-dresden.de