linux idle 进程(0号进程)的问题
根据资料,linux idle 进程是不通过folk()产生的系统第一个进程,也就是所谓的 “ 0号进程 ”。
我曾经读过linux0.11版本的内核源代码,在linux0.11中,也是有0号进程的概念,我记得在linux0.11中有个move_to_user_mode()宏,在main()函数中,当系统模块初始化完成后会调用这个宏,模拟中断返回,将整个启动代码放入到0号进程中继续执行。
但我发现在linux高版本的内核源代码中,貌似在启动过程中没有再调用这个move_to_user_mode()宏了,那么它现在是怎么做到切换到0号进程的呢?为什么删掉move_to_user_mode()这个过程呢?
------解决方案--------------------
以3.10内核为例,task 0 的进程结构(task_struct init_task)由INIT_TASK宏静态定义。该结构体(init_task)在linux启动时被设置为current_task。当初始化到rest_init函数中时,通过kernel_thread函数启动第一个内核线程kernel_init。kernel_init再通过do_execve启动/sbin/init。这就是我们看到的init进程,进程号为1。初始化的最后linux调用scheule()整个系统就运行起来了。
我感觉这个的task 0并不同于你说的linux 0.11的0号进程,因为它是一个kernel thread,并不包含运行在user space的代码。相反,task 1即init进程类似于你的0号进程,它运行user space代码。
UID PID PPID LWP C NLWP STIME TTY TIME CMD
root 1 0 1 0 1 02:56 ? 00:00:01 /sbin/init
root 2 0 2 0 1 02:56 ? 00:00:00 [kthreadd]
/* Initial task structure */
struct task_struct init_task = INIT_TASK(init_task);
EXPORT_SYMBOL(init_task);
static noinline void __init_refok rest_init(void)
{
int pid;
rcu_scheduler_starting();
/*
* 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 __ref kernel_init(void *unused)
{
kernel_init_freeable();
/* 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();
flush_delayed_fput();
if (ramdisk_execute_command) {
if (!run_init_process(ramdisk_execute_command))
return 0;
pr_err("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) {
if (!run_init_process(execute_command))
return 0;
pr_err("Failed to execute %s. Attempting defaults...\n",
execute_command);
}
if (!run_init_process("/sbin/init")
------解决方案--------------------