当页表条目(PTE)没有被标记为有效时,这意味着所需的数据不在内存中,而是在磁盘上。所以现在页面错误发生了,操作系统负责将这一页数据从磁盘加载到内存中。
我的问题是,操作系统如何知道确切的磁盘地址?
当页表条目(PTE)没有被标记为有效时,这意味着所需的数据不在内存中,而是在磁盘上。所以现在页面错误发生了,操作系统负责将这一页数据从磁盘加载到内存中。
我的问题是,操作系统如何知道确切的磁盘地址?
您以系统相关的方式询问。未标记为有效的 PTE 可能意味着该地址根本不存在于进程地址中。系统可能有另一个位来指示地址有效但不存在逻辑到物理映射。
操作系统需要维护一个表格,其中包含数据放置位置。
数据可以存在于许多地方。1.它可能是未初始化的数据,在任何地方都没有映射。通过清除物理页面并将其映射到进程地址空间来响应页面错误。
它可能在页面文件中。
有些系统有一个单独的交换文件。
它可能在可执行文件或共享库文件中。
2014年给出的答案是正确的。处理器所知道的只是页面丢失了——或者有时它有不正确的权限(例如,写入只读页面)。此时,处理器会生成一个“页面错误”异常,内核得到并且现在必须处理该异常。
在某些情况下,这个页面错误需要一直传递给应用程序,在 Linux 中作为 SIGSEGV(“分段违规”)信号,例如,当用户使用空指针时。但是,正如您所说,更常见的是,内核应该并且可以处理页面错误。内核在它自己的表中(不在页表中,页表是一个由处理器指定的具有特定格式的结构)关于每个虚拟内存页应该包含什么的信息。以下是内核通过查阅其自己的表可能了解的关于错误页面的一些事情。这不是一个详尽的清单。
这可能是来自磁盘的页面 mmap()。这种情况包括应用程序对 mmap() 的显式使用,但也会在您运行可执行文件或使用共享库时发生 - 这些也是从磁盘映射的 - 因此页面错误也可能在处理器执行指令时发生,而不仅仅是在读取时和写作。内核保留了这些映射的列表,因此当它遇到页面错误时,它可以确定它需要读取磁盘上的哪个位置以获取丢失的页面。因此,它从磁盘读取数据,当获取数据时,它会将数据放入内存中的新页面,并设置页表条目 (PTE) 以指向带有数据的新页面,并恢复应用程序线程 - 错误指令所在的位置已重试,现在成功。
这可能是一个换出到磁盘的页面。同样,内核保留一张表,其中包含哪些页面被换出,以及该页面现在位于交换分区(或交换文件或其他任何内容)中的什么位置。
这可能是对“写时复制”页面的写尝试。内核需要对源页进行拷贝,并改变页表中的地址指向新的拷贝,然后允许写入。例如,当您分配一大块内存时,它可以指向现有的“零填充”页面,并且仅在您第一次写入页面时才分配。在 fork() 之后的另一个示例,新进程的页面都是指向原始进程页面的写时复制页面,并且只有在第一次写入时才会被实际复制(由任一进程)。
但是,由于您正在寻找可靠的来源,也许您想阅读 Linux 内核具体如何执行此操作的说明,例如: https ://vistech.net/~champ/online-docs/books/linuxkernel2/ 060.htm。
它与虚拟内存寻址相同。
程序中出现的地址是虚拟地址或程序地址。对于每次内存访问,无论是获取指令还是数据,CPU 都必须将虚拟地址转换为真实的物理地址。可以认为虚拟内存地址由两部分组成:页号和页内的偏移量。页码确定哪一页包含信息,偏移量指定页内的哪个字节。偏移量字段的大小是页面大小的日志基数 2。
如果虚拟地址有效,则系统检查页框是否空闲。如果没有空闲帧,则运行页面替换算法以删除页面。