#ifndef _LINUX_INIT_H #define _LINUX_INIT_H #ifdef DDE_LINUX #include #endif #include /* These macros are used to mark some functions or * initialized data (doesn't apply to uninitialized data) * as `initialization' functions. The kernel can take this * as hint that the function is used only during the initialization * phase and free up used memory resources after * * Usage: * For functions: * * You should add __init immediately before the function name, like: * * static void __init initme(int x, int y) * { * extern int z; z = x * y; * } * * If the function has a prototype somewhere, you can also add * __init between closing brace of the prototype and semicolon: * * extern int initialize_foobar_device(int, int, int) __init; * * For initialized data: * You should insert __initdata between the variable name and equal * sign followed by value, e.g.: * * static int init_variable __initdata = 0; * static char linux_logo[] __initdata = { 0x32, 0x36, ... }; * * Don't forget to initialize data not at file scope, i.e. within a function, * as gcc otherwise puts the data into the bss section and not into the init * section. * * Also note, that this data cannot be "const". */ /* These are for everybody (although not all archs will actually discard it in modules) */ #ifndef DDE_LINUX #define __init __section(.init.text) __cold notrace #else #define __init __used #endif #define __initdata __section(.init.data) #define __initconst __section(.init.rodata) #define __exitdata __section(.exit.data) #define __exit_call __used __section(.exitcall.exit) /* modpost check for section mismatches during the kernel build. * A section mismatch happens when there are references from a * code or data section to an init section (both code or data). * The init sections are (for most archs) discarded by the kernel * when early init has completed so all such references are potential bugs. * For exit sections the same issue exists. * The following markers are used for the cases where the reference to * the *init / *exit section (code or data) is valid and will teach * modpost not to issue a warning. * The markers follow same syntax rules as __init / __initdata. */ #define __ref __section(.ref.text) noinline #define __refdata __section(.ref.data) #define __refconst __section(.ref.rodata) /* backward compatibility note * A few places hardcode the old section names: * .text.init.refok * .data.init.refok * .exit.text.refok * They should be converted to use the defines from this file */ /* compatibility defines */ #define __init_refok __ref #define __initdata_refok __refdata #define __exit_refok __ref #ifdef MODULE #define __exitused #else #define __exitused __used #endif #define __exit __section(.exit.text) __exitused __cold /* Used for HOTPLUG */ #define __devinit __section(.devinit.text) __cold #define __devinitdata __section(.devinit.data) #define __devinitconst __section(.devinit.rodata) #define __devexit __section(.devexit.text) __exitused __cold #define __devexitdata __section(.devexit.data) #define __devexitconst __section(.devexit.rodata) /* Used for HOTPLUG_CPU */ #define __cpuinit __section(.cpuinit.text) __cold #define __cpuinitdata __section(.cpuinit.data) #define __cpuinitconst __section(.cpuinit.rodata) #define __cpuexit __section(.cpuexit.text) __exitused __cold #define __cpuexitdata __section(.cpuexit.data) #define __cpuexitconst __section(.cpuexit.rodata) /* Used for MEMORY_HOTPLUG */ #define __meminit __section(.meminit.text) __cold #define __meminitdata __section(.meminit.data) #define __meminitconst __section(.meminit.rodata) #define __memexit __section(.memexit.text) __exitused __cold #define __memexitdata __section(.memexit.data) #define __memexitconst __section(.memexit.rodata) /* For assembly routines */ #define __HEAD .section ".head.text","ax" #define __INIT .section ".init.text","ax" #define __FINIT .previous #define __INITDATA .section ".init.data","aw" #define __INITRODATA .section ".init.rodata","a" #define __FINITDATA .previous #define __DEVINIT .section ".devinit.text", "ax" #define __DEVINITDATA .section ".devinit.data", "aw" #define __DEVINITRODATA .section ".devinit.rodata", "a" #define __CPUINIT .section ".cpuinit.text", "ax" #define __CPUINITDATA .section ".cpuinit.data", "aw" #define __CPUINITRODATA .section ".cpuinit.rodata", "a" #define __MEMINIT .section ".meminit.text", "ax" #define __MEMINITDATA .section ".meminit.data", "aw" #define __MEMINITRODATA .section ".meminit.rodata", "a" /* silence warnings when references are OK */ #define __REF .section ".ref.text", "ax" #define __REFDATA .section ".ref.data", "aw" #define __REFCONST .section ".ref.rodata", "a" #ifndef __ASSEMBLY__ /* * Used for initialization calls.. */ typedef int (*initcall_t)(void); typedef void (*exitcall_t)(void); extern initcall_t __con_initcall_start[], __con_initcall_end[]; extern initcall_t __security_initcall_start[], __security_initcall_end[]; /* Defined in init/main.c */ extern int do_one_initcall(initcall_t fn); extern char __initdata boot_command_line[]; extern char *saved_command_line; extern unsigned int reset_devices; /* used by init/main.c */ void setup_arch(char **); void prepare_namespace(void); extern void (*late_time_init)(void); #endif #ifndef MODULE #ifndef __ASSEMBLY__ /* initcalls are now grouped by functionality into separate * subsections. Ordering inside the subsections is determined * by link order. * For backwards compatibility, initcall() puts the call in * the device init subsection. * * The `id' arg to __define_initcall() is needed so that multiple initcalls * can point at the same handler without causing duplicate-symbol build errors. */ #ifndef DDE_LINUX #define __define_initcall(level,fn,id) \ static initcall_t __initcall_##fn##id __used \ __attribute__((__section__(".initcall" level ".init"))) = fn #else // DDE_LINUX // XXX: DDE CTORs are executed in reverse order as was done by // Linux' initcalls in earlier versions #include #define __define_initcall(level,fn,id) DDEKIT_CTOR(fn,level) #endif /* * Early initcalls run before initializing SMP. * * Only for built-in code, not modules. */ #define early_initcall(fn) __define_initcall("early",fn,early) /* * A "pure" initcall has no dependencies on anything else, and purely * initializes variables that couldn't be statically initialized. * * This only exists for built-in code, not for modules. */ #ifndef DDE_LINUX #define pure_initcall(fn) __define_initcall("0",fn,0) #define core_initcall(fn) __define_initcall("1",fn,1) #define core_initcall_sync(fn) __define_initcall("1s",fn,1s) #define postcore_initcall(fn) __define_initcall("2",fn,2) #define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s) #define arch_initcall(fn) __define_initcall("3",fn,3) #define arch_initcall_sync(fn) __define_initcall("3s",fn,3s) #define subsys_initcall(fn) __define_initcall("4",fn,4) #define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s) #define fs_initcall(fn) __define_initcall("5",fn,5) #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s) #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs) #define device_initcall(fn) __define_initcall("6",fn,6) #define device_initcall_sync(fn) __define_initcall("6s",fn,6s) #define late_initcall(fn) __define_initcall("7",fn,7) #define late_initcall_sync(fn) __define_initcall("7s",fn,7s) #else /* DDE_LINUX */ #define pure_initcall(fn) __define_initcall(1000,fn,1000) //#define dde_initcall(fn) __define_initcall(1009,fn,10) //#define dde_process_initcall(fn) __define_initcall(1008,fn,10) #define core_initcall(fn) __define_initcall(1000,fn,7) #define core_initcall_sync(fn) __define_initcall(1007s,fn,7s) #define postcore_initcall(fn) __define_initcall(1001,fn,6) #define postcore_initcall_sync(fn) __define_initcall(1006s,fn,6s) #define arch_initcall(fn) __define_initcall(1002,fn,5) #define arch_initcall_sync(fn) __define_initcall(1005s,fn,5s) #define subsys_initcall(fn) __define_initcall(1003,fn,4) #define subsys_initcall_sync(fn) __define_initcall(1004s,fn,4s) #define fs_initcall(fn) __define_initcall(1004,fn,3) #define fs_initcall_sync(fn) __define_initcall(1003s,fn,3s) //#define rootfs_initcall(fn) __define_initcall(ootfs,fn,rootfs) #define device_initcall(fn) __define_initcall(1005,fn,2) #define device_initcall_sync(fn) __define_initcall(1002s,fn,2s) #define late_initcall(fn) __define_initcall(1006,fn,1) #define late_initcall_sync(fn) __define_initcall(1001s,fn,1s) #endif #define __initcall(fn) device_initcall(fn) #ifndef DDE_LINUX #define __exitcall(fn) \ static exitcall_t __exitcall_##fn __exit_call = fn #else #define __exitcall(fn) #endif #define console_initcall(fn) \ static initcall_t __initcall_##fn \ __used __section(.con_initcall.init) = fn #define security_initcall(fn) \ static initcall_t __initcall_##fn \ __used __section(.security_initcall.init) = fn struct obs_kernel_param { const char *str; int (*setup_func)(char *); int early; }; /* * Only for really core code. See moduleparam.h for the normal way. * * Force the alignment so the compiler doesn't space elements of the * obs_kernel_param "array" too far apart in .init.setup. */ #define __setup_param(str, unique_id, fn, early) \ static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \ static struct obs_kernel_param __setup_##unique_id \ __used __section(.init.setup) \ __attribute__((aligned((sizeof(long))))) \ = { __setup_str_##unique_id, fn, early } #define __setup(str, fn) \ __setup_param(str, fn, fn, 0) /* NOTE: fn is as per module_param, not __setup! Emits warning if fn * returns non-zero. */ #define early_param(str, fn) \ __setup_param(str, fn, fn, 1) /* Relies on boot_command_line being set */ void __init parse_early_param(void); #endif /* __ASSEMBLY__ */ /** * module_init() - driver initialization entry point * @x: function to be run at kernel boot time or module insertion * * 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); /** * module_exit() - driver exit entry point * @x: function to be run when driver is removed * * module_exit() will wrap the driver clean-up code * 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 /* 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) #define subsys_initcall(fn) module_init(fn) #define fs_initcall(fn) module_init(fn) #define device_initcall(fn) module_init(fn) #define late_initcall(fn) module_init(fn) #define security_initcall(fn) module_init(fn) /* Each module must use one module_init(). */ #define module_init(initfn) \ static inline initcall_t __inittest(void) \ { return initfn; } \ int init_module(void) __attribute__((alias(#initfn))); /* This is only required if you want to be unloadable. */ #define module_exit(exitfn) \ static inline exitcall_t __exittest(void) \ { return exitfn; } \ void cleanup_module(void) __attribute__((alias(#exitfn))); #define __setup_param(str, unique_id, fn) /* nothing */ #define __setup(str, func) /* nothing */ #endif /* Data marked not to be saved by software suspend */ #define __nosavedata __section(.data.nosave) /* This means "can be init if no module support, otherwise module load may call it." */ #ifdef CONFIG_MODULES #define __init_or_module #define __initdata_or_module #else #define __init_or_module __init #define __initdata_or_module __initdata #endif /*CONFIG_MODULES*/ /* Functions marked as __devexit may be discarded at kernel link time, depending on config options. Newer versions of binutils detect references from retained sections to discarded sections and flag an error. Pointers to __devexit functions must use __devexit_p(function_name), the wrapper will insert either the function_name or NULL, depending on the config options. */ #if defined(MODULE) || defined(CONFIG_HOTPLUG) #define __devexit_p(x) x #else #define __devexit_p(x) NULL #endif #ifdef MODULE #define __exit_p(x) x #else #define __exit_p(x) NULL #endif #endif /* _LINUX_INIT_H */