在start_kernel最后的rest_init函数中内核创建了两个内核线程,一个是内核线程的管理者,另一个是内核初始化线程kernel_init.
kernel_init它将完成设备驱动程序的初始化,并调用init_post函数启动用户空间的init进程。
static int __init kernel_init(void * unused)
{
/*Wait until kthreadd is all set-up.*/
wait_for_completion(&kthreadd_done);
/* Now the scheduler is fully set up and can do blocking allocations */
gfp_allowed_mask = __GFP_BITS_MASK;
/* init can allocate pages on any node */
set_mems_allowed(node_states[N_HIGH_MEMORY]);
/* init can run on any cpu. */
set_cpus_allowed_ptr(current, cpu_all_mask);
cad_pid = task_pid(current);
smp_prepare_cpus(setup_max_cpus);
do_pre_smp_initcalls();
lockup_detector_init();
smp_init();
sched_init_smp();
//以上代码是在SMP系统做准备,激活所有CPU,并开始SMP系统的调度
/*do_basic_setup函数主要是初始化设备驱动,完成其他驱动程序(直接编译进内核的模块)的初始化。内核中大部分的启动数据输出(都是各设备的驱动模块输出ÿ