Skip to content

Latest commit

 

History

History
134 lines (78 loc) · 5.04 KB

chapter4.md

File metadata and controls

134 lines (78 loc) · 5.04 KB

引言

提高物理内存的使用效率->虚存。

  1. 动态内存分配
  2. 页表的虚实内存映射机制
    1. 简化编译器对地址空间的设置
    2. 加强应用之间和内核之间的内存隔离
    3. 空分复用

应用层面来看地址都是从0开始,也就是应用程序的linker.ld起始地址都是0x10000,而os通过页表加载到不同的物理地址中,程序员不用考虑访问地址。

动态内存分配

动态分配的内存区域就是heap,由os管理。

  • 初始化的时候提供一大块内存空间
  • 提供分配和释放的接口
  • 管理空闲块

静态分配

编译期间就知道变量的大小,分配了固定内存用来存储。

动态分配

应用有一个大小随着运行增减的heap空间

内存碎片

  • 内碎片:已经分配出去,没用满
  • 外碎片:没分,但是太小了分不出去

rust中的堆数据结构

指针

  • 裸指针 *const T/*mut T,和C的指针一样,本身的数值就是地址,不安全,编译器只能保证他不能修改只读的数据
  • 引用&T/&mut T,是一个地址范围,但是检查比较严格,也就是所有权模型
  • 智能指针,胖指针,除了地址范围,还有额外信息,能起到控制和管理作用

相关智能指针

  • Box <T> 创建时在堆上分配一个类型为T的变量,自身也保存在这个变量的位置,当他被回收的时候,变量的空间也就没了。
  • Rc <T> 是单线程用的引用技术类型,使多个指针指向同一变量,都可以拿到不可变引用,计数为0后都被回收。Arc是多线程用的。
  • RefCell <T> ,借用检查在运行时进行。实现内部可变性。
  • Mutex <T> 是一个互斥锁,在多线程中使用,内部可变性,同步互斥。

在内核中支持动态分配

用alloc库定义的接口来实现动态内存分配器。alloc需要os提供一个全局的动态内存分配器,这个分配器要实现规定的GlobalAlloc Trait,包括分配和回收两个接口,它将利用这个分配器管理堆空间,使得容器可用。

这里直接使用已有的分配器,进行全局静态实例化分配器,然后分配一段heap空间,用分配器管理这段空间。

os只是代为初始化这个heap空间为0,实际上它属于没有被初始化的全局数据。所以分配在.bss段中。

地址空间

硬件:内存保护/映射/地址转换

os:提供统一的虚存访问接口

CPU访问的是虚拟地址,通过MMU+页表进行地址转换,找到物理地址。

os中建立虚实地址空间映射机制。

地址空间设计目的

  • 开发者不用关系
  • 不要太大开销
  • 安全

虚拟地址需要MMU内存管理单元支持。

内核要提供支持,使得MMU对于不同应用、相同的虚拟地址映射到正确的物理地址。

实现方法大全:

分段管理

  • 一个app空间是bound,物理地址起始是base,内核负责切换base。内存块的占用状态用位表表示。
  • 产生内碎片,给stack、heap预留了空间,可能无法充分利用。
  • 为解决内碎片,就使用段来管理,段大小是不同的,则需要不同的base-bound配对每个段,一个任务就有多个base-bound。
  • 解决了内碎片问题,还有外碎片问题

分页管理

页面大小固定,一个app一个页表,对应虚拟页号和物理页号。

虚拟地址 = 虚拟页号 + 偏移

物理地址 = get value(虚拟页号) + 偏移

权限:rwx 限制了app对得到的物理地址的应用方式 读/写/取指令

SV39多级页表的硬件机制

rv64提供了SV39的多级页表硬件机制,先了解硬件,再完成软件对应的实现。

虚拟地址和物理地址

MMU没启动,访问的地址都是物理地址。satp这个CSR可以启动分页模型,如何S和U的访问地址都作为虚拟地址,去MMU转成物理地址。M级是物理地址。

satp的字段:

  • MODE 使用的页表实现方式
  • ASID 地址空间标识符
  • PPN 根页表所在的物理页号 (不同应用对应的页表的搜索入口,切换任务的时候也要切换这个,并且要刷新快表TLB)

当MODE 设置为 0 的时候,代表所有访存都被视为物理地址;而设置为 8 的时候,SV39 分页机制被启用,所有 S/U 特权级的访存被视为一个 39 位的虚拟地址,它们需要先经过 MMU 的地址转换流程,如果顺利的话,则会变成一个 56 位的物理地址来访问物理内存;否则则会触发异常,这体现了分页机制的内存保护能力

地址相关的数据结构抽象与类型定义

实际同时usize,通过封装。实现trait,进行相互生成和转换。

数据结构实现

[derive(Copy, Clone)]  //能让下面的结构体自动实现深拷贝

虚存地址:39 = 27 + 12

物理地址:56 = 44 +12

页表项: 64 = 10 + 44(ppn) + 2 + 8(pte标志)

多级页表

线性表的开销太大,使用字典树的思想,构造多级页表。SV39是三级页表实现的。

可用物理页管理

物理内存范围 0x80000000 - 0x80800000