task4 finished
This commit is contained in:
153
answers-pgtbl.txt
Normal file
153
answers-pgtbl.txt
Normal file
@ -0,0 +1,153 @@
|
||||
### 背景信息
|
||||
- **页面表结构**:
|
||||
- 页面大小(`PGSIZE`):通常为 4KB(4096 字节)。
|
||||
- 最大虚拟地址(`MAXVA`):在 Sv39 模式下为 2^39(512GB)。
|
||||
- 页面表条目(PTE):包含物理地址(PA)、权限位(读/写/执行等)以及有效位(Valid bit)。
|
||||
- 三级页面表:PML4(顶级),L2(中间级),L1(最低级),每个页面表包含 512 条目(2^9)。
|
||||
- 虚拟地址(VA):39 位,分为 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 的条目,以及其下级页面表的最后几个条目(509–511)。
|
||||
- 对应虚拟地址接近 `MAXVA`(`0x3fffffd` 到 `0x3ffffff`)。
|
||||
- 输出格式:
|
||||
- 每行表示一个页面表条目,格式为:
|
||||
```
|
||||
[索引]: pte [PTE值] pa [物理地址] [va 虚拟地址 flags 权限]
|
||||
```
|
||||
- 缩进(`..`)表示页面表层级:顶级(无缩进)、L2(`..`)、L1(`.. ..`)。
|
||||
- 仅 L1 页面表条目包含虚拟地址(`va`)和权限标志(`flags`)。
|
||||
|
||||
#### 2. **页面表条目解析**
|
||||
页面表条目(PTE)格式(RISC-V Sv39):
|
||||
- **PTE 结构**:64 位,包含:
|
||||
- 物理页面号(PPN):44 位(高 44 位,右移 10 位得到物理页面地址)。
|
||||
- 权限位:V(Valid,有效)、R(Read,读)、W(Write,写)、X(Execute,执行)、U(User,用户态可访问)。
|
||||
- 其他标志:G(Global)、A(Accessed)、D(Dirty)等。
|
||||
- **物理地址(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`,表示 Valid(V=1)。
|
||||
- **L2 页面表(索引 0)**:
|
||||
- `..0: pte 0x0000000021fd2001 pa 0x0000000087f48000`
|
||||
- PTE 值:`0x21fd2001`。
|
||||
- 物理地址:`0x87f48000`(L1 页面表地址)。
|
||||
- 标志:Valid(V=1)。
|
||||
- **L1 页面表(索引 0–3)**:
|
||||
- `.. ..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 页面表地址)。
|
||||
- 标志:Valid(V=1)。
|
||||
- **L2 页面表(索引 511)**:
|
||||
- `..511: pte 0x0000000021fd2c01 pa 0x0000000087f4b000`
|
||||
- PTE 值:`0x21fd2c01`。
|
||||
- 物理地址:`0x87f4b000`(L1 页面表地址)。
|
||||
- 标志:Valid(V=1)。
|
||||
- **L1 页面表(索引 509–511)**:
|
||||
- `.. ..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 个页面**:
|
||||
- 输出显示索引 509–511(虚拟地址 `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 个页面(509–511),可能是因为只有这些页面有有效映射。
|
||||
- **缺失的 `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`,可能是设备寄存器或内核代码的固定映射。
|
||||
|
||||
|
||||
@ -126,38 +126,40 @@ sys_uptime(void)
|
||||
|
||||
uint64
|
||||
sys_pgaccess(void)
|
||||
{
|
||||
uint64 va;
|
||||
int n;
|
||||
uint64 user_mask_addr;
|
||||
argaddr(0, &va);
|
||||
argint(1, &n);
|
||||
argaddr(2, &user_mask_addr);
|
||||
if (va < 0 || n < 0 || user_mask_addr < 0)
|
||||
return -1;
|
||||
|
||||
if (n < 0 || n > 32)
|
||||
return -1;
|
||||
|
||||
{
|
||||
// lab pgtbl: your code here.
|
||||
struct proc *p = myproc();
|
||||
uint64 mask = 0;
|
||||
unsigned int abits=0;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint64 v = va + i * PGSIZE;
|
||||
pte_t *pte = walk(p->pagetable, v, 0);
|
||||
uint64 addr;
|
||||
argaddr(0, &addr);
|
||||
|
||||
if (!pte || (*pte & PTE_PS))
|
||||
continue;
|
||||
int num;
|
||||
argint(1,&num);
|
||||
|
||||
if ((*pte & PTE_V) && (*pte & PTE_A)) {
|
||||
mask |= (1 << i); // Set bit i in mask
|
||||
*pte &= ~PTE_A; // Clear the Accessed bit
|
||||
uint64 dest;
|
||||
argaddr(2, &dest);
|
||||
|
||||
|
||||
for(int i=0;i<num;i++){
|
||||
uint64 query_addr = addr + i * PGSIZE ;
|
||||
|
||||
|
||||
pte_t * pte=walk(p->pagetable, query_addr, 0);
|
||||
if(*pte&PTE_A)
|
||||
{
|
||||
abits=abits|(1<<i);
|
||||
*pte=(*pte)&(~PTE_A);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (copyout(p->pagetable, user_mask_addr, (char*)&mask, sizeof(mask)) < 0)
|
||||
|
||||
|
||||
if(copyout(p->pagetable,dest,(char*)&abits, sizeof(abits)) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user