了解Linux进程管理

了解Linux进程管理

我尝试了解 Linux 内核的内部结构、进程管理以及进程的上下文切换。据我了解教程(来自该社区、IBM 等),按下电源按钮后,引导加载程序会加载内核。然后它启动调度程序并创建最终的 init 进程,该进程负责启动所有其他进程。

所以一段时间后,会发生上下文切换。在此上下文切换期间,内核查看新进程的页表并将其加载(如果需要)到 MMU 的 TLB 中。内核是否将整个页表(32 位系统上的 4 GB 虚拟内存)加载到 MMU 中?这个表交换是如何工作的,因为据我了解,顶部的 1 GB 内存将存在并且在所有进程中都不会被换出,因为这是内核内存?所有进程的页表是否都包含前 1 GB 内存的直接映射,以便前 1 GB 虚拟内存直接映射到前 1 GB 物理内存?

是否有某种关于此上下文切换如何工作的文档,因为我找不到任何为像我这样的菜鸟解释这一点的文档。

答案1

每个进程都有自己的一组页面,跨越 32 位 x86 计算机上的低 3 GB。 32 位计算机上的前 1 GB 对于所有进程都是通用的,并且不能从用户空间访问。顶部 1 GB 保留给内核,最初包含整个物理 RAM 偏移 3 GB 的映射。这意味着物理内存地址 0 在虚拟地址 0xc0000000 处可见,物理内存地址 1 在地址 0xc0000001 处可见,依此类推。当内存大小超过 1 GB 限制时,多余的物理内存开始通过“highmem”窗口访问。

在 x86-64 上,地址空间的上半部分保留给内核,下半部分保留给用户空间。请注意,当前硬件不允许使用整个 64 位地址空间:通常只有 48 个地址位可用,高 16 位必须全部为零或全部为 1。 (可用位数的确切数量因 CPU 型号而异。)

在上下文切换时,映射的用户空间部分被新进程的映射替换,但内核部分保持不变。整个 4 GB 内存空间没有被映射,只有实际使用的部分。这允许使用更小的页表树。初始映射由包含要运行的程序的 ELF 文件确定。当动态分配新内存、使用映射mmap或自动扩展堆栈时,页表会根据需要进行修改。

调度程序没有“启动”,因为它不是一个单独的进程。当正在运行的进程需要等待输入或某些其他事件时,或者当当前进程用完其时间片时,内核会重新调度进程。每个进程都处于几种状态之一,例如等待某个事件、准备运行或正在运行。当内核进行重新调度时,它会检查准备运行的进程列表,并选择一个(每个 CPU)来运行下一个。

此外,转换后备缓冲区 (TLB) 不是由内核直接加载(在 x86 处理器上)。软件仅修改页表,硬件在运行时根据需要自动填充TLB中的条目。 TLB可以通过软件刷新;这需要在上下文切换时完成。

已经写了一些关于 Linux 内核内部结构的书籍(例如“Understanding the Linux Kernel”),但其中大多数已经很老了。但是,即使它们不再是好的参考,其中许多确实提供了相关信息,但您必须记住,很多事情已经发生了变化。

相关内容