在上面已经对基本的硬件、系统的结构初始化完成,接着下来系统要做的工作,就是创建进程,对进程进行管理,才可以让系统生生不息,处理各种各样的任务。虽然大部份的初始化工作已经完成,但还需要更进一步初始化,因此创建一个内核初始化线程来继续初始化。为了有一个干净,又可以拷贝,又方便创建线程的方法,就是创建一个特别的内核线程kthreadd,这样所有以后需要创建的线程都是由这个线程创建出来的,可以说这个线程为其余内核线程之母。创建完这两个线程之后,初始化进程还需要对线程调度器的状态进行运行一次,以便初始化到合适的值。最后,这个初始化进程就退化为一个IDLE空闲进程了,完成了引导系统所有的工作,进入系统正常运行的状态。具体的代码如下:
staticvoid noinline __init_refok rest_init(void)
__releases(kernel_lock)
{
intpid;
kernel_thread(kernel_init,NULL, CLONE_FS | CLONE_SIGHAND);
这行代码是调用创建内核线程函数kernel_thread来创建内核第二阶段的初始化线程。
numa_default_policy();
这行代码是设置当前进程使用缺省的内存管理策略。
pid= kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
这行代码是创建一个干净内核线程,以便以后其它所有内核线程全部拷贝它,并由它来创建,这样达到更方便创建线程,不用设置太多参数。
kthreadd_task= find_task_by_pid_ns(pid, &init_pid_ns);
这行代码是通过进程ID查找内核线程的任务地址,并保存起来,方便访问。
unlock_kernel();
这行代码是释放大内核锁,以便多CPU可以访问内核代码。
/*
* The boot idle thread must execute schedule()
* at least once to get things moving:
*/
init_idle_bootup_task(current);
这行代码是初始化空闲进程的调度器,以便让空闲进程知道怎么样调度任务列表里的进程。current是指向当前IDLE任务的结构。
preempt_enable_no_resched();
这行代码是减少内核抢先计数,并且不进行调度操作。这样运行后,以便IDLE进程可以让别的高优先级的进程运行。
schedule();
这行代码是调用进程调度函数schedule,主要初始化调度器可以切换回到空闲任务。
preempt_disable();
这行代码是增加内核抢先计数。
/*Call into cpu_idle with preempt disabled */
cpu_idle();
这行代码是调用CPU空闲任务进程运行,不再返回来。
}
//QQ:9073204 EMAIL:[email protected]
//蔡军生 2012-9-8