例如产品中,major=0xC5;
|
static int alp_get_ontMajor(char *str) { gMajor = simple_strtoul(str + 2, NULL, 16); return 1; } __setup("major=", alp_get_ontMajor); //注册处理函数 unsigned long SYS_GetOntMajor(void) //提供给驱动使用 { return gMajor; } |
__setup宏的定义
|
/* * 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) \ __attribute__((aligned((sizeof(long))))) \ = { __setup_str_##unique_id, fn, early } #define __setup(str, fn) \ __setup_param(str, fn, fn, 0) |
进行转换:
|
__setup("major=", alp_get_ontMajor); ----------------------------------------------------------------------------------------------------------------- __setup_param("major=", alp_get_ontMajor, alp_get_ontMajor, 0) ----------------------------------------------------------------------------------------------------------------- static const char __setup_str_alp_get_ontMajor[] __initconst __aligned(1) = "major"; static struct obs_kernel_param __setup_str_alp_get_ontMajor __used __section(.init.setup) __attribute__((aligned((sizeof(long))))) = {__setup_str_alp_get_ontMajor, alp_get_ontMajor, 0} |
字符串被存储在__setup_str_alp_get_ontMajor,该变量被__initconst 及 __aligned(1)修饰;
__aligned(1):按照1字节对齐;
__initconst:表示将其修饰的变量放置在.init.rodata段中,ro:read only, rodata段放置字符串常量或define定义的常量
另外还声明一个obs_kernel_param 结构__setup_str_alp_get_ontMajor,
|
struct obs_kernel_param { const char *str; int (*setup_func)(char *); int early; }; |
该结构被__used 和__section(.init.setup)修饰:
__used: (网上查到的gcc扩展表示编译期间此值备用。)
__section(.init.setup):将obs_kernel_param 放置在.init.setup段中,这样该段就是obs_kernel_param 结构组成的列表
处理内核启动参数时,会来查找.init.setup段,并调用 *setup_func指向的函数
初始化相关宏如下:
|
#define __init __section(.init.text) __cold notrace #define __initdata __section(.init.data) #define __initconst __section(.init.rodata) #define __exitdata __section(.exit.data) #define __exit_call __used __section(.exitcall.exit) |
标记为初始化的函数和数据,表示该函数和数据仅在初始化期间使用。在模块装载后,模块装载就会将初始化函数扔掉;这样将函数占用的内存释放出来。