ucore lab3 虚拟内存管理

ucore lab3 虚拟内存管理

首先查看有关该lab的数据结构

vma: 描述了一块连续的虚拟内存空间,保证start<=end,list_link是一个双向链表,按照从小到大的顺序把一系列用vma_struct表示的虚拟内存空间链接起来,并且还要求这些链起来的vma_struct应该是不相交的,即vma之间的地址空间无交集。

struct vma_struct {struct mm_struct *vm_mm; // the set of vma using the same PDT uintptr_t vm_start;      // start addr of vma      uintptr_t vm_end;        // end addr of vma, not include the vm_end itselfuint32_t vm_flags;       // flags of vmalist_entry_t list_link;  // linear list link which sorted by start addr of vma
};

mm_struct:管理使用同一PDT的vma集合的结构体

struct mm_struct {  list_entry_t mmap_list;  //双向链表头,链接了所有属于同一页目录表的虚拟内存空间struct vma_struct *mmap_cache;  //指向当前正在使用的虚拟内存空间pde_t *pgdir; //指向的就是 mm_struct数据结构所维护的页表int map_count; //记录mmap_list里面链接的vma_struct的个数void *sm_priv; //指向用来链接记录页访问情况的链表头};  

mmap_list是双向链表头,链接了所有属于同一页目录表的虚拟内存空间,mmap_cache是指向当前正在使用的虚拟内存空间,由于操作系统执行的“局部性”原理,当前正在用到的虚拟内存空间在接下来的操作中可能还会用到,这时就不需要查链表,而是直接使用此指针就可找到下一次要用到的虚拟内存空间。pgdir 所指向的就是 mm_struct数据结构所维护的页表。通过访问pgdir可以查找某虚拟地址对应的页表项是否存在以及页表项的属性等。map_count记录mmap_list 里面链接的 vma_struct的个数。sm_priv指向用来链接记录页访问情况的链表头,这建立了mm_struct和后续要讲到的swap_manager之间的联系。

练习1:给未被映射的地址映射上物理页(需要编程)

当启动分页机制以后,如果一条指令或数据的虚拟地址所对应的物理页框不在内存中或者访问的类型有错误(比如写一个只读页或用户态程序访问内核态的数据等),就会发生页访问异常。产生页访问异常的原因主要有:目标页帧不存在(页表项全为0,即该线性地址与物理地址尚未建立映射或者已经撤销);
相应的物理页帧不在内存中(页表项非空,但Present标志位=0,比如在swap分区或磁盘文件上),这在本次实验中会出现,我们将在下面介绍换页机制实现时进一步讲解如何处理;
不满足访问权限(此时页表项P标志=1,但低权限的程序试图访问高权限的地址空间,或者有程序试图写只读页面).
当出现上面情况之一,那么就会产生页面page fault(#PF)异常。
CPU会把产生异常的线性地址存储在CR2中,并且把表示页访问异常类型的值(简称页访问异常错误码,errorCode)保存在中断栈中。

do_pgfault()函数从CR2寄存器中获取页错误异常的虚拟地址,根据error code来查找这个虚拟地址是否在某一个VMA的地址范围内,并且具有正确的权限。如果满足上述两个要求,则需要为分配一个物理页。
所以出现page fault后,会有一个中断状态指针tf,传到trap()中处理:

void
trap(struct trapframe *tf) {// dispatch based on what type of trap occurredtrap_dispatch(tf);
}

调用trap_dispatch():

static void
trap_dispatch(struct trapframe *tf) {char c;int ret;
switch (tf->tf_trapno) {
case T_PGFLT:  //page fault页访问错误if ((ret = pgfault_handler(tf)) != 0) {print_trapframe(tf);panic("handle pgfault failed. %e\n", ret);}break;

因为此时应该是page fault,所以调用pgfault_handler():

static int
pgfault_handler(struct trapframe *tf) {extern struct mm_struct *check_mm_struct;print_pgfault(tf);if (check_mm_struct != NULL) {return do_pgfault(check_mm_struct, tf->tf_err, rcr2());}//CR2存储了产生异常的线性地址panic("unhandled page fault.\n");
}

然后调用了do_pgfault()

给未被映射的地址映射上物理页。设置访问权限 的时候需要参考页面所在 VMA 的权限,同时需要注意映射物理页时需要操作内存控制 结构所指定的页表,而不是内核的页表。

    ptep = get_pte(mm->pgdir , addr , 1);  //(1) try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT.if(ptep == NULL){cprintf("get_pte in do_pgfault failed\n");goto failed;}if (*ptep == 0) {                      //(2) if the phy addr isn't exist, then alloc a page & map the phy addr with logical addrif(pgdir_alloc_page(mm->pgdir , addr , perm) == NULL){cprintf("pgdir_alloc_page in do_pgfault failed\n");goto failed;}              }
  • 请描述页目录项(Page Directory Entry)和页表项(Page Table Entry)中组成部分对ucore实现页替换算法的潜在用处。

  • 如果ucore的缺页服务例程在执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?

练习2:补充完成基于FIFO的页面替换算法

页替换算法接口

struct swap_manager
{const char *name;/* Global initialization for the swap manager */int (*init)            (void);/* Initialize the priv data inside mm_struct */int (*init_mm)         (struct mm_struct *mm);/* Called when tick interrupt occured */int (*tick_event)      (struct mm_struct *mm);/* Called when map a swappable page into the mm_struct */int (*map_swappable)   (struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in);/* When a page is marked as shared, this routine is called to* delete the addr entry from the swap manager */int (*set_unswappable) (struct mm_struct *mm, uintptr_t addr);/* Try to swap out a page, return then victim */int (*swap_out_victim) (struct mm_struct *mm, struct Page **ptr_page, int in_tick);/* check the page relpacement algorithm */int (*check_swap)(void);     
};

do_pgfault()函数中的部分代码:用于执行页面从磁盘获取并设置页面可替换

 if(swap_init_ok) {struct Page *page=NULL;if(swap_in(mm , addr , &page) != 0 ){  //根据mm和addr尝试在磁盘中加载对应的页cprintf("swap_in in do_pgfault failed\n"); goto failed;}page_insert(mm->pgdir , page ,addr , perm);     //(2) 插入页并对物理地址和虚拟地址映射swap_map_swappable(mm, addr , page , 1);       //(3) 设置为可被切换}else {cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep);goto failed;}}

_fifo_swap_out_vistim函数主要实现页面的换出,_fifo_map_swappable用于添加页面并记录内容。

_fifo_map_swappable:根据规则在头部添加了一下
static int
_fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in)
{list_entry_t *head=(list_entry_t*) mm->sm_priv;list_entry_t *entry=&(page->pra_page_link);assert(entry != NULL && head != NULL);//record the page access situlation/*LAB3 EXERCISE 2: YOUR CODE*/ //(1)link the most recent arrival page at the back of the pra_list_head qeueue.list_add(head , entry);return 0;
}
_fifo_swap_out_victim:删除尾部页面
static int
_fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick)
{list_entry_t *head=(list_entry_t*) mm->sm_priv;assert(head != NULL);assert(in_tick==0);/* Select the victim *//*LAB3 EXERCISE 2: YOUR CODE*/ //(1)  unlink the  earliest arrival page in front of pra_list_head qeueue//(2)  set the addr of addr of this page to ptr_pagelist_entry_t *ulink_pg = head->prev;assert(head != ulink_pg);list_del(ulink_pg);struct Page *page = le2page(ulink_pg , pra_page_link);assert(page != NULL);*ptr_page = page;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/5745.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python node Ubuntu 安装软件、删除软件 、更新软件 中的 软件源概念

在Node 用npm 安装软件 在Python 用 pip 安装软件 在Ubuntu 用 apt 、apt-get 、snap 安装软件 因为这三款软件 都是国外的&#xff0c; 软件包&#xff08;模块&#xff09;都放在国外的&#xff0c; 安装 、更新 特别慢 Node中配置 下载源 在 node 中 要配置 下载的的地址…

【C语言初阶】指针的运算or数组与指针的关系你了解吗?

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《快速入门C语言》《C语言初阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 &#x1f4cb; 前言&#x1f4ac; 指针运算&#x1f4ad; 指针-整数&#x1f4ad; 指针-指针&#x1f4ad; 指针…

关于K8s的Pod的详解(一)

关于K8s的Pod的详解&#xff08;一&#xff09; Pod和API server的通信加快Pod启动更改Pod的资源Pod 的持久卷的单个访问模式Pod 拓扑分布约束Pod 拓扑分布中的最小域数 Pod 作为k8s创建&#xff0c;调度&#xff0c;管理的基本单位。由上级的Controller对Node上安装的Kubelet发…

电脑安装双系统ubuntu18.04+windows后开机直接进入Windows解决方法

电脑型号&#xff1a;联想拯救者Y9000K2021H 系统&#xff1a;Windows11Ubuntu18.04双系统 问题&#xff1a;笔记本安装双系统后&#xff0c;Windows系统下处理word或者看论文&#xff1b;Ubuntu18.04系统安装ros进行机械臂控制等的研究。但最近开机后发现没有系统选项了&#…

网络传输媒体

物理层下面的传输媒体分为两种&#xff1a;导向型传输媒体和非导向型传输媒体。 一、导向型传输媒体 同轴电缆&#xff1a; 图示&#xff1a; 分类&#xff1a; 基带同轴电缆&#xff1a;用于数字传输&#xff0c;在早期局域网中广泛使用宽带同轴电缆&#xff1a;用于模拟传输…

数据结构之BinaryTree(二叉树)的实现

BinaryTree要实现的方法 总结 remove不在BinNode里&#xff0c;而是BinTree里 递归的两种写法 从上往下&#xff1a;同一对象的递归&#xff08;参数多一个&#xff0c;判空用一句话&#xff09;&#xff0c;子对象的递归&#xff08;参数void&#xff0c;判空用两句话&#…

python数据分析05—Pandas数据处理

目录 1.缺失数据处理 1.1 DataFrame自身产生的缺失数据 1.2 缺失数据判断和统计 ​1.3 缺失数据清理 2. 多源数据操作 2.1 合并函数&#xff1a;merge() 2.2 连接函数&#xff1a;join() 2.3 指定方向合并&#xff1a;concat() 3. 数据分组和聚合运算 3.1 groupby()方…

(34)继电器开关

文章目录 前言 34.1 装有IOMCU的自动驾驶仪上的继电器引脚 34.2 通过任务规划器定义继电器引脚 34.3 飞行员控制继电器 34.4 任务控制继电器 34.5 任务规划器控制继电器 前言 "继电器"是自动驾驶仪上的一个数字输出引脚&#xff0c;可在 0V 和 3.3V 或 5V 之间…

《向量数据库指南》:使用公共的Pinecone数据集

目录 数据集包含向量和元数据 列出公共数据集 加载数据集 迭代数据集 分批迭代文档并插入到索引中。 将数据集插入为数据帧。 接下来怎么做 本文档介绍如何使用现有的Pinecone数据集。 要了解创建和列出数据集的方法,请参阅创建数据集。 数据集包含向量和元数据 P…

WPF 搜索框控件样式

WPF 搜索框控件样式 完全通过Xaml代码实现&#xff0c;使用了UserControl进行封装。功能包括聚焦时控件展开&#xff0c;输入为空时的文字提示&#xff0c;以及待选提示项列表等效果。实现效果如下图&#xff1a; xaml代码 <UserControl x:Class"SearchBar.SearchBo…

《C语言杂记》C语言内存泄露分析与检测

1 内存泄露分析 在堆上分配的内存&#xff0c;没有及时释放掉&#xff0c;以便后面其它地方可以重用。在C/C中&#xff0c;内存管理器不会帮你自动回收不再使用的内存。如果你忘了释放不再使用的内存&#xff0c;这些内存就不能被重用&#xff0c;就造成了所谓的内存泄露。 一…

栈OJ(C++)

文章目录 1.最小栈2.栈的压入、弹出序列3.逆波兰表达式&#xff08;后缀表达式&#xff09;求值3.1后缀表达式求值3.2中缀表达式转后缀表达式3.3带有括号的中缀表达式转后缀表达式 1.最小栈 class MinStack { public:MinStack(){}void push(int val){_st.push(val);//empty放在…

7.23 校招实习内推 面经

1、半导体芯片一周资讯 - 英特尔全球裁员1.2万人&#xff0c;台积电3纳米良率仅为55% &#xff0c;马斯克特斯拉正自研芯片 但不会称作GPU 半导体芯片一周资讯 - 英特尔全球裁员1.2万人&#xff0c;台积电3纳米良率仅为55% &#xff0c;马斯克特斯拉正自研芯片 但不会称作GPU …

【kafka调试】用命令行查看kafka是否发出了命令

server 10.10.90.210:9092 topic stream_manager_center_capture_file 摄像头id&#xff1a; 17283ed2a1ac685f9fd5ef9f0de04792 cd /usr/loca/kafka bin/kafka-console-consumer.sh --bootstrap-server 10.10.90.210:9092 --topic stream_manager_center_capture_file 然后添…

<C语言> 数据在内存中的存储

1.数据类型介绍 C语言中的基本内置类型如下&#xff1a; char //字符数据类型 short //短整型 int //整型 long //长整型 long long //更长的整型 float //单精度浮点数 double //双精度浮点数类型的意义&#xff1a; 1.使用这个类…

设计模式-抽象工厂模式

在经济学领域中&#xff0c;其主要研究对象(商品)之间根据消费依存关系可分为互补商品或替代商品&#xff0c;其中&#xff0c;互补商品如汽车与汽油、自行车与自行车胎、大饼和香肠、开水和泡面等。在面向对象的代码世界中&#xff0c;不同对象之间也存在这种类似相互依赖的关…

使用 ChatGPT 碰到的坑

最近在使用 ChatGPT 的时候碰到一个小坑&#xff0c;因为某些特殊情况我需要使用 syslog 向 logbeat 中发送日志。 由于这是一个比较古老的协议&#xff0c;确实也没接触过&#xff0c;所以就想着让 ChatGPT 帮我生成个例子。 原本我已经在 Go 中将这个流程跑通&#xff0c;所…

RocketMQ集成Springboot --Chapter5

RocketMQ tag过滤和sql92语法过滤 tag过滤 生产者&#xff0c;由于springboot没有专门对mq进行tag标记的方法&#xff0c;只是在topic:后面加上&#xff0c;所以只需 rocketMQTemplate.sendOneWay(“tagFilterBoot:TagA”,msg1);标记即可 生产者代码如下 /***生产者* tag过滤*…

PyTorch从零开始实现Transformer

文章目录 自注意力Transformer块编码器解码器块解码器整个Transformer参考来源全部代码&#xff08;可直接运行&#xff09; 自注意力 计算公式 代码实现 class SelfAttention(nn.Module):def __init__(self, embed_size, heads):super(SelfAttention, self).__init__()self.e…

Windows Spark 开发测试版本快速搭建

1、Spark 包下载 清华大学开源软件镜像站下载(速度较快&#xff0c;但版本不全)官方各个版本 下载后解压即可。 &#xff08;可选&#xff09;添加环境变量 SPARK_HOME。并将 %SPARK_HOME%/bin、%SPARK_HOME%/sbin 添加到 path 中。 ps&#xff1a;本文使用的是 spark-3.3.0…