本文主要是介绍Linux idle进程创建过程(kernel 4.14),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
idle进程是内核创建的第一个进程,也常常被叫做swapper 进程:
asmlinkage __visible void __init start_kernel(void)
{char *command_line;char *after_dashes;set_task_stack_end_magic(&init_task);
idle进程也是唯一一个不是通过fork产生的进程,他是静态定义的一个进程,init_task就是它的任务结构体。在start_kernel函数的最后:
asmlinkage __visible void __init start_kernel(void)
{
....../* Do the rest non-__init'ed, we're now alive */
rest_init();}
rest_init函数中会创建我们系统的第一个用户空间进程,那就是大名鼎鼎的pid为1的init进程。init进程是所有用户空间进程的祖先进程,而idle进程是所有进程的祖先进程。
static noinline void __ref rest_init(void){struct task_struct *tsk;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.*/pid = kernel_thread(kernel_init, NULL, CLONE_FS);
static int __ref kernel_init(void *unused){int ret;kernel_init_freeable();/* need to finish all async __init code before freeing the memory */async_synchronize_full();ftrace_free_init_mem();free_initmem();mark_readonly();system_state = SYSTEM_RUNNING;numa_default_policy();rcu_end_inkernel_boot();if (ramdisk_execute_command) {ret = run_init_process(ramdisk_execute_command);if (!ret)return 0;pr_err("Failed to execute %s (error %d)\n",ramdisk_execute_command, ret);}/** 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) {ret = run_init_process(execute_command);if (!ret)return 0;panic("Requested init %s failed (error %d).",execute_command, ret);}if (!try_to_run_init_process("/sbin/init") ||!try_to_run_init_process("/etc/init") ||!try_to_run_init_process("/bin/init") ||!try_to_run_init_process("/bin/sh"))return 0;panic("No working init found. Try passing init= option to kernel. "
在init进程创建完成后,该进程还会创建kthreadd进程,最后进入do_idle,也就是我们所说的idle进程所做的事情,让cpu 进入idle状态。
void cpu_startup_entry(enum cpuhp_state state)
{/** This #ifdef needs to die, but it's too late in the cycle to* make this generic (arm and sh have never invoked the canary* init for the non boot cpus!). Will be fixed in 3.11*/#ifdef CONFIG_X86 /** If we're the non-boot CPU, nothing set the stack canary up* for us. The boot CPU already has it initialized but no harm* in doing it again. This is a good place for updating it, as* we wont ever return from this function (so the invalid* canaries already on the stack wont ever trigger).*/boot_init_stack_canary();
#endifarch_cpu_idle_prepare();cpuhp_online_idle(state);while (1)do_idle();
}
这篇关于Linux idle进程创建过程(kernel 4.14)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!