Files
xv6-labs/answers-pgtbl.txt
2025-05-29 11:15:51 +08:00

154 lines
9.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### 背景信息
- **页面表结构**
- 页面大小(`PGSIZE`):通常为 4KB4096 字节)。
- 最大虚拟地址(`MAXVA`):在 Sv39 模式下为 2^39512GB
- 页面表条目PTE包含物理地址PA、权限位读/写/执行等以及有效位Valid bit
- 三级页面表PML4顶级L2中间级L1最低级每个页面表包含 512 条目2^9
- 虚拟地址VA39 位,分为 VPN[2]9 位顶级索引、VPN[1]9 位中间级索引、VPN[0]9 位,最低级索引)和 12 位页面偏移。
- **`print_pgtbl` 函数**
- 打印前 10 个页面VA 从 `0` 到 `9 * PGSIZE`)和最后 10 个页面(接近 `MAXVA`)的页面表条目。
- 调用 `print_pte`,输出虚拟地址对应的页面表条目信息。
### 输出分析
以下是提供的输出:
```
xv6 kernel is booting
hart 1 starting
hart 2 starting
page table 0x0000000087f4d000
0: pte 0x0000000021fd2401 pa 0x0000000087f49000
..0: pte 0x0000000021fd2001 pa 0x0000000087f48000
.. ..0: pte 0x0000000021fd281b pa 0x0000000087f4a000 va 0x0000000000000000 flags RXU
.. ..1: pte 0x0000000021fd1c17 pa 0x0000000087f47000 va 0x0000000000000001 flags RWU
.. ..2: pte 0x0000000021fd1807 pa 0x0000000087f46000 va 0x0000000000000002 flags RW
.. ..3: pte 0x0000000021fd1417 pa 0x0000000087f45000 va 0x0000000000000003 flags RWU
255: pte 0x0000000021fd3001 pa 0x0000000087f4c000
..511: pte 0x0000000021fd2c01 pa 0x0000000087f4b000
.. ..509: pte 0x0000000021fd5413 pa 0x0000000087f55000 va 0x0000000003fffffd flags RU
.. ..510: pte 0x0000000021fd5807 pa 0x0000000087f56000 va 0x0000000003fffffe flags RW
.. ..511: pte 0x000000002000180b pa 0x0000000080006000 va 0x0000000003ffffff flags RX
init: starting sh
```
#### 1. **输出结构与 `print_pgtbl` 的关联**
- 输出由 `print_pgtbl` 函数生成,包含:
- **顶级页面表地址**`page table 0x0000000087f4d000`(根页面表所在的物理地址)。
- **前几个页面表条目**(对应 `for (uint64 i = 0; i < 10; i++)` 循环):
- 打印顶级页面表索引 0 的条目,以及其下级页面表的条目。
- 具体为虚拟地址 `0x0` 到 `0x3000`(前 4 个页面)。
- **最后几个页面表条目**(对应 `for (uint64 i = top - 10; i < top; i++)` 循环):
- 打印顶级页面表索引 255 的条目以及其下级页面表的最后几个条目509511
- 对应虚拟地址接近 `MAXVA``0x3fffffd` 到 `0x3ffffff`)。
- 输出格式:
- 每行表示一个页面表条目,格式为:
```
[索引]: pte [PTE值] pa [物理地址] [va 虚拟地址 flags 权限]
```
- 缩进(`..`表示页面表层级顶级无缩进、L2`..`、L1`.. ..`)。
- 仅 L1 页面表条目包含虚拟地址(`va`)和权限标志(`flags`)。
#### 2. **页面表条目解析**
页面表条目PTE格式RISC-V Sv39
- **PTE 结构**64 位,包含:
- 物理页面号PPN44 位(高 44 位,右移 10 位得到物理页面地址)。
- 权限位VValid有效、RRead、WWrite、XExecute执行、UUser用户态可访问
- 其他标志GGlobal、AAccessed、DDirty等。
- **物理地址PA**:从 PTE 的 PPN 字段计算,`PA = PPN << 12`。
- **权限标志flags**:输出中的 `RXU`、`RWU`、`RW` 等表示权限组合:
- `R`:可读,`W`:可写,`X`:可执行,`U`:用户态可访问。
##### **前 4 个页面VA 0x0 到 0x3000**
- **顶级页面表(索引 0**
- `0: pte 0x0000000021fd2401 pa 0x0000000087f49000`
- PTE 值:`0x21fd2401`。
- 物理地址:`0x87f49000`L2 页面表地址)。
- 标志:`0x401` 的低 10 位为 `0x001`,表示 ValidV=1
- **L2 页面表(索引 0**
- `..0: pte 0x0000000021fd2001 pa 0x0000000087f48000`
- PTE 值:`0x21fd2001`。
- 物理地址:`0x87f48000`L1 页面表地址)。
- 标志ValidV=1
- **L1 页面表(索引 03**
- `.. ..0: pte 0x0000000021fd281b pa 0x0000000087f4a000 va 0x0000000000000000 flags RXU`
- 虚拟地址:`0x0`。
- 物理地址:`0x87f4a000`。
- 标志:`RXU`Read, Execute, User`0x1b` = `0b11011`V=1, R=1, X=1, U=1
- 用途:可能是内核代码段(可读、可执行、用户态可访问)。
- `.. ..1: pte 0x0000000021fd1c17 pa 0x0000000087f47000 va 0x0000000000000001 flags RWU`
- 虚拟地址:`0x1000`1 * PGSIZE
- 物理地址:`0x87f47000`。
- 标志:`RWU`Read, Write, User`0x17` = `0b10111`V=1, R=1, W=1, U=1
- 用途:可能是数据段或堆栈(可读、可写、用户态可访问)。
- `.. ..2: pte 0x0000000021fd1807 pa 0x0000000087f46000 va 0x0000000000000002 flags RW`
- 虚拟地址:`0x2000`2 * PGSIZE
- 物理地址:`0x87f46000`。
- 标志:`RW`Read, Write`0x07` = `0b00111`V=1, R=1, W=1
- 用途:可能是内核数据(可读、可写,仅内核态)。
- `.. ..3: pte 0x0000000021fd1417 pa 0x0000000087f45000 va 0x0000000000000003 flags RWU`
- 虚拟地址:`0x3000`3 * PGSIZE
- 物理地址:`0x87f45000`。
- 标志:`RWU`Read, Write, User`0x17` = `0b10111`V=1, R=1, W=1, U=1
- 用途:可能是用户态数据或堆栈。
##### **最后 3 个页面VA 0x3fffffd 到 0x3ffffff**
- **顶级页面表(索引 255**
- `255: pte 0x0000000021fd3001 pa 0x0000000087f4c000`
- PTE 值:`0x21fd3001`。
- 物理地址:`0x87f4c000`L2 页面表地址)。
- 标志ValidV=1
- **L2 页面表(索引 511**
- `..511: pte 0x0000000021fd2c01 pa 0x0000000087f4b000`
- PTE 值:`0x21fd2c01`。
- 物理地址:`0x87f4b000`L1 页面表地址)。
- 标志ValidV=1
- **L1 页面表(索引 509511**
- `.. ..509: pte 0x0000000021fd5413 pa 0x0000000087f55000 va 0x0000000003fffffd flags RU`
- 虚拟地址:`0x3fffffd000`(接近 MAXVA
- 物理地址:`0x87f55000`。
- 标志:`RU`Read, User`0x13` = `0b10011`V=1, R=1, U=1
- 用途:可能是用户态只读数据。
- `.. ..510: pte 0x0000000021fd5807 pa 0x0000000087f56000 va 0x0000000003fffffe flags RW`
- 虚拟地址:`0x3fffffe000`。
- 物理地址:`0x87f56000`。
- 标志:`RW`Read, Write`0x07` = `0b00111`V=1, R=1, W=1
- 用途:可能是内核数据(仅内核态)。
- `.. ..511: pte 0x000000002000180b pa 0x0000000080006000 va 0x0000000003ffffff flags RX`
- 虚拟地址:`0x3ffffff000`MAXVA - PGSIZE
- 物理地址:`0x80006000`。
- 标志:`RX`Read, Execute`0x0b` = `0b01011`V=1, R=1, X=1
- 用途:可能是内核代码或设备映射(可读、可执行,仅内核态)。
#### 3. **与 `print_pgtbl` 的关联**
- **前 10 个页面**
- 输出只显示了虚拟地址 `0x0` 到 `0x3000`4 个页面),而不是 10 个,可能是因为 `print_pgtbl` 的循环被修改或页面表中只有前 4 个页面有有效映射。
- 虚拟地址计算:
- `i * PGSIZE``i` 从 0 到 3与输出中的 `va 0x0`、`0x1000`、`0x2000`、`0x3000` 匹配。
- **最后 10 个页面**
- 输出显示索引 509511虚拟地址 `0x3fffffd000` 到 `0x3ffffff000`),对应 `i` 从 `top - 3` 到 `top - 1`。
- 计算 `top`
- `MAXVA = 2^39 = 512GB``PGSIZE = 4096``top = 512GB / 4096 = 2^27 = 134,217,728`。
- 虚拟地址 `0x3ffffff`(十进制 2^30 - 1对应页面号 `2^30 / 4096 = 2^18 - 1 = 262,143`。
- 顶级索引:`262,143 >> 18 = 255`(匹配 `255:`)。
- L2 索引:`(262,143 >> 9) & 0x1FF = 511`(匹配 `..511:`)。
- L1 索引:`262,143 & 0x1FF = 511`(匹配 `.. ..511:`)。
- 输出只显示最后 3 个页面509511可能是因为只有这些页面有有效映射。
- **缺失的 `print_pgtbl` 输出**
- 函数应打印 `"print_pgtbl starting\n"` 和 `"print_pgtbl: OK\n"`,但输出中缺失,可能是被其他日志覆盖或函数被修改。
#### 4. **页面表条目含义**
- **前 4 个页面**
- 映射到物理地址 `0x87f4a000` 到 `0x87f45000`,连续的物理页面。
- 权限多样(`RXU`、`RWU`、`RW`),表明这些页面用于不同用途:
- `RXU`:用户态代码(例如,初始用户程序)。
- `RWU`:用户态数据或堆栈。
- `RW`:内核数据(仅内核态)。
- **最后 3 个页面**
- 映射到物理地址 `0x87f55000` 到 `0x80006000`,不完全连续。
- 权限包括 `RU`(用户态只读)、`RW`(内核读写)、`RX`(内核代码)。
- 最后一个页面(`va 0x3ffffff000`, `pa 0x80006000`)可能是设备内存映射(常见于内核高地址空间)。
- **物理地址**
- 大部分物理地址在 `0x87fxxxxx` 范围内,表明内存分配集中在某一区域。
- 最后一个页面映射到 `0x80006000`,可能是设备寄存器或内核代码的固定映射。