1.文件系统成分分析
要求:
文件系统层次
熟悉每个文件夹里的内容
分析文件系统的工作流程(起点: 目的:可以运行其他应用程序 可以相应用户命令)
起点分析:
static int __init kernel_init(void * unused)
init_post();
init_post(): 这是内核启动应用程序的接口
static noinline int init_post(void)
{
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
free_initmem();
mark_rodata_ro();
system_state = SYSTEM_RUNNING;
numa_default_policy();
current->signal->flags |= SIGNAL_UNKILLABLE;
if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
//如果命令行被定义,则执行自定义的程序
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
//若命令行为空,则顺序执行默认程序
run_init_process("/sbin/init");//都是由busybox所提供
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
panic("No init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}
execute_command在init_setup函数中被赋值
static int __init init_setup(char *str)
{
unsigned int i;
execute_command = str;
/*
* In case LILO is going to boot us with default command line,
* it prepends "auto" before the whole cmdline which makes
* the shell think it should execute a script with such name.
* So we ignore all arguments entered _before_ init=... [MJ]
*/
for (i = 1; i < MAX_INIT_ARGS; i++)
argv_init[i] = NULL;
return 1;
}
__setup("init=", init_setup);
//在init.h中定义
#define __setup(str, fn) \
__setup_param(str, fn, fn, 0)
//__setup_param定义
#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 }
struct obs_kernel_param {
const char *str;
int (*setup_func)(char *);
int early;
};
obsolete_checksetup处理early为0的命令
static int __init obsolete_checksetup(char *line)
{
const struct obs_kernel_param *p;
int had_early_param = 0;
p = _start;
do {
int n = strlen(p->str);
if (parameqn(line, p->str, n)) {
if (p->early) {
/* Already done in parse_early_param?
* (Needs exact match on param part).
* Keep iterating, as we can have early
* params and __setups of same names 8( */
if (line[n] == '\0' || line[n] == '=')
had_early_param = 1;
} else if (!p->setup_func) {
printk(KERN_WARNING "Parameter %s is obsolete,"
" ignored\n", p->str);
return 1;
} else if (p->setup_func(line + n))
return 1;
}
p++;
} while (p < __setup_end);
return had_early_param;
}
do_early_param处理early为1的命令
/* Check for early params. */
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 && parameq(param, p->str)) ||
(strcmp(param, "console") == 0 &&
strcmp(p->str, "earlycon") == 0)
) {
if (p->setup_func(val) != 0)
printk(KERN_WARNING
"Malformed early option '%s'\n", param);
}
}
/* We accept everything at this stage. */
return 0;
}
execute_command:
UBOOT传入的"init=linuxrc"
execute_command=linuxrc
if (linuxrc)
run_init_process(linuxrc);//内核切换到了linuxrc程序执行
在linux中linuxrc指向了busybox
1.文件系统进入后内核运行了什么应用程序
2.文件系统的初始化模式是否和内核是一样的
接收配置信息传入
传入参数的格式
解析配置信息
如何进行解析 并且识别
应用配置信息
如何进行信息的使用