- 对 linux 进行分类的第三阶段 : 除去idle外的所有的进程
1 : kernel_init
2 : kthreadd
3 : ...
...
创建过程
与cpu 的关系
内核裸机程序创建了 1号内核进程
kernel_thread(kernel_init, NULL, CLONE_FS);
1号内核进程 调用 do_execve 将自己转换为 1号用户进程
run_init_process 调用 do_execve
创建过程
与cpu 的关系
内核裸机程序 创建了 kthreadd 进程
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
3个进程跑的顺序 : (在 switch_to的调用处 和 finish_task_switch 处 加断点)
rest_init(进程0) -> schedule_preempt_disabled -> schedule ->
kthreadd(进程2) -> schedule ->
kernel_init(进程1) -> kernel_init_freeable -> do_basic_setup -> usermodehelper_init -> __alloc_workqueue_key -> kthread_create_on_node -> wait_for_completion_killable -> do_wait_for_common -> schedule_timeout -> schedule
kthread(进程x?) -> schedule ->
kernel_init(进程1) -> kernel_init_freeable -> do_basic_setup -> driver_init -> devtmpfs_init -> kthread_create_on_node -> wait_for_completion_killable -> do_wait_for_common -> schedule_timeout -> schedule
kthreadd(进程2) -> schedule ->
...
进程1 进程2 进程3 相互交缠 百余次
...
cpu_startup_entry(进程0)
其他
问题 : 在 还未执行 run_init_process 的那一刻,有多少内核线程?多少用户进程?
: 这些进程有什么用?
目前确定有的有这些
idle
kernel_init
kthread
kthreadd
可在 run_init_process 前, 遍历(如何遍历?)
do_initcalls 开始 - level2(?) kthreadd 就不被调度
而是 kthread 和 kernel_init 交缠执行
同时 kthread 会 调用
1.kthread->rescuer_thread->process_scheduled_works->process_one_work->_cond_resched->preempt_schedule_common->__schedule
2.kthread->worker_thread->process_one_work->_cond_resched->preempt_schedule_common->__schedule
3.kthread->rcu_gp_kthread->schedule_timeout->schedule->__schedule
4.kthread->smpboot_thread_fn->schedule
5.kthread->devtmpfsd->schedule