【发布时间】:2020-09-23 23:50:48
【问题描述】:
我正在尝试更多地了解process 0,例如,它是否具有内存描述符(非NULLtask_struct->mm 字段),以及它与交换或空闲进程有何关系。在我看来,在引导 cpu 上创建了一个“进程 0”,然后idle_threads_init 为每个其他 cpu 创建了一个空闲线程,但我没有找到第一个(我假设是process 0) 已创建。
更新
鉴于 tychen 引用的live book,这是我对process 0(适用于x86_64)的最新理解,有人可以确认/反驳以下内容吗?
- 一个
init_task类型为task_struct是静态定义的,任务的内核堆栈init_task.stack = init_stack,内存描述符init_task.mm=NULL和init_task.active_mm=&init_mm,其中堆栈区域init_stack和mm_structinit_mm都是静态定义。 - 只有
active_mm是非NULL 的事实意味着process 0是一个内核进程。另外,init_task.flags=PF_KTHREAD。 - 在未压缩的内核映像开始执行后不久,启动 cpu starts 以使用
init_stack作为内核堆栈。这使得current宏有意义(自机器启动以来第一次),这使得fork()成为可能。在此之后,内核实际上在process 0的上下文中运行。 -
start_kernel->arch_call_rest_init->rest_init,在这个函数内部,process 1&2被分叉了。在为process 1安排的kernel_init函数中,为每个其他逻辑CPU 创建了一个新线程(带有CLONE_VM)并将其挂接到CPU 的运行队列的rq->idle。 - 有趣的是,所有空闲线程共享相同的
tid 0(不仅仅是tgid)。通常线程共享tgid,但有不同的tid,这实际上是Linux 的process id。我想它不会破坏任何东西,因为空闲线程被锁定到它们自己的 CPU。 -
kernel_init加载init可执行文件(通常为/sbin/init),并将current->mm和active_mm切换为非NULLmm_struct,并清除PF_KTHREAD标志,这使得process 1一个合法的用户空间进程。虽然process 2没有调整mm,这意味着它仍然是一个内核进程,与process 0相同。 -
rest_init结束时,do_idle接管,表示所有CPU都有空闲进程。 - 以前有一些事情让我很困惑,但现在变得清晰了:
init_task/init_mm/init_stack等init_*对象/标签都被process 0使用,而不是init process,即process 1。
【问题讨论】:
-
请不要编辑问题的答案。将其作为答案发布,它可以与问题分开获得投票。 (并且在将来的某个时候,如果它变得过时,不会被置于其他答案之上。)
-
好的。有些东西我不确定,因此它们出现在问题中,但你说的有道理。我可以将它们放在单独的答案线程中以收集反馈。
-
哦,如果这仍然是您要求确认的内容,并且不确定是否正确,那么提出问题是有道理的。
-
好的,我会在正文中明确说明。
标签: c assembly linux-kernel x86 boot