已经解析出的“init=”后的字符串指针赋给全局变量execute_command。而这个execute_command就是内核初始化到最后执行的用户空间初始化程序。
内核对于cmdline的处理分为两个步骤:早期处理和后期处理。
1、cmdline的早期处理
对于ARM构架,cmdline的早期处理是在setup_arch函数中的parse_early_param();,但这个函数定义在init/main.c:
点击(此处)折叠或打开
/*检查早期参数.
*/
static int __init do_early_param(char
*param, char
*val)
{
const struct obs_kernel_param
*p;
for (p
= __setup_start; p
< __setup_end; p++)
{
if ((p->early
&& strcmp(param, p->str)
== 0)
||
(strcmp(param,
"console")
== 0 &&
strcmp(p->str,
"earlycon")
== 0)
) {
if
(p->setup_func(val)
!= 0)
printk(KERN_WARNING
"Malformed early option '%s'n", param);
}
}
/*这个阶段我们接受任何异常.
*/
return 0;
}
点击(此处)折叠或打开
此函数通过解析好的参数名及参数值,在上面介绍的“.init.setup”段中搜索匹配的“struct obs_kernel_param”结构体(必须标志为early,也就是用early_param(str, fn)宏定义的结构体),并调用参数处理函数。
void __init parse_early_options(char
*cmdline)
{
parse_args("early options", cmdline, NULL, 0, do_early_param);
点击(此处)折叠或打开
这里通过统一的parse_args函数处理,此函数原型如下:
点击(此处)折叠或打开
int parse_args(const char
*name,
char *args,
const struct kernel_param
*params,
unsigned num,
int
(*unknown)(char
*param, char
*val))
这个函数的处理方法主要是分离出每个类似“foo=bar,bar2”的形式,再给next_arg分离出参数名和参数值,并通过参数名在“const struct kernel_param *params”指向的地址中搜索对应的数据结构,并调用其参数处理函数。如果没有找到就调用最后一个参数“unknown”传递进来的未知参数处理函数。由于此处params为NULL,必然找不到对应的数据结构,所有分离好的参数及参数名都由最后一个函数指针参数指定的函数do_early_param来处理。也就是上面那个函数。
}
/* 构架相关代码在早期调用这个函数, 如果没有, 会在解析其他参数前再次调用这个函数。*/
void __init parse_early_param(void)
{