内核中对cmdline的解析
Posted 正在起飞的蜗牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内核中对cmdline的解析相关的知识,希望对你有一定的参考价值。
1、__setup宏
参考博客:《__setup宏定义》。
2、内核中解析cmdline的函数调用关系
start_kernel()
parse_early_param()
parse_early_options()
parse_args();
next_arg()
parse_one()
do_early_param()
3、parse_early_param()函数
void __init parse_early_param(void)
static __initdata int done = 0;
static __initdata char tmp_cmdline[COMMAND_LINE_SIZE];
if (done)
return;
/* All fall through to do_early_param. */
strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
parse_early_options(tmp_cmdline);
done = 1;
parse_early_param()函数调用parse_early_options()函数,并将cmdline传入。boot_command_line变量保存的是uboot传递给内核的cmdline,具体是在内核解析tag参数时赋值。
4、parse_early_options()函数
void __init parse_early_options(char *cmdline)
parse_args("early options", cmdline, NULL, 0, do_early_param);
调用parse_args()函数并将cmdline和do_early_param函数指针传入。
5、parse_args()函数
int parse_args(const char *name,
char *args,
struct kernel_param *params,
unsigned num,
int (*unknown)(char *param, char *val))
char *param, *val;
/* Chew leading spaces */
args = skip_spaces(args);
while (*args)
int ret;
int irq_was_disabled;
args = next_arg(args, ¶m, &val);//解析cmdline的格式解析出cmdline的每个单元
irq_was_disabled = irqs_disabled();
ret = parse_one(param, val, params, num, unknown);
if (irq_was_disabled && !irqs_disabled())
······
switch (ret)
······
return 0;
(1)next_arg()函数:按照cmdline的格式逐个解析;
比如cmdline=“root=/dev/mmcblk0p2 rootfstype=ext3”
第一次解析结果:param=“root”,val="/dev/mmcblk0p2"
第二次解析结果:param=“rootfstype”,val=“ext3”
(2)parse_one()函数:
对每个从cmdline解析出的单元进行处理;
6、parse_one()函数
static int parse_one(char *param,
char *val,
struct kernel_param *params,
unsigned num_params,
int (*handle_unknown)(char *param, char *val))
······
//handle_unknown函数指针就是do_early_param()函数
if (handle_unknown)
DEBUGP("Unknown argument: calling %p\\n", handle_unknown);
return handle_unknown(param, val);
DEBUGP("Unknown argument `%s'\\n", param);
return -ENOENT;
对next_arg()函数解析出的param和val进行处理,handle_unknown函数指针就是do_early_param()函数。具体的解析工作都是do_early_param()函数做的。
7、do_early_param()函数
static int __init do_early_param(char *param, char *val)
struct obs_kernel_param *p;
for (p = __setup_start; p < __setup_end; p++) //遍历".init.setup"段,寻找匹配的obs_kernel_param结构体
if ((p->early && strcmp(param, p->str) == 0) ||
(strcmp(param, "console") == 0 &&
strcmp(p->str, "earlycon") == 0)
)
if (p->setup_func(val) != 0) //匹配到obs_kernel_param结构体就执行绑定的处理函数
printk(KERN_WARNING
"Malformed early option '%s'\\n", param);
/* We accept everything at this stage. */
return 0;
(1)__setup_start和__setup_end是".init.setup"段的起始/结束地址;
(2)".init.setup"段的遍历结合__setup宏和链接脚本进行理解;
以上是关于内核中对cmdline的解析的主要内容,如果未能解决你的问题,请参考以下文章