在init\main.c中存在许多类似如下定义:
static int __init set_reset_devices(char *str)
{
reset_devices = 1;
return 1;
}
__setup("reset_devices", set_reset_devices);
................................
static int __init debug_kernel(char *str)
{
console_loglevel = CONSOLE_LOGLEVEL_DEBUG;
return 0;
}
static int __init quiet_kernel(char *str)
{
console_loglevel = CONSOLE_LOGLEVEL_QUIET;
return 0;
}
early_param("debug", debug_kernel);
early_param("quiet", quiet_kernel);
............................
这些定义其实是用于定义配置参数的解析,其内部主要依赖:
- 数据结构 obs_kernel_param
- 宏 __setup_param
- 编译时对section(.init.setup)的处理
数据结构
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 const char __setup_str_##unique_id[] __initconst \
__aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \
__used __section(".init.setup") \
__aligned(__alignof__(struct obs_kernel_param)) \
= { __setup_str_##unique_id, fn, early }
/*
* NOTE: __setup functions return values:
* @fn returns 1 (or non-zero) if the option argument is "handled"
* and returns 0 if the option argument is "not handled".
*/
#define __setup(str, fn) \
__setup_param(str, fn, fn, 0)
/*
* NOTE: @fn is as per module_param, not __setup!
* I.e., @fn returns 0 for no error or non-zero for error
* (possibly @fn returns a -errno value, but it does not matter).
* Emits warning if @fn returns non-zero.
*/
#define early_param(str, fn) \
__setup_param(str, fn, fn, 1)
以上内容编译时转换如下:
static const char __setup_str_set_reset_devices[] __initconst __aligned(1) = "reset_devices";
static struct obs_kernel_param __setup_set_reset_devices __used __section(".init.setup") __aligned(__alignof__(struct obs_kernel_param)) = {__setup_str_set_reset_devices, set_reset_devices, 0 }
static const char __setup_str_debug[] __initconst __aligned(1) = "debug";
static struct obs_kernel_param __setup_debug_kernel __used __section(".init.setup") __aligned(__alignof__(struct obs_kernel_param)) = {__setup_str_debug, debug_kernel, 1 }
static const char __setup_str_quiet[] __initconst __aligned(1) = "quiet";
static struct obs_kernel_param __setup_quiet_kernel __used __section(".init.setup") __aligned(__alignof__(struct obs_kernel_param)) = {__setup_str_quiet, quiet_kernel, 1 }
Section
相关的obs_kernel_param 将在编译时按照一定的顺序放置在__section(".init.setup")中
#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_) \
_label_##_BEGIN_ = .; \
KEEP(*(_sec_)) \
_label_##_END_ = .;
#define INIT_SETUP(initsetup_align) \
. = ALIGN(initsetup_align); \
BOUNDED_SECTION_POST_LABEL(.init.setup, __setup, _start, _end)