多个进程的 x86 处理器 'aware' 如何 运行?
How are x86 processors 'aware' of multiple processes being run?
我确定这个问题的答案在互联网上的某个地方(甚至是 Whosebug),但是,我很难制定问题来获得好的结果。
上周我一直在研究 x86,并且对 x86 处理器是 'aware' 不同进程 运行ning 的概念感到困惑。例如,当在保护模式下运行时,x86 处理器能够限制进程可以访问的内存。这让我相信处理器以某种方式知道存在多个进程。
这让我很困惑。从处理器的角度来看,我假设它只是获取要执行的指令列表,操作系统负责对这些指令进行排序(通过时间片、内存管理等),以便多个进程可以 运行。从处理器的角度来看,我假设它看到的只是一个顺序指令列表。
但是,由于 x86 处理器可以按进程限制内存访问,CPU 以某种方式意识到存在多个进程。
CPU不了解进程调度,后者可以通过多种不同的方式实现,而前者必须是通用芯片。
这是怎么回事
- OS 处于控制之中(阅读:CPU 正在执行一个 OS 例程)并设置一个沙箱 A 用于 运行进程 A.
- 进程 A 在此沙箱内执行。
- 发生周期性中断,为该中断服务的例程属于OS并且在沙箱之外。
- OS 处于控制之中,并设置了一个沙箱 B,用于 运行 一定量的进程 B。
- 进程 B 在此沙箱内执行。
重复该过程。
保护模式让OS创建沙箱,特别是它定义了权限(在实模式下每个程序都有相同的权限)这样进程A和进程B就无法逃脱沙箱(例如通过禁用中断和 运行ning 永远)。
CPU 不知道发生了什么,它只是看到在不同权限下执行的一系列指令和 "constraints"。
在执行不同的程序之前,OS 对 CPU 进行了不同的配置。
这也有助于解释线程和进程之间的区别:线程调度不会改变沙箱。
Jester 在评论中记得我,x86 支持任务管理。
但是,HW 任务不会将 one-to-one 映射到 OS 进程(IIRC 主要 OSes 很少使用此功能)。
阅读 Intel Manual 3 将帮助您了解 CPU 的功能以及安全 OS 的责任从 CPU 转移到内核的位置。
CPU 一次看到一个进程。 CPU 不知道进程,除非它正在执行。
For example, when operating in protected mode, the x86 processor is able to limit the memory in which a process can access.
您描述的是逻辑地址转换。操作系统为提供从逻辑页面到物理页面框架的映射的进程定义一组页面tables。页面 tables 还定义了允许访问这些页面的权限。每个进程都有自己的一组页面 tables(在某些情况下,可以共享该组的部分)。
页面的结构 tables 由处理器定义。那些 table 的内容是由操作系统建立的。因此,内存上的 "limit" 来自操作系统。
更改当前进程(由操作系统触发)的部分过程是为新进程交换页面 tables 以代替旧进程。
处理器从当前正在执行的进程的角度来看 "limits" 内存访问,并且在任何给定时间都不知道任何等效的 "limits"(第 table 页) 任何其他进程。
However, due to the fact that an x86 processor can limit memory access by process, the CPU is somehow aware that there are multiple processes.
CPU只知道当前进程的页面table。它只知道正在执行的进程上的 "limits"。当前页面 table 集定义了进程可以访问的物理内存以及它可以访问的方式(read/write/execute + 模式限制)。
From the processors perspective, I assume all it would see is a sequential list of instructions.
加上作为进程调度的关键部分的中断。
从硬件的角度来看,CPU 所做的只是 "execute instructions",一次一个。在某种(也许稍微简化)的意义上,这就是所有发生的事情。
如果你有一些特定的计算任务要执行,你确实可以编写一个合适的指令流,这样你就可以打开你的硬件,它执行你的指令,然后停止,或关闭,或其他任何事情。实际上,这就是早期计算机的运行方式。
但是,这种操作计算机的模式非常笨拙,根本无法扩展,因为它需要一个操作员负责一切,并且在此过程中重新发明各种轮子。这就是 操作系统 的概念所在: OS 是一种特定类型的指令流,它在 start-up 处加载,可以 turn 加载并执行其他指令位,动态。这种划分允许重用核心功能(想想设备驱动程序),并动态调整机器的功能(即当它是 运行 时,而不是重新编程和重置它)。此外,它允许动态加载的指令的那些部分由不同的人编写,因此我们有一个可以执行 "user-defined instructions" 的单一平台,即我们通常理解的 "program".
所以现在我们有了所有的部分: CPU 启动时执行的代码是操作系统,操作系统动态管理进一步代码的执行。大多数这些执行单元称为 进程 。 (但并不是所有的代码都是这样的,比如Linux中的可加载内核模块是动态加载的,但不构成进程。)也就是说,进程是操作系统中的一个抽象概念,它划分了OS 自己的代码和它根据请求运行的 "hosted" 代码。
根据 OS 的类型,进程的执行可能具有奇特的功能,例如虚拟内存(每个进程都看到自己的独立内存)和保护(任何进程都不能干扰 OS 或其他进程)。 OSes 通过使用 CPU 功能来实现这些功能:提供地址转换的内存管理器单元,以及限制可用于执行的指令的保护环。不过,并非所有 OSes 都这样做;例如,在 DOS 中,每个进程都可以完全访问物理内存,从而访问 OS 的状态。无论如何,OS 通常为进程提供 API(例如 "system calls"),再次使用硬件功能(中断或特殊系统调用指令),并且用户代码通常通过此与环境交互API 而不是直接与外围设备对话。例如,这意味着硬件驱动程序仅由 OS 实现,用户代码可以进行不透明的 "print output" 调用而无需了解可用输出设备的详细信息。
示例: 可能有助于说明流行的 Linux 操作系统上的进程,x86 硬件上的 运行:启动了一个新进程当现有进程(例如 shell 或 init
)通过引发中断 128 调用 clone
系统调用时。中断使 CPU 将控制转移到中断处理程序例程,由 OS 在 boot-up 期间设置。当进入中断处理程序时,CPU 切换到 ring 0,特权模式。中断处理程序使内核创建新进程,然后将控制权转回调用进程(这意味着切换到保护环 3,无特权;进程只在环 3 中执行)。对于新进程的创建,内核创建相关的内部簿记结构,在MMU中建立新的页表,然后将控制权转移到clone
调用的入口点,类似于原来的方式呼叫 returns。 (我在这里掩盖了调度问题;一次只发生一次控制转移,其他 "scheduled" 稍后发生。)现在存在新进程的事实仅反映在内核的内部簿记数据。 CPU 对此一无所知;它所看到的只是触发中断和定期更改页表。
我确定这个问题的答案在互联网上的某个地方(甚至是 Whosebug),但是,我很难制定问题来获得好的结果。
上周我一直在研究 x86,并且对 x86 处理器是 'aware' 不同进程 运行ning 的概念感到困惑。例如,当在保护模式下运行时,x86 处理器能够限制进程可以访问的内存。这让我相信处理器以某种方式知道存在多个进程。
这让我很困惑。从处理器的角度来看,我假设它只是获取要执行的指令列表,操作系统负责对这些指令进行排序(通过时间片、内存管理等),以便多个进程可以 运行。从处理器的角度来看,我假设它看到的只是一个顺序指令列表。
但是,由于 x86 处理器可以按进程限制内存访问,CPU 以某种方式意识到存在多个进程。
CPU不了解进程调度,后者可以通过多种不同的方式实现,而前者必须是通用芯片。
这是怎么回事
- OS 处于控制之中(阅读:CPU 正在执行一个 OS 例程)并设置一个沙箱 A 用于 运行进程 A.
- 进程 A 在此沙箱内执行。
- 发生周期性中断,为该中断服务的例程属于OS并且在沙箱之外。
- OS 处于控制之中,并设置了一个沙箱 B,用于 运行 一定量的进程 B。
- 进程 B 在此沙箱内执行。
重复该过程。
保护模式让OS创建沙箱,特别是它定义了权限(在实模式下每个程序都有相同的权限)这样进程A和进程B就无法逃脱沙箱(例如通过禁用中断和 运行ning 永远)。
CPU 不知道发生了什么,它只是看到在不同权限下执行的一系列指令和 "constraints"。
在执行不同的程序之前,OS 对 CPU 进行了不同的配置。
这也有助于解释线程和进程之间的区别:线程调度不会改变沙箱。
Jester 在评论中记得我,x86 支持任务管理。
但是,HW 任务不会将 one-to-one 映射到 OS 进程(IIRC 主要 OSes 很少使用此功能)。
阅读 Intel Manual 3 将帮助您了解 CPU 的功能以及安全 OS 的责任从 CPU 转移到内核的位置。
CPU 一次看到一个进程。 CPU 不知道进程,除非它正在执行。
For example, when operating in protected mode, the x86 processor is able to limit the memory in which a process can access.
您描述的是逻辑地址转换。操作系统为提供从逻辑页面到物理页面框架的映射的进程定义一组页面tables。页面 tables 还定义了允许访问这些页面的权限。每个进程都有自己的一组页面 tables(在某些情况下,可以共享该组的部分)。
页面的结构 tables 由处理器定义。那些 table 的内容是由操作系统建立的。因此,内存上的 "limit" 来自操作系统。
更改当前进程(由操作系统触发)的部分过程是为新进程交换页面 tables 以代替旧进程。
处理器从当前正在执行的进程的角度来看 "limits" 内存访问,并且在任何给定时间都不知道任何等效的 "limits"(第 table 页) 任何其他进程。
However, due to the fact that an x86 processor can limit memory access by process, the CPU is somehow aware that there are multiple processes.
CPU只知道当前进程的页面table。它只知道正在执行的进程上的 "limits"。当前页面 table 集定义了进程可以访问的物理内存以及它可以访问的方式(read/write/execute + 模式限制)。
From the processors perspective, I assume all it would see is a sequential list of instructions.
加上作为进程调度的关键部分的中断。
从硬件的角度来看,CPU 所做的只是 "execute instructions",一次一个。在某种(也许稍微简化)的意义上,这就是所有发生的事情。
如果你有一些特定的计算任务要执行,你确实可以编写一个合适的指令流,这样你就可以打开你的硬件,它执行你的指令,然后停止,或关闭,或其他任何事情。实际上,这就是早期计算机的运行方式。
但是,这种操作计算机的模式非常笨拙,根本无法扩展,因为它需要一个操作员负责一切,并且在此过程中重新发明各种轮子。这就是 操作系统 的概念所在: OS 是一种特定类型的指令流,它在 start-up 处加载,可以 turn 加载并执行其他指令位,动态。这种划分允许重用核心功能(想想设备驱动程序),并动态调整机器的功能(即当它是 运行 时,而不是重新编程和重置它)。此外,它允许动态加载的指令的那些部分由不同的人编写,因此我们有一个可以执行 "user-defined instructions" 的单一平台,即我们通常理解的 "program".
所以现在我们有了所有的部分: CPU 启动时执行的代码是操作系统,操作系统动态管理进一步代码的执行。大多数这些执行单元称为 进程 。 (但并不是所有的代码都是这样的,比如Linux中的可加载内核模块是动态加载的,但不构成进程。)也就是说,进程是操作系统中的一个抽象概念,它划分了OS 自己的代码和它根据请求运行的 "hosted" 代码。
根据 OS 的类型,进程的执行可能具有奇特的功能,例如虚拟内存(每个进程都看到自己的独立内存)和保护(任何进程都不能干扰 OS 或其他进程)。 OSes 通过使用 CPU 功能来实现这些功能:提供地址转换的内存管理器单元,以及限制可用于执行的指令的保护环。不过,并非所有 OSes 都这样做;例如,在 DOS 中,每个进程都可以完全访问物理内存,从而访问 OS 的状态。无论如何,OS 通常为进程提供 API(例如 "system calls"),再次使用硬件功能(中断或特殊系统调用指令),并且用户代码通常通过此与环境交互API 而不是直接与外围设备对话。例如,这意味着硬件驱动程序仅由 OS 实现,用户代码可以进行不透明的 "print output" 调用而无需了解可用输出设备的详细信息。
示例: 可能有助于说明流行的 Linux 操作系统上的进程,x86 硬件上的 运行:启动了一个新进程当现有进程(例如 shell 或 init
)通过引发中断 128 调用 clone
系统调用时。中断使 CPU 将控制转移到中断处理程序例程,由 OS 在 boot-up 期间设置。当进入中断处理程序时,CPU 切换到 ring 0,特权模式。中断处理程序使内核创建新进程,然后将控制权转回调用进程(这意味着切换到保护环 3,无特权;进程只在环 3 中执行)。对于新进程的创建,内核创建相关的内部簿记结构,在MMU中建立新的页表,然后将控制权转移到clone
调用的入口点,类似于原来的方式呼叫 returns。 (我在这里掩盖了调度问题;一次只发生一次控制转移,其他 "scheduled" 稍后发生。)现在存在新进程的事实仅反映在内核的内部簿记数据。 CPU 对此一无所知;它所看到的只是触发中断和定期更改页表。