Skip to content

Commit

Permalink
内存管理
Browse files Browse the repository at this point in the history
  • Loading branch information
copi143 committed Aug 4, 2024
1 parent 8f9ca23 commit c3add04
Show file tree
Hide file tree
Showing 2 changed files with 227 additions and 0 deletions.
148 changes: 148 additions & 0 deletions mm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# mm

Plant OS内存管理的实现

## Warnings

## Using

## Testing

## TODO

虚拟内存

## Principle

### 基本原理

在32位模式下,线性地址的组成分为三个部分

```[graph]
digraph G {
"dir" [
label = "<f0>Directory | <f1>Table | <f2>Offset"
shape = record
]
"cr3" [
label = "cr3"
shape = record
]
"first+" [
label = "+"
]
"second+" [
label = "+"
]
"third+" [
label = "+"
]
subgraph _ {
"页目录" [
label = "页目录||<f0>|"
shape = record
]
"页表" [
label = "页表||<f0>|"
shape = record
]
"页" [
label = "页||<f0>|"
shape = record
]
rank = same
}
"cr3" -> "first+"
"dir":f0 -> "first+"
"first+" -> "页目录":f0
"页目录":f0 -> "second+"
"dir":f1 -> "second+"
"second+" -> "页表":f0
"页表":f0 -> "third+"
"dir":f2 -> "third+"
"third+" -> "页":f0
}
```

依据此原理,我们可以维护页目录和页表来设置线性地址与物理地址的对应关系

通过设置页目录和页表的属性,例如,关闭某个页的写属性,那么在ring3下访问这个页,就会报PF(Page Fault),那么我们就可以处理这个PF,重新设置这个页的属性,这也是COW(Copy on write,写时复制)的原理。

### pde_clone

以下是代码:

```c
u32 pde_clone(u32 addr) {
for (int i = DIDX(0x70000000) * 4; i < 0x1000; i += 4) {
u32 *pde_entry = (u32 *)(addr + i);
u32 p = *pde_entry & (0xfffff000);
pages[IDX(*pde_entry)].count++;
*pde_entry &= ~PAGE_WRABLE;
for (int j = 0; j < 0x1000; j += 4) {
u32 *pte_entry = (u32 *)(p + j);
if ((page_get_attr(get_line_address(i / 4, j / 4, 0)) & PAGE_USER)) {
pages[IDX(*pte_entry)].count++;
if (page_get_attr(get_line_address(i / 4, j / 4, 0)) & PAGE_SHARED) {
*pte_entry |= PAGE_WRABLE;
continue;
}
}
*pte_entry &= ~PAGE_WRABLE;
}
}
u32 result = (u32)page_malloc_one_no_mark();
memcpy((void *)result, (void *)addr, 0x1000);
flush_tlb(result);
flush_tlb(addr);
asm_set_cr3(addr);

return result;
}
```
```c
for (int i = DIDX(0x70000000) * 4; i < 0x1000; i += 4)
```

遍历 **0x70000000 到 末尾的** 所对应的 **页目录**:这里不使用"i < DIDX(0xf0000000)"(0xf0000000是用户地址结束的地方),是因为,本来这后面也不应该被使用,所以我们这里就干脆全部设置了,省事,也防止一些bug,比如哪里做完某些操作之后,忘记将某些敏感地址写回不可写后,给恶意程序有可乘之机。

```c
u32 *pde_entry = (u32 *)(addr + i);
u32 p = *pde_entry & (0xfffff000);
pages[IDX(*pde_entry)].count++;
*pde_entry &= ~PAGE_WRABLE;
```

`pde_entry`: pde中表项的地址
`p` : pde表项低十二位是属性位,前面就是物理页的索引,因而将第十二位置0,之后来读取其存储的pte地址
`pages[IDX(*pde_entry)].count++``*pde_entry &= ~PAGE_WRABLE`:毕竟是克隆一份pde,所以相应的这里也要增加一份引用,然后我们将这个地方设置成不可写(为了实现写时复制这一特性)

```c
for (int j = 0; j < 0x1000; j += 4)
```

遍历PTE的表项

```c
u32 *pte_entry = (u32 *)(p + j);
if ((page_get_attr(get_line_address(i / 4, j / 4, 0)) & PAGE_USER)) {
pages[IDX(*pte_entry)].count++;
if (page_get_attr(get_line_address(i / 4, j / 4, 0)) & PAGE_SHARED) {
*pte_entry |= PAGE_WRABLE;
continue;
}
}
*pte_entry &= ~PAGE_WRABLE;
```
`pte_entry` :PTE表项的地址
我们先获取到这个pte表项所对应页框(物理)的属性,如果用户可访问,其引用自增<br>
## Dependencies
mem.c -- malloc free realloc( 依赖于 `libc/alloc`) kmalloc kree krealloc(依赖于`page.c`)的实现
## Contribute
79 changes: 79 additions & 0 deletions 进程间内存关系图.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<mxfile host="65bd71144e">
<diagram id="-FQKTz0l85yIBoSj2X8f" name="第 1 页">
<mxGraphModel dx="765" dy="525" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="5" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="3">
<mxGeometry relative="1" as="geometry">
<mxPoint x="210" y="210" as="targetPoint"/>
<Array as="points"/>
</mxGeometry>
</mxCell>
<mxCell id="6" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="3">
<mxGeometry relative="1" as="geometry">
<mxPoint x="440" y="200" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="3" value="0x400000 (最开始我们配置的页表)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="150" y="90" width="360" height="30" as="geometry"/>
</mxCell>
<mxCell id="9" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="7" target="10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="496" y="300" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="7" value="init(r0阶段)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="411" y="211" width="169" height="30" as="geometry"/>
</mxCell>
<mxCell id="8" value="idle" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="170" y="211" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="20" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fontSize=12;fontColor=#FFFFFF;" edge="1" parent="1" source="10" target="21">
<mxGeometry relative="1" as="geometry">
<mxPoint x="496" y="390" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="10" value="init.bin" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="466" y="285" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="11" value="pde_clone() &amp;amp; os_execute 加载程序" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="500" y="241" width="220" height="30" as="geometry"/>
</mxCell>
<mxCell id="12" value="&lt;font style=&quot;font-size: 18px;&quot; color=&quot;#ff0808&quot;&gt;需要注意的是:0x400000的页表已经设置全部内存不可被用户访问&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="60" y="20" width="560" height="50" as="geometry"/>
</mxCell>
<mxCell id="23" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fontSize=12;fontColor=#FFFFFF;" edge="1" parent="1" source="21" target="24">
<mxGeometry relative="1" as="geometry">
<mxPoint x="496" y="470" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="21" value="Something" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontColor=#FFFFFF;" vertex="1" parent="1">
<mxGeometry x="466" y="375" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="26" style="edgeStyle=none;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;fontSize=12;fontColor=#FFFFFF;" edge="1" parent="1" source="24">
<mxGeometry relative="1" as="geometry">
<mxPoint x="410" y="540" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="27" style="edgeStyle=none;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;fontSize=12;fontColor=#FFFFFF;" edge="1" parent="1" source="24">
<mxGeometry relative="1" as="geometry">
<mxPoint x="590" y="540" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="24" value="APP" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontColor=#FFFFFF;" vertex="1" parent="1">
<mxGeometry x="465.5" y="470" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="29" value="&lt;font style=&quot;font-size: 10px;&quot;&gt;应用程序可能创建多个线程&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontColor=#FFFFFF;" vertex="1" parent="1">
<mxGeometry x="465.5" y="510" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="30" value="&lt;span style=&quot;font-size: 12px;&quot;&gt;....&lt;/span&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontColor=#FFFFFF;" vertex="1" parent="1">
<mxGeometry x="370" y="540" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="31" value="&lt;span style=&quot;font-size: 12px;&quot;&gt;....&lt;/span&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontColor=#FFFFFF;" vertex="1" parent="1">
<mxGeometry x="560" y="540" width="60" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

0 comments on commit c3add04

Please sign in to comment.