Question about memory management in L4 Fiasco O.C + L4re

Adam Lackorzynski adam at os.inf.tu-dresden.de
Mon Jan 4 23:55:47 CET 2016


Hi,

On Mon Jan 04, 2016 at 17:03:49 +0100, Mahdi Aichouch wrote:
> I combined the loader flags
> "L4.Ldr_flags.eager_map+L4.Ldr_flags.pinned_segs" in order to create fixed
> memory region for the text and data segments of an L4 task*. *And to be
> able to see their physical address using phys( ) method of Dataspace
> object. But, looking at the traces I didn't see any difference. After
> digging into the code where the Dataspace objects are created I saw that
> for instance in the following method from the file
> pkg/l4re_kernel/server/src/loader.cc :
> 
> L4Re_app_model::Dataspace
> L4Re_app_model::alloc_ds(unsigned long size) const
> {
>   Dataspace mem = chkcap(Global::cap_alloc.alloc<L4Re::Dataspace>(),
>       "ELF loader: could not allocate capability");
>   chksys(Global::allocator->alloc(size, mem, (Global::l4re_aux->ldr_flags &
> L4RE_AUX_LDR_FLAG_PINNED_SEGS) ? L4Re::Mem_alloc::Pinned : 0 ), "loading
> writabel ELF segment");
>   return mem;
> }
> 
> The value of Global::l4re_aux->ldr_flags is equal to 0. And given the
> result of the test the created Dataspace is not pinned, because 0 is given
> as argument to alloc( ) method.
> 
> I was unable to find out why the attribute Global::l4re_aux->ldr_flags is
> not equal to L4.Ldr_flags.eager_map+L4.Ldr_flags.pinned_segs, as I was
> expecting.
> Could you please clarify this point.

Looking more closely at your last mail... the ldr_flags=... needs to go
out one level of {}, i.e.:
 L4.default_loader:start({ ldr_flags = L4.Ldr_flags.eager_map + L4.Ldr_flags.pinned_segs,
                           log = { "hello1", "green" }
			 }, "rom/hello");


> For my test, I modified the precedent code as follow :
> 
> chksys(Global::allocator->alloc(size, mem, /*(Global::l4re_aux->ldr_flags &
> L4RE_AUX_LDR_FLAG_PINNED_SEGS) ?*/  L4Re::Rm::Eager_map |
>  L4Re::Mem_alloc::Pinned /*:0*/ ), "loading writabel ELF segment");
> 
> Then, in the traces I was I able to see the physical address of the created
> Dataspace objects.

Thats ok to do for your use case.

> After that, I tested L4Linux and I saw that the physical addresses of the
> created Dataspace object of text and data segments when loading L4Linux
> binary have for example the following value :
> 
> l4linux | l4re_kernel: Loader::alloc_app_stack stack dataspace phys addr =
> 605b1000 size = 1000
> l4linux | Global loader flags (Global::l4re_aux->ldr_flags) = 0
> l4linux | l4re_kernel: L4Re_app_model::alloc_ds dataspace phys @addr =
> [605b2000] size = [3f9000] flags 0
> l4linux | Phdr_load(): dataspace at physical address [0x605b2000], size
> [3f9000]
> l4linux | Phdr_load(): map from file (attaching ro ELF segment),
> prog_attach_ds [paddr = 0xa8000000 (0xa80segments00000), offs 0, size
> 4165632, all segs cow? 0]
> l4linux | Global loader flags (Global::l4re_aux->ldr_flags) = 0
> l4linux | l4re_kernel: L4Re_app_model::alloc_ds dataspace phys @addr =
> [60aaf000] size = [2000] flags 0
> l4linux | Phdr_load(): dataspace at physical address [0x60aaf000], size
> [2000]
> l4linux | Phdr_load(): attaching rw ELF segment: prog_attach_ds
> [l4_addr(0xa8400000) paddr(0xa8400000), offs 4194304, size 8192, all segs
> cow? 0]
> 
> 
> Looking in the trace from the main( ) function in L4Linux we can see that
> the physical address of the text and data areas of L4Linux are different
> from the precedents value printed using the phys( ) method of the
> corresponding Dataspace objects. As we can see below in the lines showing
> the physical value of stext - etext, sdata - edata areas :
> 
> ...
> l4linux | L4LINUX: Ma DBG: Virtual Address 00000000 End 00000000
> l4linux |  Physical Address 00000000  End 00000000
> l4linux | L4LINUX: Ma DBG: Starting binary at 0x2000360, argc=14
> argv=0xafff4f6c *argv=0xb1007ff0 argv0=rom/vmlinuz.arm
> l4linux | External resolver is at 0xa800075c
> l4linux | ======> L4Linux starting... <========
> l4linux | Linux version 3.16.0-l4 (aichouch at aichouch-ThinkCentre-M90) (gcc
> version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29) )
> #57 SMP Mon Jan 4 15:16:18 CET 2016
> l4linux | Binary name: rom/vmlinuz.arm
> l4linux |    This is an AEABI build.
> l4linux | Linux kernel command line (13 args): mem=128M
> l4memtype=pinned,continuous console=ttyLv0 l4x_rd=rom/ramdisk-arm.rd
> root=1:0 ramdisk_size=49152 rw init=/bin/sh earlyprintk=1 showpfexc=1
> showghost=1 print-fatal-signals=1 l4shmnet.add=shmns,macparCPU mapping
> (l:p)[1]: 0:0
> l4linux | Image: 020000a0 - 02600000 [6143 KiB].
> l4linux | Areas: Text:     020000a0 - 023b2000 [3783kB] (a bit longer)
> l4linux |        Data:     023b2000 - 023dd460 [173kB]
> l4linux |        Initdata: 02387000 - 023b1a00 [170kB]
> l4linux |        BSS:      023e239c - 024a6780 [784kB]
> l4linux | Device scan:
> l4linux |   Device: L4ICU
> l4linux |   Device: imx6q-fec.dev
> l4linux |     MEM: 02188000 - 0218bfff
> l4linux |     IRQ: 00000096 - 00000096
> l4linux |     IRQ: 00000097 - 00000097
> l4linux |   Device: dmamem
> l4linux |     MEM: 60ab1000 - 60b30fff
> l4linux | Device scan done.
> l4linux | L4LINUX: Ma DBG: l4lx_thread_create: Created thread 416 (cpu0)
> (u:b3000e00, v:b3000c00, sp:023b3fa4)
> l4linux | main thread will be 416
> l4linux | l4x_register_pointer_section: addr = 02000000 size = 4878336
> l4linux | section-with-init: Virt: 0x2000000 to 0x24a677f [4761 KiB]
> l4linux | section-with-init: Phys: 0x60b33000 to 0x60fd977f, [4761 KiB]
> l4linux | Main thread running, waiting...
> l4linux | Main thread running, waiting...
> l4linux | stext virt 020000a0, phys 60b330a0
> l4linux | etext virt 023b2000, phys 60ee5000
> l4linux | sdata virt 023b2000, phys 60ee5000
> l4linux | edata virt 023dd460, phys 60f10460
> l4linux | L4x: Memory size: 128MB
> l4linux | L4x: Setting superpages for main memory
> l4linux | L4x: Adjusted memory start: 02000000
> l4linux |     Main memory: Virt: 0x2600000 to 0xa5fffff [131072 KiB]
> l4linux |     Main memory: Phys: 0x64800000 to 0x6c7fffff, [131072 KiB]
> l4linux | l4x: vmalloc area: 0a600000 - 12600000
> l4linux | l4x_register_pointer_section: addr = 02000000 size = 4878336
> l4linux |            text: Virt: 0x2000000 to 0x24a677f [4761 KiB]
> l4linux |            text: Phys: 0x60b33000 to 0x60fd977f, [4761 KiB]
> l4linux | Booting Linux on physical CPU 0x0
> l4linux | Linux version 3.16.0-l4 (aichouch at aichouch-ThinkCentre-M90) (gcc
> version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29) )
> #57 SMP Mon Jan 4 15:16:18 CET 2016
> l4linux | CPU: Fiasco [410fc090] revision 0 (ARMv7), cr=00000000
> l4linux | CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing
> instruction cache
> l4linux | Machine: L4
> l4linux | Ignoring unrecognised tag 0x00000000
> l4linux | bootconsole [earlykdb0] enabled
> l4linux | Forcing write-allocate cache policy for SMP
> l4linux | Forcing shared mappings for SMP
> l4linux | Memory policy: Data cache writealloc
> l4linux | Page fault: addr = bffff003 pc = 0238aba0 (rw, T)
> l4linux | Forward PF to our pager
> l4linux | Loading: rom/ramdisk-arm.rd
> l4linux | INITRD: Size of RAMdisk is 49152KiB
> l4linux | INITRD: 12600000 - 15600000
> ...
> 
> Could you please explain why there is a difference in the physical
> addresses of the Dataspaces representing the text and data sections when
> loading L4Linux binary, and the physical addresses of these sections when
> L4Linux is booting.

The L4Linux you are loading via ned is not the Linux kernel but a
wrapper around that that contains the Linux kernel. L4Re will load the
wrapper while the Linux output is the actual Linux kernel. The output
before "=== L4Linux starting ===" is from the loader that is
loading/unpacking the inner part, you probably want to look there as
well (arch/l4/boot/ldr.c).



Adam
-- 
Adam                 adam at os.inf.tu-dresden.de
  Lackorzynski         http://os.inf.tu-dresden.de/~adam/




More information about the l4-hackers mailing list