内核初始化过程中,挂载根文件系统后,怎么初始化的呢?以linux-2.6.35为例,先看看内核初始化时候,做了些什么?
1、内核初始化到文件系统初始化
init/main.c(内核C入口)
asmlinkage void __init start_kernel(void)
{
...
rest_init();
}
static noinline void __init_refok rest_init(void)
__releases(kernel_lock)
{
...
/*
* We need to spawn init first so that it obtains pid 1, however
* the init task will end up wanting to create kthreads, which, if
* we schedule it before we create kthreadd, will OOPS.
*/
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
...
}
static int __init kernel_init(void * unused)
{
...
init_post();
return 0;
}
static noinline int init_post(void)
__releases(kernel_lock)
{
...
run_init_process("/sbin/init");
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.");
}
static void run_init_process(char *init_filename)
{
argv_init[0] = init_filename;
kernel_execve(init_filename, argv_init, envp_init);
}
static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
struct pt_regs regs;
int ret;
memset(®s, 0, sizeof(struct pt_regs));
ret = do_execve((char *)filename, (char __user * __user *)argv,
(char __user * __user *)envp, ®s);
...
}
简单说就是:
start_kernel()--->rest_init()--开启内核线程-->kernel_init()--->init_post()--->run_init_process("/sbin/init")