summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZheng Da <zhengda1936@gmail.com>2010-01-19 11:21:27 +0100
committerZheng Da <zhengda1936@gmail.com>2010-01-19 11:21:27 +0100
commit76ab4925b163ee5bf6594c79be063662e2157d00 (patch)
tree9d46a9885a9925df46bace7ee65d0c6b31169170
parent2680eecc499e43679be098e5834d4f3a62f59a0c (diff)
Add initcall in ddekit.
-rw-r--r--libddekit/Makefile2
-rw-r--r--libddekit/include/ddekit/initcall.h42
-rw-r--r--libddekit/initcall.c27
3 files changed, 70 insertions, 1 deletions
diff --git a/libddekit/Makefile b/libddekit/Makefile
index 4d5d58fa..958e67d3 100644
--- a/libddekit/Makefile
+++ b/libddekit/Makefile
@@ -21,7 +21,7 @@ makemode := library
libname = libddekit
SRCS= condvar.c init.c interrupt.c lock.c malloc.c memory.c \
pci.c pgtab.c printf.c resources.c list.c panic.c \
- thread.c timer.c kmem.c
+ thread.c timer.c kmem.c initcall.c
LCLHDRS = include/ddekit/condvar.h include/ddekit/lock.h \
include/ddekit/semaphore.h include/ddekit/debug.h \
include/ddekit/inline.h include/ddekit/panic.h \
diff --git a/libddekit/include/ddekit/initcall.h b/libddekit/include/ddekit/initcall.h
new file mode 100644
index 00000000..b503cc6a
--- /dev/null
+++ b/libddekit/include/ddekit/initcall.h
@@ -0,0 +1,42 @@
+#ifndef _ddekit_initcall_h
+#define _ddekit_initcall_h
+
+// from l4/sys/compiler.h
+#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ >= 4
+#define L4_STICKY(x) __attribute__((used)) x
+#else
+#define L4_STICKY(x) __attribute__((unused)) x
+#endif
+
+#define l4str(s) #s
+
+// from dde_linux/ARCH-x86/ctor.h
+typedef void (*l4ddekit_initcall_t)(void);
+
+#define __l4ddekit_initcall(p) \
+ __attribute__ ((__section__ (".l4dde_ctors." #p)))
+
+/** Define a function to be a DDEKit initcall.
+ *
+ * Define a function to be a DDEKit initcall. This function will then be placed
+ * in a separate linker section of the binary (called .l4dde_ctors). The L4Env
+ * construction mechanism will execute all constructors in this section during
+ * application startup.
+ *
+ * This is the right place to place Linux' module_init functions & Co.
+ *
+ * \param fn function
+ */
+#define DDEKIT_INITCALL(fn) DDEKIT_CTOR(fn, 1)
+
+#define DDEKIT_CTOR(fn, prio) \
+ static l4ddekit_initcall_t \
+ L4_STICKY(__l4ddekit_initcall_##fn) \
+ __l4ddekit_initcall(prio) = (void *)fn
+
+/**
+ * Runs all registered initcalls.
+ */
+void ddekit_do_initcalls(void);
+
+#endif
diff --git a/libddekit/initcall.c b/libddekit/initcall.c
new file mode 100644
index 00000000..78c24146
--- /dev/null
+++ b/libddekit/initcall.c
@@ -0,0 +1,27 @@
+#include <ddekit/initcall.h>
+
+#define BEG { (crt0_hook) ~1U }
+#define END { (crt0_hook) 0 }
+
+#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ >= 4
+#define SECTION(x) __attribute__((used, section( x )))
+#else
+#define SECTION(x) __attribute__((section( x )))
+#endif
+
+typedef void (*const crt0_hook)(void);
+
+static crt0_hook __L4DDE_CTOR_BEG__[1] SECTION(".mark_beg_l4dde_ctors") = BEG;
+static crt0_hook __l4DDE_CTOR_END__[1] SECTION(".mark_end_l4dde_ctors") = END;
+
+void ddekit_do_initcalls() {
+ crt0_hook *list = __L4DDE_CTOR_BEG__;
+
+ list++;
+ while (*list)
+ {
+ (**list)();
+ list++;
+ }
+}
+