6.S081笔记

Lec 01简单介绍

XV6(OS)运行在一个RISC-V微处理器上,我们用QEMU模拟RISC-V,从而在一个QEMU模拟器上运行XV6。

Lec 03

硬件对强隔离的支持

两种方式实现了隔离性:

  1. 内核态、用户态的切换(user/kernel mode)
  2. 虚拟内存

请添加图片描述
我们可以认为user/kernel mode是分隔用户空间和内核空间的边界,用户空间运行的程序运行在user mode,内核空间的程序运行在kernel mode。操作系统位于内核空间。

RISC-V中,用ECALL来让应用程序可以将控制权转移给内核(用户态转内核态)。具体来说:
  ECALL接收一个数字参数,当一个用户程序想要将程序执行的控制权转移到内核,它只需要执行ECALL指令,并传入一个数字。这里的数字参数代表了应用程序想要调用的System Call。

假设我现在要执行另一个系统调用write,write系统调用不能直接调用内核中的write代码,而是由封装好的系统调用函数执行ECALL指令。所以write函数实际上调用的是ECALL指令,指令的参数是代表了write系统调用的数字。之后控制权到了syscall函数,syscall会实际调用write系统调用。

宏内核与微内核

宏内核与微内核的区别:是否将整个OS代码都运行在内核态中,如果是的话就是宏内核。

宏内核代表:Linux
微内核代表:Windows

宏内核的特点:

  • 坏处:代码量越大,出现漏洞的概率就越大,就越不安全。一旦内核态出现BUG,就容易被攻击
  • 好处:因为这些子模块(文件系统、虚拟内存)现在都位于同一个程序中,它们可以紧密的集成在一起,这样的集成提供很好的性能

微内核的特点:

  • 好处:不用说,就是安全
  • 坏处:举个例子:比如说某个程序需要和文件系统交互,需要先通过内核IPC(进程间通信)先通知内核(内核态),内核再把信息转发给文件系统(用户态)。文件系统再将结果返回给内核(内核态),由内核态转发给程序(用户态)。很明显,微内核会导致在用户态和内核态反复跳转,性能很差

Lec 04 虚拟内存

虚拟内存:

  • 存在虚拟地址空间到物理地址空间的映射
  • 实现隔离性

1. 地址空间

为了防止不同程序之间不会互相影响(隔离性),我们应该给不同程序专属的地址空间。

所以,当我们运行cat时,它的地址空间从0到某个地址结束。当我们运行Shell时,它的地址也从0开始到某个地址结束。内核的地址空间也从0开始到某个地址结束。

在这里插入图片描述
如果cat程序想要向地址1000写入数据,那么cat只会向它自己的地址1000,而不是Shell的地址1000写入数据。所以,基本上来说,每个程序都运行在自己的地址空间,并且这些地址空间彼此之间相互独立。在这种不同地址空间的概念中,cat程序甚至都不具备引用属于Shell的内存地址的能力。这种方式为我们提供了强隔离性,cat现在不能引用任何不属于自己的内存。

虚拟内存地址可以大于物理内存。

在XV6中,kalloc.c保存了空余内存块:
kmem这个结构体将所有空闲的内存块串成一个链表来管理,每个节点都指向一个空闲内存块的开头地址。链表的头指针为freelist

1.1 页表

我们如何能够实现地址空间呢?或者说如何在一个物理内存上,创建不同的地址空间?使用页表。页表是在硬件中通过处理器和内存管理单元(Memory Management Unit)实现。

虚拟地址如何转换为物理地址?
  内存管理单元(MMU)会将虚拟地址翻译成物理地址。之后这个物理地址会被用来索引物理内存,并从物理内存加载,或者向物理内存存储数据。

为了能够完成虚拟内存地址到物理内存地址的翻译,MMU会有一个表单(页表),表单中,一边是虚拟内存地址,另一边是物理内存地址(以4KB为一个单位,页长)。举个例子,虚拟内存地址0x1000对应了一个我随口说的物理内存地址0xFFF0。这样的表单可以非常灵活。

通常来说,内存地址对应关系的表单(页表)也保存在内存中。所以CPU中需要有一些寄存器用来存放页表在物理内存中的地址。 现在,在内存的某个位置保存了地址关系表单,我们假设这个位置的物理内存地址是0x10。那么在RISC-V上一个叫做SATP的寄存器会保存地址0x10。

这样,CPU就可以告诉MMU,可以从哪找到将虚拟内存地址翻译成物理内存地址的表单。

所以,总结一下:MMU不保存页表,他只是从内存中读取页表,然后完成翻译

注意,每个进程都有自己的独立页表,并且这个页表定义了应用程序的地址空间。所以当操作系统将CPU从一个应用程序切换到另一个应用程序时,同时也需要切换SATP寄存器中的内容,从而指向新的进程保存在物理内存中的地址对应页表。

实际上,实际情况不可能是一个虚拟内存地址对应page table中的一个条目。接下来我将分两步介绍RISC-V中是如何工作的。:

第一步:不要为每个地址创建一条表单条目,而是为每一页创建一条表单条目,所以每一次地址翻译都是针对一个page。而RISC-V中,一个page是4KB(页长)。

第二步:现在,内存地址的翻译方式略微的不同了。首先对于虚拟内存地址,我们将它划分为两个部分,index和offset,index用来查找page,offset对应的是一个page中的哪个字节。
  
当MMU在做地址翻译的时候,通过读取虚拟内存地址中的index可以知道物理内存中的page号。之后虚拟内存地址中的offset指向了page中的4096个字节中的某一个,假设offset是12,那么page中的第12个字节被使用了。将offset加上page的起始地址,就可以得到物理内存地址。

有关RISC-V的一件有意思的事情是,虚拟内存地址都是64bit,这也说的通,因为RISC-V的寄存器是64bit的。但是实际上,在我们使用的RSIC-V处理器上,并不是所有的64bit都被使用了,也就是说高25bit并没有被使用。这样的结果是限制了虚拟内存地址的数量,虚拟内存地址的数量现在只有2^39个,大概是512GB。

在剩下的39bit中,有27bit被用来当做index12bit被用来当做offset。offset必须是12bit,因为对应了一个page的4096个字节

一个目录项(PTE)的大小为64比特(位)(因为OS为64位),也就是8个字节。所以一个4k页的页表正好对应512个PTE。采用多级页表结构的最重要的原因就是节约因为存储页表而耗费的内存页。

2. 支持虚拟内存的硬件

3. 代码展示虚拟内存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值