__setup(string, fn)
#ifndef MODULE #define early_param(str, fn) __setup_param(str, fn, fn, 0) #else /* MODULE */ #define early_param(str, fn) #endif
//net/core/dev.c
_setup("netdev=", netdev_boot_setup);
//net/ethernet/eth.c
__setup("ether=", netdev_boot_setup); #define __setup(str, fn) __setup_param(str, fn, fn, 0)
#define early_param(str, fn) __setup_param(str, fn, fn, 1)
#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 }
early_param和__setup唯一不同的就是传递给__setup_param的最后一个参数early。_setup_param定义了一个struct obs_kernel_param类型的结构,然后通过_section宏,使这个变量在链接的时候能够放置在段.init.setup。下文有.init.setup的介绍。
struct obs_kernel_param结构如下:
struct obs_kernel_param {
const char *str;
int (*setup_func)(char *);
int early;
}; parse_args("early options", tmp_cmdline, NULL, 0, do_early_param);
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
&unknown_bootoption);
struct obs_kernel_param {
const char *str;
int (*setup_func)(char *);
int early;
};module_init(XXX); module_exit(XXX);
static char version[] _ _devinitdata = DRV_NAME " ... ";
static struct vortex_chip_info {
...
} vortex_info_tbl[] _ _devinitdata = {
{"3c590 Vortex 10Mbps",
... ... ...
}
static int _ _init vortex_init (void)
{
...
}
static void _ _exit vortex_cleanup (void)
{
...
}
module_init(vortex_init);
module_exit(vortex_cleanup);
原文地址:http://blog.csdn.net/windeal3203/article/details/43529185