linux - 平面内存模型和 protected 内存模型之间的区别?

标签 linux memory memory-management model vxworks

扁平内存模型和 protected 内存模型的区别? VxWorks支持平面内存模型,Linux也支持平面内存模型吗?

最佳答案

为了给出一个有意义的答案,让我们先回顾一下一些概念。

大多数现代处理器都有一个内存管理单元 (MMU),用于多种用途。

一个目的是在虚拟地址(CPU“看到”的地址)和物理地址(芯片实际连接的地方)之间进行映射。这称为地址转换。

另一个目的是为某些虚拟内存位置设置访问属性(比如内存是可读写的,或只读的,或不可访问的)

使用 MMU,您可以拥有所谓的“统一映射”,其中处理器的虚拟地址与物理地址相同(即您不使用地址转换)。例如,如果处理器访问 0x10000,那么它正在访问物理位置​​ 0x10000。

“平面”内存模型通常是指 CPU 访问的任何虚拟地址都是唯一的。因此,对于 32 位 CPU,您最多只能使用 4G 地址空间。

它最常(但不一定)用于指代虚拟内存和物理内存之间的统一映射。

相比之下,在工作站领域,大多数操作系统 (Linux/Windows) 使用“重叠”内存模型。例如,您在 Windows 中启动的任何程序(进程)的起始地址都是 0x10000。

Windows 如何让 10 个进程都从地址 0x10000 运行?

这是因为每个进程都使用 MMU 将虚拟地址 0x10000 映射到不同的物理地址。 P1 可能有 0x10000 = 0x10000 而 P2 有 0x10000 = 0x40000,等等...

在 RAM 中,程序位于不同的物理地址,但 CPU 虚拟地址空间对于每个进程来说看起来是一样的。

据我所知,Windows 和标准 Linux 总是使用重叠模型(即它们没有平面模型)。 uLinux 或其他特殊内核可能具有平面模型。

现在,保护与平面模型与 protected 模型无关。 我会说大多数重叠模型操作系统将使用保护,以便一个进程不会影响另一个进程(即写入内存)。

随着 VxWorks 6.x 和实时进程的引入,即使使用平面内存模型,各个 RTP 也可以通过使用保护来相互保护(和内核应用程序)。

如果您不使用 RTP 并在 vxWorks 内核中运行所有内容,则不会使用任何保护措施。


那么,保护是如何工作的(无论是在 VxWorks RTP 还是其他操作系统进程中)? 本质上,RTP/进程存在于一个“内存气泡”中,具有一定范围的(虚拟)地址,其中包含代码、数据、堆和其他各种内存位置。

如果 RTP/进程试图访问其气泡外的内存位置,则 MMU 会生成异常并调用操作系统(或信号处理程序)。典型的结果是段违规/总线异常。

但是,如果一个进程无法逃脱它的内存泡沫,它怎么能将数据包发送到以太网端口呢?这因处理器架构而异,但本质上,用户端 (RTP) 套接字库(例如)进行“系统调用”——这是一种将 cpu 切换到内核空间和主管模式的特殊指令。此时,某种设备驱动程序(通常驻留在内核中)运行以将数据推送到某些硬件设备。完成后,系统调用返回,我们回到运行用户代码的 RTP/进程空间。

操作系统负责所有 MMU 编程、系统调用处理等...这对应用程序是不可见的。

关于linux - 平面内存模型和 protected 内存模型之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18417849/

相关文章:

memory - 在 Go 中处理包分配的最佳实践

ios - 内存使用量不断增加

swift - 如何从数组中释放所有引用元素?

linux - Bash 选项卡完成改变了行为

c - 使用 Valgrind 写入和读取错误

Java 文档和注释的 Java 内存管理

c++ - std::vector 如何复制其数据以进行重新分配?

python - SocketServer.ThreadingTCPServer - 程序重启后无法绑定(bind)到地址

linux - Docker 容器 - 在 Win 和 Linux 上的不同行为

java - CentOS 上还有其他 SelectorProvider(默认 EPollSelectorProvider)吗?