XV6源码阅读——进程地址空间

2024-04-25 02:20

本文主要是介绍XV6源码阅读——进程地址空间,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 页表
  • 实际情况


前言

一个本硕双非的小菜鸡,备战24年秋招。打算尝试6.S081,将它的Lab逐一实现,并记录期间心酸历程。
代码下载

官方网站:6.S081官方网站

页表

每个进程都有一个单独的页表,当xv6在进程之间切换时,也会更改页表。如图2.3所示,一个进程的用户内存从虚拟地址零开始,可以增长到MAXVA (kernel/riscv.h:348),原则上允许一个进程内存寻址空间为256G。

在这里插入图片描述
当进程向xv6请求更多的用户内存时,xv6首先使用kalloc来分配物理页面。然后,它将PTE添加到进程的页表中,指向新的物理页面。Xv6在这些PTE中设置PTE_W、PTE_X、PTE_R、PTE_U和PTE_V标志。大多数进程不使用整个用户地址空间;xv6在未使用的PTE中留空PTE_V。

我们在这里看到了一些使用页表的很好的例子。首先,不同进程的页表将用户地址转换为物理内存的不同页面,这样每个进程都拥有私有内存。第二,每个进程看到的自己的内存空间都是以0地址起始的连续虚拟地址,而进程的物理内存可以是非连续的。第三,内核在用户地址空间的顶部映射一个带有蹦床(trampoline)代码的页面,这样在所有地址空间都可以看到一个单独的物理内存页面。

图3.4更详细地显示了xv6中执行态进程的用户内存布局。栈是单独一个页面,显示的是由exec创建后的初始内容。包含命令行参数的字符串以及指向它们的指针数组位于栈的最顶部。再往下是允许程序在main处开始启动的值(即main的地址、argc、argv),这些值产生的效果就像刚刚调用了main(argc, argv)一样。
在这里插入图片描述
为了检测用户栈是否溢出了所分配栈内存,xv6在栈正下方放置了一个无效的保护页(guard page)。如果用户栈溢出并且进程试图使用栈下方的地址,那么由于映射无效(PTE_V为0)硬件将生成一个页面故障异常。当用户栈溢出时,实际的操作系统可能会自动为其分配更多内存。

XV6使用进程的页表,不仅是告诉硬件如何映射用户虚拟地址,也是明晰哪一个物理页面已经被分配给该进程的唯一记录。这就是为什么释放用户内存(在uvmunmap中)需要检查用户页表的原因。

实际情况

像大多数操作系统一样,xv6使用分页硬件进行内存保护和映射。大多数操作系统通过结合分页和页面故障异常使用分页,比xv6复杂得多,我们将在第4章讨论这一点。

内核通过使用虚拟地址和物理地址之间的直接映射,以及假设在地址0x8000000处有物理RAM (内核期望加载的位置) ,Xv6得到了简化。这在QEMU中很有效,但在实际硬件上却是个坏主意;实际硬件将RAM和设备置于不可预测的物理地址,因此(例如)在xv6期望能够存储内核的0x8000000地址处可能没有RAM。更严肃的内核设计利用页表将任意硬件物理内存布局转换为可预测的内核虚拟地址布局。

RISC-V支持物理地址级别的保护,但xv6没有使用这个特性。

在有大量内存的机器上,使用RISC-V对“超级页面”的支持可能很有意义。而当物理内存较小时,小页面更有用,这样可以以精细的粒度向磁盘分配和输出页面。例如,如果一个程序只使用8KB内存,给它一个4MB的物理内存超级页面是浪费。在有大量内存的机器上,较大的页面是有意义的,并且可以减少页表操作的开销。

xv6内核缺少一个类似malloc可以为小对象提供内存的分配器,这使得内核无法使用需要动态分配的复杂数据结构。

内存分配是一个长期的热门话题,基本问题是有效使用有限的内存并为将来的未知请求做好准备。今天,人们更关心速度而不是空间效率。此外,一个更复杂的内核可能会分配许多不同大小的小块,而不是(如xv6中)只有4096字节的块;一个真正的内核分配器需要处理小分配和大分配。

这篇关于XV6源码阅读——进程地址空间的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/933471

相关文章

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

C#如何优雅地取消进程的执行之Cancellation详解

《C#如何优雅地取消进程的执行之Cancellation详解》本文介绍了.NET框架中的取消协作模型,包括CancellationToken的使用、取消请求的发送和接收、以及如何处理取消事件... 目录概述与取消线程相关的类型代码举例操作取消vs对象取消监听并响应取消请求轮询监听通过回调注册进行监听使用Wa

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

webapp地址

F:\LSP\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear