summaryrefslogtreecommitdiff
path: root/include/linux/init.h
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2002-11-10 17:08:07 -0800
committerAndy Grover <agrover@groveronline.com>2002-11-10 17:08:07 -0800
commitaa65be3f456be1ac4359f7fffeb7b4ae3c149419 (patch)
tree7deb9cf5ee0103545138396b83bc260092ab8240 /include/linux/init.h
parent850b830c9639af788e2917aed3aea8d8bb9da1a1 (diff)
[PATCH] In-kernel Module Loader
This is an implementation of the in-kernel module loader extending the try_inc_mod_count() primitive and making its use compulsory. This has the benifit of simplicity, and similarity to the existing scheme. To reduce the cost of the constant increments and decrements, reference counters are lockless and per-cpu. Eliminated (coming in following patches): o Modversions o Module parameters o kallsyms o EXPORT_SYMBOL_GPL and MODULE_LICENCE checks o DEVICE_TABLE support. New features: o Typesafe symbol_get/symbol_put o Single "insert this module" syscall interface allows trivial userspace. o Raceless loading and unloading You will need the trivial replacement module utilities from: http://ozlabs.org/~rusty/module-init-tools-0.6.tar.gz
Diffstat (limited to 'include/linux/init.h')
-rw-r--r--include/linux/init.h121
1 files changed, 63 insertions, 58 deletions
diff --git a/include/linux/init.h b/include/linux/init.h
index d9b7f490e66d..52db706d0ed0 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -38,17 +38,30 @@
* Also note, that this data cannot be "const".
*/
-#ifndef MODULE
+/* These are for everybody (although not all archs will actually
+ discard it in modules) */
+#define __init __attribute__ ((__section__ (".init.text")))
+#define __initdata __attribute__ ((__section__ (".init.data")))
+#define __exit __attribute__ ((__section__(".exit.text")))
+#define __exitdata __attribute__ ((__section__(".exit.data")))
+#define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit")))
-#ifndef __ASSEMBLY__
+/* For assembly routines */
+#define __INIT .section ".init.text","ax"
+#define __FINIT .previous
+#define __INITDATA .section ".init.data","aw"
+#ifndef __ASSEMBLY__
/*
* Used for initialization calls..
*/
typedef int (*initcall_t)(void);
typedef void (*exitcall_t)(void);
+#endif
-extern initcall_t __initcall_start, __initcall_end;
+#ifndef MODULE
+
+#ifndef __ASSEMBLY__
/* initcalls are now grouped by functionality into separate
* subsections. Ordering inside the subsections is determined
@@ -70,7 +83,7 @@ extern initcall_t __initcall_start, __initcall_end;
#define __initcall(fn) device_initcall(fn)
-#define __exitcall(fn) \
+#define __exitcall(fn) \
static exitcall_t __exitcall_##fn __exit_call = fn
/*
@@ -83,39 +96,21 @@ struct kernel_param {
extern struct kernel_param __setup_start, __setup_end;
-#define __setup(str, fn) \
- static char __setup_str_##fn[] __initdata = str; \
- static struct kernel_param __setup_##fn __attribute__((unused)) __initsetup = { __setup_str_##fn, fn }
+#define __setup(str, fn) \
+ static char __setup_str_##fn[] __initdata = str; \
+ static struct kernel_param __setup_##fn \
+ __attribute__((unused,__section__ (".init.setup"))) \
+ = { __setup_str_##fn, fn }
#endif /* __ASSEMBLY__ */
-/*
- * Mark functions and data as being only used at initialization
- * or exit time.
- */
-#define __init __attribute__ ((__section__ (".init.text")))
-#define __exit __attribute__ ((unused, __section__(".exit.text")))
-#define __initdata __attribute__ ((__section__ (".init.data")))
-#define __exitdata __attribute__ ((unused, __section__ (".exit.data")))
-#define __initsetup __attribute__ ((unused,__section__ (".init.setup")))
-#define __init_call(level) __attribute__ ((unused,__section__ (".initcall" level ".init")))
-#define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit")))
-
-/* For assembly routines */
-#define __INIT .section ".init.text","ax"
-#define __FINIT .previous
-#define __INITDATA .section ".init.data","aw"
-
/**
* module_init() - driver initialization entry point
* @x: function to be run at kernel boot time or module insertion
*
- * module_init() will add the driver initialization routine in
- * the "__initcall.int" code segment if the driver is checked as
- * "y" or static, or else it will wrap the driver initialization
- * routine with init_module() which is used by insmod and
- * modprobe when the driver is used as a module.
- */
+ * module_init() will either be called during do_initcalls (if
+ * builtin) or at module insertion time (if a module). There can only
+ * be one per module. */
#define module_init(x) __initcall(x);
/**
@@ -126,39 +121,21 @@ extern struct kernel_param __setup_start, __setup_end;
* with cleanup_module() when used with rmmod when
* the driver is a module. If the driver is statically
* compiled into the kernel, module_exit() has no effect.
+ * There can only be one per module.
*/
#define module_exit(x) __exitcall(x);
-#else
-
-#define __init
-#define __exit
-#define __initdata
-#define __exitdata
-#define __initcall(fn)
-/* For assembly routines */
-#define __INIT
-#define __FINIT
-#define __INITDATA
-
-/* These macros create a dummy inline: gcc 2.9x does not count alias
- as usage, hence the `unused function' warning when __init functions
- are declared static. We use the dummy __*_module_inline functions
- both to kill the warning and check the type of the init/cleanup
- function. */
-typedef int (*__init_module_func_t)(void);
-typedef void (*__cleanup_module_func_t)(void);
-#define module_init(x) \
- int init_module(void) __attribute__((alias(#x))); \
- static inline __init_module_func_t __init_module_inline(void) \
- { return x; }
-#define module_exit(x) \
- void cleanup_module(void) __attribute__((alias(#x))); \
- static inline __cleanup_module_func_t __cleanup_module_inline(void) \
- { return x; }
+/**
+ * no_module_init - code needs no initialization.
+ *
+ * The equivalent of declaring an empty init function which returns 0.
+ * Every module must have exactly one module_init() or no_module_init
+ * invocation. */
+#define no_module_init
-#define __setup(str,func) /* nothing */
+#else /* MODULE */
+/* Don't use these in modules, but some people do... */
#define core_initcall(fn) module_init(fn)
#define postcore_initcall(fn) module_init(fn)
#define arch_initcall(fn) module_init(fn)
@@ -167,6 +144,34 @@ typedef void (*__cleanup_module_func_t)(void);
#define device_initcall(fn) module_init(fn)
#define late_initcall(fn) module_init(fn)
+/* Each module knows its own name. */
+#define __DEFINE_MODULE_NAME \
+ char __module_name[] __attribute__((section(".modulename"))) = \
+ __stringify(KBUILD_MODNAME)
+
+/* These macros create a dummy inline: gcc 2.9x does not count alias
+ as usage, hence the `unused function' warning when __init functions
+ are declared static. We use the dummy __*_module_inline functions
+ both to kill the warning and check the type of the init/cleanup
+ function. */
+
+/* Each module must use one module_init(), or one no_module_init */
+#define module_init(initfn) \
+ __DEFINE_MODULE_NAME; \
+ static inline initcall_t __inittest(void) \
+ { return initfn; } \
+ int __initfn(void) __attribute__((alias(#initfn)));
+
+#define no_module_init __DEFINE_MODULE_NAME
+
+/* This is only required if you want to be unloadable. */
+#define module_exit(exitfn) \
+ static inline exitcall_t __exittest(void) \
+ { return exitfn; } \
+ void __exitfn(void) __attribute__((alias(#exitfn)));
+
+
+#define __setup(str,func) /* nothing */
#endif
/* Data marked not to be saved by software_suspend() */