(undone) MIT6.S081 2023 学习笔记 (Day4: LAB3 page tables)

LAB 网页:https://pdos.csail.mit.edu/6.S081/2023/labs/pgtbl.html


任务1:Speed up system calls

根据网页,操作系统可以通过把部分数据放入用户空间的页表,来使得部分系统调用不用进入内核空间,从而提高速度。我们的第一个任务是:对 getpid() 系统调用实现这个优化(通过对页表插入映射的方式)。

以下是作业要求:
1.当一个进程被创建的时候,可以在 USYSCALL 位置插入一个只读的页。在页的开头,存入一个 usyscall 结构体,并且使用当前进程的 pid 初始化它。在实验中,ugetpid() 已经在用户空间中被实现,它会使用 USYSCALL 的映射。只要 ugetpid() 能通过测试,这个 lab 就满分。

暗示:
1.Choose permission bits that allow userspace to only read the page.
2.There are a few things that need to be done over the lifecycle of a new page. For inspiration, understand the trapframe handling in kernel/proc.c.

思考题:
Which other xv6 system call(s) could be made faster using this shared page? Explain how.

OK,根据作业要求,我们先来看看这个 ugetpid() 的实现,相关的测试代码位于 user/pgtbltest.c

void
err(char *why)
{printf("pgtbltest: %s failed: %s, pid=%d\n", testname, why, getpid());exit(1);
}void
ugetpid_test()
{int i;printf("ugetpid_test starting\n");testname = "ugetpid_test";// 执行 64 次 fork,判断 getpid() 是否等于 ugetpid()for (i = 0; i < 64; i++) {int ret = fork();if (ret != 0) {wait(&ret);if (ret != 0)exit(1);continue;}if (getpid() != ugetpid())err("missmatched PID");exit(0);}printf("ugetpid_test: OK\n");
}int
main(int argc, char *argv[])
{ugetpid_test();pgaccess_test();printf("pgtbltest: all tests succeeded\n");exit(0);
}

从代码来看,实际上就是重复调用 fork(),并且在子进程中调用 getpid() 和 ugetpid(),判断两者是否相等。

直接运行 make qemu,发现能执行 pgtbltest,阅读 Makefile,发现 pgtbltest 默认就被作为用户程序编译进磁盘。但是 pgtbltest 虽能执行,却会报错,报错如下:
在这里插入图片描述
在这里插入图片描述
根据手册,scause = 0xd 是 “Load page fault”,缺页错误。说明用户程序访问了一块自己并不拥有的内存。

我们仔细读读 ugetpid() 的实现,如下:

// User memory layout.
// Address zero first:
//   text
//   original data and bss
//   fixed-size stack
//   expandable heap
//   ...
//   USYSCALL (shared with kernel)
//   TRAPFRAME (p->trapframe, used by the trampoline)
//   TRAMPOLINE (the same page as in the kernel)#define TRAPFRAME (TRAMPOLINE - PGSIZE)
#define USYSCALL (TRAPFRAME - PGSIZE)struct usyscall {int pid;  // Process ID
};int
ugetpid(void)
{struct usyscall *u = (struct usyscall *)USYSCALL;return u->pid;
}

结构体 usyscall 其实就是一个 pid 整型,USYSCALL 是一个地址。从代码来看,ugetpid() 其实就是访问了一块虚拟内存。

现在思路大致明了了:在内核里,分配进程的时候,把该进程 pid 映射到该进程的页表上。

先来看分配进程的函数:kernel/proc.c : allocproc()

// Look in the process table for an UNUSED proc.
// If found, initialize state required to run in the kernel,
// and return with p->lock held.
// If there are no free procs, or a memory allocation fails, return 0.
static struct proc*
allocproc(void)
{struct proc *p;for(p = proc; p < &proc[NPROC]; p++) {acquire(&p->lock);if(p->state == UNUSED) {goto found;} else {release(&p->lock);}}return 0;found:p->pid = allocpid();p->state = USED;// Allocate a trapframe page.if((p->trapframe = (struct trapframe *)kalloc()) == 0){freeproc(p);release(&p->lock);return 0;}// An empty user page table.p->pagetable = proc_pagetable(p);if(p->pagetable == 0){freeproc(p);release(&p->lock);return 0;}// Set up new context to start executing at forkret,// which returns to user space.memset(&p->context, 0, sizeof(p->context));p->context.ra = (uint64)forkret;p->context.sp = p->kstack + PGSIZE;return p;
}

可以看到,函数里分配了 pid,以及页表。我们现在进入分配页表的 proc_pagetable() 函数看看

// Create a user page table for a given process, with no user memory,
// but with trampoline and trapframe pages.
pagetable_t
proc_pagetable(struct proc *p)
{pagetable_t pagetable;// An empty page table.pagetable = uvmcreate();if(pagetable == 0)return 0;// map the trampoline code (for system call return)// at the highest user virtual address.// only the supervisor uses it, on the way// to/from user space, so not PTE_U.if(mappages(pagetable, TRAMPOLINE, PGSIZE,(uint64)trampoline, PTE_R | PTE_X) < 0){uvmfree(pagetable, 0);return 0;}// map the trapframe page just below the trampoline page, for// trampoline.S.if(mappages(pagetable, TRAPFRAME, PGSIZE,(uint64)(p->trapframe), PTE_R | PTE_W) < 0){uvmunmap(pagetable, TRAMPOLINE, 1, 0);uvmfree(pagetable, 0);return 0;}return pagetable;
}

可以看到这里使用 mappages 来映射用户页表。我们在这里加上 pid 的映射应该就行了。
我们依葫芦画瓢加上对 pid 的映射,如下:

#ifdef LAB_PGTBL// 把 USYSCALL 映射到用户页表,加速部分系统调用// 若出错,释放 TRAMPOLINE 和 TRAMPFRAME,再释放页表if(mappages(pagetable, USYSCALL, PGSIZE,(uint64)(&(p->pid)), PTE_R) < 0){uvmunmap(pagetable, TRAMPOLINE, 1, 0);uvmunmap(pagetable, TRAPFRAME, 1, 1);uvmfree(pagetable, 0);return 0;}
#endif

启动 make qemu,发现报错,如下:
在这里插入图片描述

这是在 freewalk 函数中 panic。我们启动 qemu-gdb,对 panic,打断点,可以看到函数调用栈如下:
在这里插入图片描述
a
a

TODO: here


TODO: here

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

CSS:怎么把网站都变成灰色

当大家看到全站的内容都变成了灰色&#xff0c;包括按钮、图片等等。这时候我们可能会好奇这是怎么做到的呢&#xff1f; 有人会以为所有的内容都统一换了一个 CSS 样式&#xff0c;图片也全换成灰色的了&#xff0c;按钮等样式也统一换成了灰色样式。但你想想这个成本也太高了…

探索Python文档自动化的奥秘:`python-docx`库全解析

文章目录 探索Python文档自动化的奥秘&#xff1a;python-docx库全解析1. 背景&#xff1a;为何选择python-docx&#xff1f;2. python-docx是什么&#xff1f;3. 如何安装python-docx&#xff1f;4. 简单库函数使用方法创建文档添加段落添加标题添加表格插入图片 5. 应用场景自…

OCP证书如何下载?

访问Oracle CertView网站&#xff1a; 打开网址 https://certview.oracle.com/ &#xff0c;这是Oracle官方提供的证书查询平台 。 登录账号&#xff1a; 使用您的Oracle账号和密码登录CertView。如果您不记得密码&#xff0c;可以通过注册账号时预留的邮箱重置密码 。 查看成…

OBOO鸥柏“触摸屏广告一体机交互”亮相2024中国珠海航展

2024年11月12日&#xff0c;第十五届中国国际航空航天博览会&#xff08;简称中国航展或珠海航展&#xff09;在珠海拉开帷幕。展会现场&#xff0c;既有OBOO鸥柏一大批高精尖液晶显示产品集体亮相&#xff0c;也有航天相关科技领域及飞行表演队炫技蓝天等。在中国航展的各个科…

【智能分子动力学】深度学习驱动分子动力学方法概述

深度学习驱动分子动力学&#xff08;Deep Learning-driven Molecular Dynamics&#xff0c;简称DLDMD&#xff09;方法是将深度学习技术应用于分子动力学模拟中的一种创新方法。这种方法通过深度学习模型来提升传统分子动力学模拟的效率和精度&#xff0c;尤其是在复杂系统的建…

(69)基于Hilbert(希尔伯特)变换的调相信号解调的MATLAB仿真

文章目录 前言一、希尔伯特变换二、相位调制1.基本原理2.调制特点3.应用 三、使用希尔伯特变换进行相位解调的原理1. 解调原理2.算法优点 四、MATLAB仿真1. 仿真代码2. 仿真结果 总结 前言 本文首先介绍了相位调制技术&#xff0c;然后说明了使用希尔伯特变换进行调相信号解调…

ISUP协议视频平台EasyCVR视频设备轨迹回放平台智慧农业视频远程监控管理方案

在当今快速发展的农业领域&#xff0c;智慧农业已成为推动农业现代化、助力乡村全面振兴的新手段和新动能。随着信息技术的持续进步和城市化进程的加快&#xff0c;智慧农业对于监控安全和智能管理的需求日益增长。 视频设备轨迹回放平台EasyCVR作为智慧农业视频远程监控管理方…

Python——NumPy库的简单用法,超级详细教程使用

一、什么是NumPy库 NumPy&#xff1a;它是python的一个科学计算库函数&#xff0c;它是由c语言编写的 它应用于数据处理、机器学习、图像处理、文件操作等等 二、array函数 这里导入库numpy&#xff0c;命名为np&#xff0c;后面的np都是代表着是numpy函数 array函数表示创建…

【postman】怎么通过curl看请求报什么错

获取现成的curl方式&#xff1a; 1&#xff0c;拿别人给的curl 2&#xff0c;手机app界面通过charles抓包&#xff0c;点击接口复制curl 3&#xff0c;浏览器界面-开发者工具-选中接口复制curl 拿到curl之后打开postman&#xff0c;点击import&#xff0c;粘贴curl点击send&am…

高翔【自动驾驶与机器人中的SLAM技术】学习笔记(十三)图优化SLAM的本质

一、直白解释slam与图优化的结合 我从b站上学习理解的这个概念。 视频的大概位置是1个小时以后&#xff0c;在第75min到80min之间。图优化SLAM是怎么一回事。 slam本身是有运动方程的&#xff0c;也就是运动状态递推方程&#xff0c;也就是预测过程。通过t1时刻&#xff0c…

哔哩喵 2.3.11 | 非常好用的第三方B站客户端

哔哩喵是一款非常好用的第三方B站客户端&#xff0c;它允许用户查看各个分区在每个时间段的热门视频列表&#xff0c;支持关键字和UP主屏蔽功能&#xff0c;并能通过添加代理服务器来观看受地区限制的番剧。最新版本2.3.11更新了多项功能&#xff0c;包括个人中心头像及动态大图…

算法定制LiteAIServer摄像机实时接入分析平台玩手机打电话检测算法:智能监控的新篇章

在现代社会&#xff0c;随着智能手机的普及&#xff0c;无论是在工作场所还是公共场所&#xff0c;玩手机或打电话的行为日益普遍。然而&#xff0c;在某些特定环境下&#xff0c;如工厂生产线、仓库、学校课堂等&#xff0c;这些行为可能会影响到工作效率、安全或教学秩序。为…

11个c语言编程练习题

0. 钞票和硬币 money.c 读取一个带有两个小数位的浮点数&#xff0c;代表货币价值。将该值分解为多种钞票和硬币的和&#xff0c;要求使用的钞票和硬币的总数量尽可能少。 货币面值有100&#xff0c;50&#xff0c;20&#xff0c;10&#xff0c;5&#xff0c;1&#xff0c;0.…

【go从零单排】Signals、Exit

&#x1f308;Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 &#x1f4d7;概念 在 Go 语言中&#xff0c;信号&#xff08;signals&#xff09;是操作系统用来通…

PyAEDT:Ansys Electronics Desktop API 简介

在本文中&#xff0c;我将向您介绍 PyAEDT&#xff0c;这是一个 Python 库&#xff0c;旨在增强您对 Ansys Electronics Desktop 或 AEDT 的体验。PyAEDT 通过直接与 AEDT API 交互来简化脚本编写&#xff0c;从而允许在 Ansys 的电磁、热和机械求解器套件之间无缝集成。通过利…

教你制作更方便快捷的电子产品目录!

​在现代工作环境中&#xff0c;电子产品目录进入目录内容的分类的制作。按照电子产品的是至关类型进行重要的分类&#xff0c;环节如&#xff1a;一个清晰、详尽手机、便于、电脑查找的电子产品目录&#xff0c;平板不仅能提高工作效率&#xff0c;还能给客户留下良好的印象。…

硬件工程师之电子元器件—二极管(5)之肖特基二极管

写在前面 本系列文章主要讲解二极管的相关知识&#xff0c;希望能帮助更多的同学认识和了解二极管。 若有相关问题&#xff0c;欢迎评论沟通&#xff0c;共同进步。(*^▽^*) 二极管 9. 肖特基二极管(SBD) 肖特基势垒二极管&#xff08;SBD&#xff09;作为一种二极管&#…

实习冲刺第二十一天

14.最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1&#xff1a; 输入&#xff1a;strs ["flower","flow","flight"] 输出&#xff1a;"fl"示例…

游戏引擎学习第11天

视频参考:https://www.bilibili.com/video/BV1QLmDYQE3n 平台层的编写 应该是平台可移植什么的吧 逐项补充说明&#xff1a; 存档位置 在游戏或应用程序中&#xff0c;需要保存用户的进度、设置和数据&#xff0c;存档位置是指存放这些数据的文件夹路径。通常&#xff0c;平台…

炼码LintCode--数据库题库(级别:入门;数量:144道)--刷题笔记_01

目录 炼码LintCode数据库入门级别的笔记未完待续~~~ 炼码LintCode 数据库 入门级别的笔记 笔记如下&#xff0c;把所有涉及到的入门级别的知识点简单总结了一下。 以及一点点举一反三的写法。 增 INSERT INTO 表名 (列1, 列2, ...) VALUES (值1, 值2, ...);批量增 INSERT INT…