Hi list,
I am doing a port of a rather large Linux kernel module to TUDOS. I am using DDE for linux26 which works quite good, so far. But I just started to work on that and I am still in an early phase of evaluation.
I want to keep the legacy kernel module code inside a separate library which is than linked to my DDE application. The module's "init" method is included in the library but not inside the final binary. That's why it is not called by l4dde26_do_initcalls().
Can I somehow tell the linker to also include "module_init()"-functions from within a library?
Best regards, Andre
On Tue Feb 17, 2009 at 19:10:29 +0100, Andre Puschmann wrote:
I am doing a port of a rather large Linux kernel module to TUDOS. I am using DDE for linux26 which works quite good, so far. But I just started to work on that and I am still in an early phase of evaluation.
I want to keep the legacy kernel module code inside a separate library which is than linked to my DDE application. The module's "init" method is included in the library but not inside the final binary. That's why it is not called by l4dde26_do_initcalls().
Can I somehow tell the linker to also include "module_init()"-functions from within a library?
The initcall must be placed in a special section, and is also prefixed, i.e. 'foo' gets to '__l4ddekit_initcall_foo'. There must be such a function in your lib, placed in a section '.l4dde_ctors'. Is that the case?
Adam
Hi Adam,
Adam Lackorzynski wrote:
The initcall must be placed in a special section, and is also prefixed, i.e. 'foo' gets to '__l4ddekit_initcall_foo'. There must be such a function in your lib, placed in a section '.l4dde_ctors'. Is that the case?
Yes, I read this. That is why I double checked it:
$ readelf -W -s libhellomod.a File: libhellomod.a(hello.o) There are 19 section headers, starting at offset 0x11da8:
Section Headers: [Nr] Name Type Addr Off Size ES Lk Inf Al Flags
..
[12] .l4dde_ctors."6" PROGBITS 00000000 011cd4 000004 00 0 0 4 [00000003]: WRITE, ALLOC
Symbol table '.symtab' contains 17 entries: Num: Value Size Type Bind Vis Ndx Name
..
9: 00000000 4 OBJECT LOCAL DEFAULT 12 __l4ddekit_initcall_hello_init
..
So, looks like __l4ddekit_initcall_hello_init belongs to section 12 which is indeed .l4dde_ctors.
Best regards, Andre
Hi Andre,
I want to keep the legacy kernel module code inside a separate library which is than linked to my DDE application. The module's "init" method is included in the library but not inside the final binary. That's why it is not called by l4dde26_do_initcalls().
When creating the final binary, the linker has the habit of throwing code out it considers unused. For library constructors, this can go wrong, because the calls to them are generated only at runtime and are thus not visible to the linker, which then wrongly concludes to drop them.
The fix (actually it's more of a workaround) is to rename the static library in the Makefile TARGET from libdriver.a to libdriver.o.a. This causes the build system to combine the individual objects into one large object instead of a regular static library archive. You can later link to that lib with -ldriver.o as expected.
The effect is that the linker cannot throw code out of such a lib, because to it, this is essentially one large object file and the GNU linker only drops code with object granularity. (So this uses one peculiarity of the GNU linker to fix another one.)
Michael
Hi Michael,
Michael Roitzsch schrieb:
When creating the final binary, the linker has the habit of throwing code out it considers unused. For library constructors, this can go wrong, because the calls to them are generated only at runtime and are thus not visible to the linker, which then wrongly concludes to drop them.
The fix (actually it's more of a workaround) is to rename the static library in the Makefile TARGET from libdriver.a to libdriver.o.a. This causes the build system to combine the individual objects into one large object instead of a regular static library archive. You can later link to that lib with -ldriver.o as expected.
The effect is that the linker cannot throw code out of such a lib, because to it, this is essentially one large object file and the GNU linker only drops code with object granularity. (So this uses one peculiarity of the GNU linker to fix another one.)
Ack. Thanks for that hint. Your proposal works like a charm. Here is another solution: I wrote a small "hello-world" Linux kernel module with just two functions: init_module() and exit_module(). I thought that would be enough for demonstration. My fault. The linker needs at least one _real_ reference. So adding a further print_hello() function to the module and a call to that function from within my L4 server fixed the whole problem. Now, I see DDE calling my init function.
Thanks very much.
Andre
Hi Andre,
The fix (actually it's more of a workaround) is to rename the static library in the Makefile TARGET from libdriver.a to libdriver.o.a.
Ack. Thanks for that hint. Your proposal works like a charm. Here is another solution: I wrote a small "hello-world" Linux kernel module with just two functions: init_module() and exit_module(). I thought that would be enough for demonstration. My fault. The linker needs at least one _real_ reference.
That's true. Even in this single-object-library, the linker needs to get the idea that something from it is used. Otherwise, the entire library is dropped.
Good that you got it working.
Michael
l4-hackers@os.inf.tu-dresden.de