__setup宏定义
struct obs_kernel_param {
const char *str;
int (*setup_func)(char *);
int early;
};
#define __initconst __section(.init.rodata)
#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) \
__attribute__((aligned((sizeof(long))))) \
= { __setup_str_##unique_id, fn, early }
#define __setup(str, fn) __setup_param(str, fn, fn, 0)
在linux/include/init.h中定义;
__setup宏的使用
static int __init root_dev_setup(char *line)
{
strlcpy(saved_root_name, line, sizeof(saved_root_name));
return 1;
}
__setup("root=", root_dev_setup);
用来绑定cmdline中解析出的功能的处理函数,上面的例子就是绑定root_dev_setup()函数去处理cmdline中指定的根文件系统位置(root=xxx)。
__setup宏的功能作用
__setup宏将处理函数和从cmdline解析出的参数进行绑定;比如上面的作用就是在cmdline中
解析出"root=/dev/mmcblk0p7",就会调用root_dev_setup()函数,把"/dev/mmcblk0p7"作为参数
传递给root_dev_setup()函数。
__setup宏的展开
//将下面的宏展开
__setup("root=", root_dev_setup);
//展开的结果
static const char __setup_str_root_dev_setup[] __section(.init.rodata) \
__aligned(1) = str; \
static struct obs_kernel_param __setup_root_dev_setup \
__used __section(.init.setup) \
__attribute__((aligned((sizeof(long))))) \
= { __setup_str_root_dev_setup, root_dev_setup, 0}
__setup宏解析
(1)__initconst:“.init.rodata"段属性是放代码常量的;
(2)__section(.init.setup):将处理cmdline的obs_kernel_param类型变量都集中放在”.init.setup"段,
在链接脚本可以指定该段的起始地址(__setup_start)和结束地址(__setup_end);
(3)__setup宏的作用:定义了一个静态常量字符数组和静态局部obs_kernel_param类型变量,并复制;
将字符数组赋予".init.rodata"段属性,obs_kernel_param类型变量赋予".init.setup"段属性;