operating-system - 这个页面目录有效吗?
问题描述
我不确定我对分页的理解。我想通过创建一个假设的页面目录来检查,并要求社区在此过程中指出我的错误。
让我们假设内核代码适合第一帧 - 0x0000 到 0x1000,并且页面目录将放置在 0x10000。这将是一个身份图。
所以首先,我去看了intel 80386手册,找到了这个插图
╔══════════════════════════════════════╤═══════╤══ ═╤═╤═╤═══╤═╤═╤═╗ ║ │ │ │ │ │U│R│ ║ ║ 页帧地址 31..12 │ AVAIL │0 0│D│A│0 0│/│/│P║ ║ │ │ │ │ │ │S│W│ ║ ╚══════════════════════════════════════╧═══════╧══ ═╧═╧═╧═══╧═╧═╧═╝
页面目录将只有一个条目(当前位不会设置在其他条目上)。这里是:
11000000 00001000 10000000 00000000
所以这意味着它存在,并且相应的页表位于00000000 0000001 0001
,右移 12 位。这评估为0x11000
。(这是我的目标,但它真的是这个意思吗?)。现在我明白了现在的意思,但是在这种情况下读/写是什么意思?它不是指框架,所以...
对于位于0x11000
: 的页表,除了地址之外,一切都几乎相同。
11000000 0000000 00000000 00000000
11000000 0000100 00000000 00000000
etc
11000000 0000100 01000000 00000000
这就是内核的完整页表目录。它是否正确?过程中是否有任何错误?读/写位作为页面目录条目意味着什么?
解决方案
请参阅 Intel 的系统编程指南中的表 4-5 以及第 4-6 节。在页目录项中,R/W 位控制相应页表中所有页的可写性,即虚拟内存的整个 4MB 区域。因此,如果您清除该位,则该区域中的所有页面都是只读的,无论它们各自的 R/W 位可能设置为什么。如果您设置该位,则 CPU 会参考页面本身的 R/W 位来决定是否允许写入。
换句话说,一个页面的有效读写状态是您步行到达它的所有分页结构中的 R/W 位的逻辑与。如果您正在尝试写入,并且 CPU 在其页表遍历的任何阶段遇到清除的 R/W 位,它可以通过页面错误提前退出。当有更多级别时,此原则在 64 位模式中继续成立。
如果您需要将较大的内存区域设置为只读,这可能会很方便;您可以只清除页面目录条目中的 R/W 位,而无需遍历表中的所有页面。一个常见的例子是调用fork()
;的 Unix 进程。它的所有可写内存都需要变为只读,以便它可以在写时复制。
推荐阅读
- javascript - 嵌套动态表单 Antd
- c++ - 无法在 Windows 上使用 mingw 将 sqlite3 与 c 连接
- spring-webclient - io.netty.channel.unix.Errors$NativeEceptionIoException: readAddress failed: Connection reset by peer 请求将被重试
- docker - 将 Docker 镜像推送到 Container Registry
- c - 使用套接字在客户端/服务器之间传输数据
- r - 数据框长到宽格式
- scala - 如何在 scala 中处理 CSV 文件,以便将其行分隔成数组?
- spring-boot - 在 SpringSecurity 中删除用户时获取 null SecurityContextHolder.getContext()
- r - 每行中具有最大数量的标志行
- java - 并行运行任务,收到一定结果后取消线程