OS-lab2

启动之后,我们的操作系统要能运行,需要一个载体,就是内存。内存的访问不是直接的,而是通过MMU完成。在完成MMU之前,我们先看看一些需要用到的宏定义和函数。

include

  • pmap.h

    定义了内存控制块Page结构体,用于记录页面的分配和使用情况。其中pp_link有两个成员,*le_next用于指向下一个元素,le_prev用于指向前一个元素的**le_next的地址。pp_ref用于记录页面被引用的次数。

    page2pa函数通过给定的Page控制块计算对应的页面的物理地址。

    page2ppn函数通过给定的Page控制块计算这个页面控制块在整个页面控制块数组中的下标。

    pa2page函数通过给定的物理地址计算对应的页面控制块。

    page2kva函数通过给定的Page控制块计算计算这个页面对应的内核虚地址。

    va2pa函数通过给定的页目录和虚拟地址计算对应的物理地址。

    此外还声明了pmap.c中的一些函数。

  • queue.h

    通过宏定义定义了关于链表的一些操作,如初始化、插入删除等。

  • mmu.h

    定义了一系列变量如页面大小BY2PG、标志位PTE_V等。PDX(va)用于获得虚拟地址的高10位,PTX(va)类似。PADDR(kva)用于将内核虚拟地址转化为物理地址,KADDR正好相反。PTE_ADDR用于获得页表项存储的物理地址。

现在,我们一步一步实现MMU。

mm

  • pmap.c

    这个文件集合了管理内存的大部分函数。其中*pages是页面控制块数组,freemem是空闲内存的地址。

    mips_detect_memory函数手动给basemem、maxpa、npage等全局变量进行了赋值。

    *alloc函数手动分配n字节的空闲内存。具体思路即修改freemem的值,然后将alooced_mem清零后返回这个地址。

    *boot_pgdir_walk函数用于获取对应虚拟地址对应的二级页表项。具体流程是通过页目录找到页目录项地址;将页目录项的值转为虚拟地址;检查是否存在,若不存在且create为1,就分配一页,并给对应的页表项赋上标志位;然后再求得对应二级页表项的虚拟地址并返回。

    boot_map_segment函数用于将size大小的虚拟地址区间映射到size大小的物理地址区间。首先将size按BY2PG取整;然后以页为单位,利用*boot_pgdir_walk获得每一页的页表项,再将物理地址和对应的标志位赋给对应的页表项,完成映射。

    mips_vm_init函数完成初始的建立两级页表的任务。首先是用alloc函数分配一页给页目录;然后分配npage个Page给pages数组,用于管理页面;再将pages数组这片区域映射到物理内存;类似的,分配空间给envs进程控制块数组,并映射到对应的物理内存区域。

    以上都是在启动过程中完成的操作。核心是mips_vm_init函数。

    page_init函数用于初始化pages数组并设置page_free_list数组。首先用LIST_INIT函数初始化page_free_list;然后通过freemem和end求得已经分配了多少空闲内存;将已分配的内存即freemem以下的内存以页为单位,通过修改pp_ref为1的方式记录下来;剩下的内存即freemem以上的内存则将pp_ref记为0,并利用LIST_INSERT_HEAD加入到page_free_list中。

    page_alloc函数用于分配一页物理内存。首先需要检查是否存在空闲内存,即利用LIST_EMPTY检查page_free_list是否为空;然后取出第一项并在链表中删掉这一项;最后将这一项对应的内存清零后返回这一页面控制块。

    page_free函数用来释放一页内存。当pp_ref为0时将这一页利用LIST_INSERT_HEAD加入到page_free_list中。

    pgdir_walk函数类似boot_pgdir_walk函数,基本思路一样。区别在于,pgdir_walk函数是在启动之后,所以在需要创建新页表的时候可以使用page_alloc函数,并且分配后将对应的pp_ref增加。boot_pgdir_walk函数由于没有建立页表映射机制,对于pp_ref是无法操作的。

    page_insert函数用于将物理页映射到特定虚拟地址。首先利用pgdir_walk函数取得虚拟地址va的页表项;检查这一页表项是否已经对应到了指定页面上,若页表项不为空且已经映射到了指定页面,则利用tlb_invalidate更新tlb,然后给对应的页表项赋值并返回;若这一页表项不为空且映射的页面不是指定页面,则需要用page_remove将这一虚拟地址对应的页面移除;然后利用tlb_invalidate更新tlb;再一次利用pgdir_walk函数取得页表项,对这一页表项赋值并增加pp_ref。

    page_lookup函数用于获得虚拟地址对应的Page和页表项。首先通过pgdir_walk得到虚拟地址对应的页表项;如果页表项为空或页表项有效位为0则返回;然后通过pa2page得到Page。

    page_decref函数用于减少pp_ref。

    page_remove函数用于移除物理页面到虚拟地址的映射。首先利用page_lookup获得Page和对应的页表项;减少pp_ref,若pp_ref为0则需要用page_free释放掉这一物理页;将页表项清零,并用tlb_invalidate更新tlb。

    tlb_invalidate函数用于使虚拟地址对应的tlb表项失效,而下次访问这个地址就会触发tlb充填,完成对tlb的更新。核心是调用tlb_out函数。

    剩下的三个函数physical_memory_manage_check、page_check、pageout用于检查以上的内存管理函数功能是否正确。

  • tlb_asm.S

    这个文件用于处理tlb更新,即tlb_out函数。首先将CP0_ENTRYHI寄存器的值取出来,将虚拟地址写入;通过tlbp查找与CP0_ENTRYHI内容匹配的页表项并写入CP0_INDEX,由于tlb内部采用流水线设计,因此这条指令后需要执行nop;若找到则将CP0_ENTRYHI和CP0_ENTRYLO0清零,这样在未来对这一虚拟地址进行访问就会诱发tlb充填;利用tlbwi根据CP0_INDEX写tlb,然后恢复CP0_ENTRYHI;若没找到则将CP0_ENTRYHI恢复为原来的值并返回。

OS-lab2的更多相关文章

  1. 【bug记录】OS Lab3 踩坑记

    OS Lab3 踩坑记 Lab3在之前Lab2的基础上,增加了进程建立.调度和中断异常处理.其中测试包括进程建立以及进程调度部分. 由于是第一次做bug记录,而且是调试完bug后再做的记录,所以导致记 ...

  2. OS课程 ucore_lab2实验报告

    练习零:填写已有实验    本实验依赖实验1.请把你做的实验1的代码填入本实验中代码中有"LAB1"的注释相应部分.提示:可采用diff和patch工具进行半自动的合并(merge ...

  3. ucore操作系统学习笔记(二) ucore lab2物理内存管理分析

    一.lab2物理内存管理介绍 操作系统的一个主要职责是管理硬件资源,并向应用程序提供具有良好抽象的接口来使用这些资源. 而内存作为重要的计算机硬件资源,也必然需要被操作系统统一的管理.最初没有操作系统 ...

  4. CMU15-455 Lab2 - task4 Concurrency Index -并发B+树索引算法的实现

    最近在做 CMU-15-445 Database System,lab2 是需要完成一个支持并发操作的B+树,最后一部分的 Task4 是完成并发的索引这里对这部分加锁的思路和完成做一个总结,关于 B ...

  5. [OS] 操作系统课程(三)

    工具 源码阅读:understand 源码文档自动生成工具:Doxygen 编译环境:gcc 运行环境:x86机器或QEMU 调试工具:QEMU+(GDB or IDE) IDE:Eclipse-CD ...

  6. MIT6.828 Lab2 内存管理

    Lab2 0. 任务介绍 你将编写一个内存管理代码.主要分为两大部分.分别对物理内存和虚拟内存的管理. 对于物理内存,每次分配内存分配器会为你分配4096bytes.也称为一个页(在大部分操作系统中一 ...

  7. NodeJs之OS

    OS Node.js提供了一些基本的底层操作系统的模块OS. API var os = require('os'); console.log('[arch] 操作系统CPU架构'+os.arch()) ...

  8. Node.js:OS模块

    os模块,可以用来获取操作系统相关的信息和机器物理信息,例如操作系统平台,内核,cpu架构,内存,cpu,网卡等信息. 使用如下所示: const os = require('os'); var de ...

  9. Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验

    Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...

  10. Mac OS 使用 Vagrant 管理虚拟机(VirtualBox)

    Vagrant(官网.github)是一款构建虚拟开发环境的工具,支持 Window,Linux,Mac OS,Vagrant 中的 Boxes 概念类似于 Docker(实质是不同的),你可以把它看 ...

随机推荐

  1. (转载)Python中关键词yield怎么用?

    原文: https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do 译文: https://zhuanlan.z ...

  2. ChatGPT:让程序开发更轻松

    作者:京东科技 赵龙波 "贾维斯,你在吗?" "随时待命,先生." 类似<钢铁侠>里的人工智能助理贾维斯,ChatGPT或许是你的随时待命的助手.C ...

  3. 深入解读.NET MAUI音乐播放器项目(一):概述与架构

    系列文章将分步解读音乐播放器核心业务及代码: 深入解读.NET MAUI音乐播放器项目(一):概述与架构 深入解读.NET MAUI音乐播放器项目(二):播放内核 深入解读.NET MAUI音乐播放器 ...

  4. elasticsearch-head-master安装

    1 简介 elasticsearch-head是一款专门针对于elasticsearch的客户端工具,elasticsearch-head是一个基于node.js的前端工程 2 依赖 需要安装node ...

  5. 通过pdf模板,填充内容,生成pdf文件---JAVA

    1 概述 我们通常会遇到需要生成某些固定格式,但是内容不同的文件,那么我们就可以使用⽤Adobe Acrobat DC来创建pdf模块,然后通过代码对模板进行填充,生成pdf文件 2 创建一个pdf模 ...

  6. zookeeper05Curator

    转https://blog.csdn.net/u012129558/article/details/81076487   1.zookeeper 开源客户端curator介绍 1.1 curator简 ...

  7. windows10环境下的RabbitMQ安装步骤

    RabbitMQ是一个在AMQP协议标准基础上完整的,可复用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...

  8. 冰河指南AI技术社区基于ChatGPT正式启动运营

    大家好,我是冰河~~ 最近ChatGPT真的太火了,科技圈几乎都在争相报导这个黑科技,它能够通过学习和理解人们的语言来和人类进行对话,能够与人们进行交流,甚至可以对你提出的问题进行分析,尽可能给出你想 ...

  9. The Missing Semester - 第三讲 学习笔记

    第三讲 Vim 课程视频地址:https://www.bilibili.com/video/BV1Dy4y1a7BW 课程讲义地址:https://missing-semester-cn.github ...

  10. uboot之顶层Makefile

    uboot版本信息 VERSION = 2006 主版本号 PATCHLEVEL = 03 补丁版本号 SUBLEVEL = 次此版本号 EXTRAVERSION =  附加版本 NAME      ...