Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef _LINUX_UML_INIT_H |
2 | #define _LINUX_UML_INIT_H | |
3 | ||
4 | /* These macros are used to mark some functions or | |
5 | * initialized data (doesn't apply to uninitialized data) | |
6 | * as `initialization' functions. The kernel can take this | |
7 | * as hint that the function is used only during the initialization | |
8 | * phase and free up used memory resources after | |
9 | * | |
10 | * Usage: | |
11 | * For functions: | |
12 | * | |
13 | * You should add __init immediately before the function name, like: | |
14 | * | |
15 | * static void __init initme(int x, int y) | |
16 | * { | |
17 | * extern int z; z = x * y; | |
18 | * } | |
19 | * | |
20 | * If the function has a prototype somewhere, you can also add | |
21 | * __init between closing brace of the prototype and semicolon: | |
22 | * | |
23 | * extern int initialize_foobar_device(int, int, int) __init; | |
24 | * | |
25 | * For initialized data: | |
26 | * You should insert __initdata between the variable name and equal | |
27 | * sign followed by value, e.g.: | |
28 | * | |
29 | * static int init_variable __initdata = 0; | |
30 | * static char linux_logo[] __initdata = { 0x32, 0x36, ... }; | |
31 | * | |
32 | * Don't forget to initialize data not at file scope, i.e. within a function, | |
33 | * as gcc otherwise puts the data into the bss section and not into the init | |
34 | * section. | |
35 | * | |
36 | * Also note, that this data cannot be "const". | |
37 | */ | |
38 | ||
39 | #ifndef _LINUX_INIT_H | |
40 | typedef int (*initcall_t)(void); | |
41 | typedef void (*exitcall_t)(void); | |
42 | ||
99c9f502 JD |
43 | #ifndef __KERNEL__ |
44 | #ifndef __section | |
45 | # define __section(S) __attribute__ ((__section__(#S))) | |
46 | #endif | |
47 | ||
7c1fed03 JD |
48 | #if __GNUC__ == 3 |
49 | ||
99c9f502 JD |
50 | #if __GNUC_MINOR__ >= 3 |
51 | # define __used __attribute__((__used__)) | |
52 | #else | |
53 | # define __used __attribute__((__unused__)) | |
54 | #endif | |
55 | ||
7c1fed03 JD |
56 | #else |
57 | #if __GNUC__ == 4 | |
58 | # define __used __attribute__((__used__)) | |
59 | #endif | |
60 | #endif | |
61 | ||
99c9f502 JD |
62 | #else |
63 | #include <linux/compiler.h> | |
64 | #endif | |
1da177e4 LT |
65 | /* These are for everybody (although not all archs will actually |
66 | discard it in modules) */ | |
3ff6eecc AB |
67 | #define __init __section(.init.text) |
68 | #define __initdata __section(.init.data) | |
69 | #define __exitdata __section(.exit.data) | |
70 | #define __exit_call __used __section(.exitcall.exit) | |
1da177e4 LT |
71 | |
72 | #ifdef MODULE | |
3ff6eecc | 73 | #define __exit __section(.exit.text) |
1da177e4 | 74 | #else |
3ff6eecc | 75 | #define __exit __used __section(.exit.text) |
1da177e4 LT |
76 | #endif |
77 | ||
78 | #endif | |
79 | ||
80 | #ifndef MODULE | |
81 | struct uml_param { | |
82 | const char *str; | |
83 | int (*setup_func)(char *, int *); | |
84 | }; | |
85 | ||
86 | extern initcall_t __uml_initcall_start, __uml_initcall_end; | |
87 | extern initcall_t __uml_postsetup_start, __uml_postsetup_end; | |
88 | extern const char *__uml_help_start, *__uml_help_end; | |
89 | #endif | |
90 | ||
91 | #define __uml_initcall(fn) \ | |
92 | static initcall_t __uml_initcall_##fn __uml_init_call = fn | |
93 | ||
94 | #define __uml_exitcall(fn) \ | |
95 | static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn | |
96 | ||
97 | extern struct uml_param __uml_setup_start, __uml_setup_end; | |
98 | ||
99 | #define __uml_postsetup(fn) \ | |
100 | static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn | |
101 | ||
102 | #define __non_empty_string(dummyname,string) \ | |
103 | struct __uml_non_empty_string_struct_##dummyname \ | |
104 | { \ | |
105 | char _string[sizeof(string)-2]; \ | |
106 | } | |
107 | ||
108 | #ifndef MODULE | |
109 | #define __uml_setup(str, fn, help...) \ | |
110 | __non_empty_string(fn ##_setup, str); \ | |
111 | __uml_help(fn, help); \ | |
112 | static char __uml_setup_str_##fn[] __initdata = str; \ | |
113 | static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn } | |
114 | #else | |
115 | #define __uml_setup(str, fn, help...) \ | |
116 | ||
117 | #endif | |
118 | ||
119 | #define __uml_help(fn, help...) \ | |
120 | __non_empty_string(fn ##__help, help); \ | |
121 | static char __uml_help_str_##fn[] __initdata = help; \ | |
122 | static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn | |
123 | ||
124 | /* | |
125 | * Mark functions and data as being only used at initialization | |
126 | * or exit time. | |
127 | */ | |
3ff6eecc AB |
128 | #define __uml_init_setup __used __section(.uml.setup.init) |
129 | #define __uml_setup_help __used __section(.uml.help.init) | |
130 | #define __uml_init_call __used __section(.uml.initcall.init) | |
131 | #define __uml_postsetup_call __used __section(.uml.postsetup.init) | |
132 | #define __uml_exit_call __used __section(.uml.exitcall.exit) | |
1da177e4 LT |
133 | |
134 | #ifndef __KERNEL__ | |
135 | ||
75e5584c | 136 | #define __define_initcall(level,fn) \ |
3ff6eecc | 137 | static initcall_t __initcall_##fn __used \ |
75e5584c JD |
138 | __attribute__((__section__(".initcall" level ".init"))) = fn |
139 | ||
140 | /* Userspace initcalls shouldn't depend on anything in the kernel, so we'll | |
141 | * make them run first. | |
142 | */ | |
143 | #define __initcall(fn) __define_initcall("1", fn) | |
144 | ||
1da177e4 LT |
145 | #define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn |
146 | ||
3ff6eecc | 147 | #define __init_call __used __section(.initcall.init) |
1da177e4 LT |
148 | |
149 | #endif | |
150 | ||
151 | #endif /* _LINUX_UML_INIT_H */ |