操作系统lab2实验报告

合集下载

操作系统实验二实验报告

操作系统实验二实验报告

操作系统实验二实验报告一、实验目的本次操作系统实验二的主要目的是深入理解和掌握进程管理的相关概念和技术,包括进程的创建、执行、同步和通信。

通过实际编程和实验操作,提高对操作系统原理的认识,培养解决实际问题的能力。

二、实验环境本次实验使用的操作系统为 Windows 10,编程环境为 Visual Studio 2019。

三、实验内容及步骤(一)进程创建实验1、首先,创建一个新的 C++项目。

2、在项目中,使用 Windows API 函数`CreateProcess`来创建一个新的进程。

3、为新进程指定可执行文件的路径、命令行参数、进程属性等。

4、编写代码来等待新进程的结束,并获取其退出代码。

(二)进程同步实验1、设计一个生产者消费者问题的模型。

2、使用信号量来实现生产者和消费者进程之间的同步。

3、生产者进程不断生成数据并放入共享缓冲区,当缓冲区已满时等待。

4、消费者进程从共享缓冲区中取出数据进行处理,当缓冲区为空时等待。

(三)进程通信实验1、选择使用管道来实现进程之间的通信。

2、创建一个匿名管道,父进程和子进程分别读写管道的两端。

3、父进程向管道写入数据,子进程从管道读取数据并进行处理。

四、实验结果及分析(一)进程创建实验结果成功创建了新的进程,并能够获取到其退出代码。

通过观察进程的创建和执行过程,加深了对进程概念的理解。

(二)进程同步实验结果通过使用信号量,生产者和消费者进程能够正确地进行同步,避免了缓冲区的溢出和数据的丢失。

分析结果表明,信号量机制有效地解决了进程之间的资源竞争和协调问题。

(三)进程通信实验结果通过管道实现了父进程和子进程之间的数据通信。

数据能够准确地在进程之间传递,验证了管道通信的有效性。

五、遇到的问题及解决方法(一)在进程创建实验中,遇到了参数设置不正确导致进程创建失败的问题。

通过仔细查阅文档和调试,最终正确设置了参数,成功创建了进程。

(二)在进程同步实验中,出现了信号量使用不当导致死锁的情况。

操作系统lab2实验报告

操作系统lab2实验报告

操作系统lab2实验报告实验目的:本实验的目的是通过设计和实现一个简单的操作系统内核,加深对操作系统基本概念和原理的理解。

具体实验内容包括进程管理、内存管理和文件系统的设计与实现。

实验环境:1.操作系统:Linux2.编程语言:C语言一、实验背景1.1 操作系统简介操作系统是计算机系统中的一个重要组成部分,负责管理和控制计算机的各种资源,提供用户和应用程序的接口,以及协调和调度各种任务的执行。

1.2 实验目标本实验的主要目标是设计和实现一个简单的操作系统内核,包括进程管理、内存管理和文件系统等功能。

二、实验内容2.1 进程管理①进程创建描述进程创建的过程和相关数据结构,包括创建新进程的系统调用、进程控制块等。

②进程调度描述进程调度的算法和实现方式,包括进程调度队列、调度算法等。

③进程同步与通信描述进程同步和通信的机制和方法,包括信号量、互斥锁、条件变量等。

2.2 内存管理①内存分配描述内存分配的算法和实现方式,包括连续内存分配、非连续内存分配等。

②页面置换描述页面置换的算法和实现方式,包括最优页面置换算法、先进先出页面置换算法等。

2.3 文件系统①文件操作描述文件操作的系统调用和相关数据结构,包括文件打开、读写、关闭等。

②文件系统结构描述文件系统的组织结构和实现方式,包括超级块、索引节点、块位图等。

三、实验步骤3.1 环境搭建搭建实验环境,包括安装Linux操作系统、编译器等。

3.2 进程管理实现根据设计要求,实现进程创建、调度、同步与通信等功能。

3.3 内存管理实现根据设计要求,实现内存分配、页面置换等功能。

3.4 文件系统实现根据设计要求,实现文件操作和文件系统结构。

3.5 测试与调试编写测试用例,对实现的操作系统内核进行测试和调试,并记录实验结果。

四、实验结果分析分析测试结果,评估实验过程中遇到的问题和解决方法,总结操作系统内核的性能和功能特点。

五、实验总结对实验过程中的收获和经验进行总结,提出改进和优化的建议。

操作系统实验报告实验二

操作系统实验报告实验二

操作系统实验报告实验二一、实验目的本次操作系统实验二的目的在于深入理解和掌握操作系统中的进程管理和进程调度相关知识,通过实际的编程和实验操作,观察和分析不同进程调度算法的性能和效果,提高对操作系统核心概念的理解和应用能力。

二、实验环境本次实验在 Windows 10 操作系统下进行,使用 Visual Studio 2019作为编程工具。

实验中涉及的编程语言为 C++。

三、实验内容(一)进程创建与控制编写程序实现创建多个进程,并通过进程控制原语(如创建、等待、终止等)对进程进行管理和控制。

(二)进程调度算法实现1、先来先服务(FCFS)调度算法按照进程到达的先后顺序进行调度,先到达的进程先获得 CPU 资源进行执行。

2、短作业优先(SJF)调度算法优先调度执行时间短的进程,以减少平均等待时间。

3、时间片轮转(RR)调度算法将 CPU 时间划分为固定大小的时间片,每个进程在一个时间片内执行,时间片结束后切换到下一个进程。

(三)性能评估指标1、平均等待时间所有进程等待时间的总和除以进程数量。

2、平均周转时间所有进程周转时间的总和除以进程数量。

周转时间为进程从提交到完成的时间间隔。

四、实验步骤(一)进程创建与控制1、定义进程结构体,包含进程 ID、到达时间、执行时间等信息。

2、使用系统调用或库函数创建进程。

3、在父进程中通过等待函数等待子进程结束,并获取子进程的返回状态。

(二)进程调度算法实现1、先来先服务(FCFS)调度算法按照进程到达时间的先后顺序将进程放入就绪队列。

从就绪队列中取出第一个进程进行调度执行。

2、短作业优先(SJF)调度算法计算每个进程的执行时间。

按照执行时间从小到大的顺序将进程放入就绪队列。

从就绪队列中取出执行时间最短的进程进行调度执行。

3、时间片轮转(RR)调度算法将进程按照到达时间先后顺序放入就绪队列。

为每个进程分配一个时间片,当时间片用完后,将进程放入就绪队列尾部,重新调度下一个进程。

操作系统Lab2实验报告

操作系统Lab2实验报告

深入学习 操作系统的原理和实 现细节,包括进程通 信、死锁处理、虚拟 化技术等。
实践应用
希望将所学的操作系 统知识应用到实际项 目中,提高自己的实 践能力。
持续学习
随着技术的不断发展 ,操作系统也在不断 更新和进步,需要保 持持续学习的态度。
探索新领域
对于新兴的操作系统 领域,如云操作系统 、物联网操作系统等 ,也希望有所涉猎和 探索。
学生将了解操作系统内核的组成和功能,以及操作系统如何通过内核 实现各种基本功能。
学生将通过实验深入了解操作系统的内部实现细节,提高自己对操作 系统设计和实现的认知水平。
02
实验内容
进程管理实验
总结词
理解进程状态及其转换、进程控制块PCB的组成、进程调度算法。
详细描述
通过实验,我们深入了解了进程的概念、状态及其转换。进程控制块PCB的组成,包括进程标 识符、进程状态、优先级、CPU寄存器内容等信息。此外,我们还学习了进程调度算法,如先 来先服务、最短作业优先、优先级调度等,并进行了模拟实验。
THANKS
感谢观看
操作系统Lab2实验 报告
汇报人:
202X-01-08
目录
• 实验目的 • 实验内容 • 实验结果与分析 • 问题与改进建议 • 总结与展望
01
实验目的
理解操作系统的基本概念
01
掌握核心概念
02
操作系统是计算机系统的核心软件,负责管理计算机硬件和软件资源 ,为用户提供便利的操作界面和高效的服务。
03
操作系统具有并发性、虚拟性、异步性和随机性的特点,这些特点决 定了操作系统在计算机系统中的重要地位和作用。
04
操作系统的基本功能包括进程管理、内存管理、文件管理和设备管理 ,这些功能是操作系统实现其核心目标的基础。

Linux_LAB2

Linux_LAB2

实验二Linux桌面环境的基本操作实验目的:1.通过本次实验熟练的掌握Linux操作系统桌面环境下的基本操2.了解Linux文件系统的目录格式。

3.掌握GNOME桌面环境和KDE桌面环境的切换。

实训内容1:熟悉GNOME桌面环境的各组成部分。

掌握文件管理器的使用方法。

设置GNOME桌面环境1.面板的基本操作【操作要求1】在GNOME桌面上增加和删除面板;在面板上增加和删除对象。

【操作步骤】见课件中的步骤。

【操作要求2】设置面板的位置和自动隐藏,启动不同的应用程序,将它们放置于不同的4个虚拟桌面(工作区)中。

【操作步骤】见课件中的步骤。

2. 查看Linux的目录结构,认识/bin、/etc、/lost+found、/sbin、/var、/boot、/root、/home、/mnt、/tmp、/dev、/lib、/proc、/usr目录及其作用。

【操作要求】查看Linux的目录结构。

【操作步骤】参见“Linux文件系统结构”课件中的内容。

3.使用文件管理器(注意:本操作尽量在/home目录中进行)【操作要求1】基本文件操作:a)新建文本文件;b)新建一个目录;c)以不同的视图方式查看文件;d)删除刚才新建的文本文件和目录【操作要求2】显示隐藏文件。

4.设置桌面【操作要求1】为虚拟桌面(工作区)更换桌面背景图片。

【操作要求2】更换桌面屏幕保护程序。

【操作步骤】以上3个操作要求见课件。

5.熟悉Linux的目录结构【操作要求1】找到桌面(Desktop)所对应的实际目录。

【操作步骤】root的主文件夹-Desktop中可以找到。

实验内容2熟悉KDE桌面环境的各组成部分。

掌握Konqueror文件管理器的使用方法。

设置KDE桌面环境。

1.面板的基本操作【操作要求1】在KDE面板上增加和删除对象。

【操作步骤】见课件及书上【操作要求2】设置面板的位置和自动隐藏。

【操作步骤】见课件及书上2.桌面的基本操作【操作要求】重新排列桌面图标,将虚拟桌面设置为6个。

pintos Lab2 实验报告

pintos Lab2 实验报告

华东师范大学软件学院实验报告实验课程:操作系统实践年级:大二实验成绩:实验名称:Pintos-User Programs 姓名:实验编号:学号:实验日期:2018/12/27指导教师:组号:实验时间:4学时一、实验目的当前, 我们已经完成了pintos 的第一部分(熟悉了其基础结构和线程包), 现在是开始处理系统中允许运行用户程序的部分的时候了。

基本代码已经支持加载和运行用户程序, 但不能加载和运行或交互性。

在此项目中, 我们将使程序能够通过系统调用与操作系统进行交互。

我们将在"userprog" 目录中进行工作, 但我们也将与pintos 的几乎所有其他部分进行交互。

具体目的如下:(1)了解Pintos操作系统的功能流程及内核的软件工程结构。

(2)通过Pintos操作系统内核的剖析,了解现有Pintos操作系统在处理用户程序方面中存在的参数传递问题,有效解决其参数传递的问题。

(3)通过Pintos内核剖析,了解其中断处理的机制,学会操作系统中断功能的编写方法。

(4)了解现有Pintos操作系统的系统调用功能,根据其中断机制,完善系统调用功能,使Pintos系统具有处理用户中断请求的功能。

(5)通过Pintos内核剖析,解决现有Pintos操作系统中存在的进程终止时缺少终端提示的问题。

(6)通过Pintos内核剖析,解决现有Pintos操作系统中存在的运行文件禁止写操作的问题。

二、实验内容与实验步骤实验内容如下:(1)在分析内核的基础上,对Pintos操作系统的参数传递问题提出有效的策略,设计算法,分步跟踪和调试,通过实践,有效解决参数传递问题,并对实验结果进行分析。

(2)通过Pintos操作系统内核的剖析,了解其中断处理的机制,在此基础上,完善Pintos的系统调用功能,设计算法,分步跟踪和调试,通过测试分析完善的系统调用功能。

(3)在分析内核的基础上,对现有Pintos操作系统进行完善,增加进程终止的终端提示功能,设计算法,分步跟踪和调试,通过实践,验证终端提示功的有效性。

OS-lab2实验报告

OS-lab2实验报告

OS-lab2实验报告lab2实验报告⼀、实验思考题Thinking 2.1请思考cache⽤虚拟地址来查询的可能性,并且给出这种⽅式对访存带来的好处和坏处。

另外,你能否能根据前⼀个问题的解答来得出⽤物理地址来查询的优势?虚拟地址:cache⽤虚拟地址来查询是有可能的,并且确实存在这样的cache组织⽅式(VIVT、VIPT)好处:不需要使⽤mmu转换成物理地址就可以直接根据虚拟地址查找cache中的数据坏处:不同的进程可能会有相同的虚拟地址,安全性和数据正确性很难保证,需要引⼊物理地址或者其他的标识符加以区分物理地址:优势:优势即在于没有根据虚拟地址查询时需要区分不同的进程的问题,查询的安全性和数据正确性更有保证Thinking 2.2在我们的实验中,有许多对虚拟地址或者物理地址操作的宏函数(详见include/mmu.h ),那么我们在调⽤这些宏的时候需要弄清楚需要操作的地址是物理地址还是虚拟地址,阅读下⾯的代码,指出x是⼀个物理地址还是虚拟地址。

int x;char *value = return_a_pointer();*value = 10;x = (int) value;x是⼀个虚拟地址Thinking 2.3我们在 include/queue.h 中定义了⼀系列的宏函数来简化对链表的操作。

实际上,我们在 include/queue.h ⽂件中定义的链表和 glibc 相关源码较为相似,这⼀链表设计也应⽤于Linux 系统中 (sys/queue.h ⽂件)。

请阅读这些宏函数的代码,说说它们的原理和巧妙之处。

原理:链表头是⼀个结构体,存储了头指针,对于链表的每⼀个节点,内部存储的结构体存储了指向下⼀个节点的地址和前⼀项中指向下⼀个节点的指针的地址。

巧妙之处:每⼀个节点存储了前⼀项中指向下⼀个节点的指针的地址,插⼊和删除节点的复杂度很低Thinking 2.4我们注意到我们把宏函数的函数体写成了 do { /* ... */ } while(0)的形式,⽽不是仅仅写成形如 { /* ... */ } 的语句块,这样的写法好处是什么?空的宏定义避免warning存在⼀个独⽴的block,可以⽤来进⾏变量定义,替换到程序当中不会产⽣歧义或者错误,能够进⾏⽐较复杂的实现Thinking 2.5注意,我们定义的 Page 结构体只是⼀个信息的载体,它只代表了相应物理内存页的信息,它本⾝并不是物理内存页。

《操作系统》实验二

《操作系统》实验二

《操作系统》实验二一、实验目的本实验旨在加深对操作系统基本概念和原理的理解,通过实际操作,提高对操作系统设计和实现的认知。

通过实验二,我们将重点掌握进程管理、线程调度、内存管理和文件系统的基本原理和实现方法。

二、实验内容1、进程管理a.实现进程创建、撤销、阻塞、唤醒等基本操作。

b.设计一个简单的进程调度算法,如轮转法或优先级调度法。

c.实现进程间的通信机制,如共享内存或消息队列。

2、线程调度a.实现线程的创建、撤销和调度。

b.实现一个简单的线程调度算法,如协同多任务(cooperative multitasking)。

3、内存管理a.设计一个简单的分页内存管理系统。

b.实现内存的分配和回收。

c.实现一个简单的内存保护机制。

4、文件系统a.设计一个简单的文件系统,包括文件的创建、读取、写入和删除。

b.实现文件的存储和检索。

c.实现文件的备份和恢复。

三、实验步骤1、进程管理a.首先,设计一个进程类,包含进程的基本属性(如进程ID、状态、优先级等)和操作方法(如创建、撤销、阻塞、唤醒等)。

b.然后,实现一个进程调度器,根据不同的调度算法对进程进行调度。

可以使用模拟的方法,不需要真实的硬件环境。

c.最后,实现进程间的通信机制,可以通过模拟共享内存或消息队列来实现。

2、线程调度a.首先,设计一个线程类,包含线程的基本属性(如线程ID、状态等)和操作方法(如创建、撤销等)。

b.然后,实现一个线程调度器,根据不同的调度算法对线程进行调度。

同样可以使用模拟的方法。

3、内存管理a.首先,设计一个内存页框类,包含页框的基本属性(如页框号、状态等)和操作方法(如分配、回收等)。

b.然后,实现一个内存管理器,根据不同的内存保护机制对内存进行保护。

可以使用模拟的方法。

4、文件系统a.首先,设计一个文件类,包含文件的基本属性(如文件名、大小等)和操作方法(如创建、读取、写入、删除等)。

b.然后,实现一个文件系统管理器,包括文件的存储和检索功能。

LAB2实验报告2033

LAB2实验报告2033

LAB2实验报告2033数字系统组成原理实验实验二运算器ALU181学号 1315212033姓名滕健伟班级电子信息2班华侨大学电子工程系一、算术逻辑运算实验一.实验目的1.了解简单运算器的数据传输通路。

2.验证运算功能发生器的组合功能。

3.掌握算术逻辑运算加、减、与的工作原理。

4.验证实验台运算的8 位加、减、与、直通功能。

5.按给定数据,完成几种指定的算术和逻辑运算。

二.实验内容实验原理算术逻辑单元ALU 的数据通路如图1-1 所示。

其中运算器ALU181 根据74LS181 的功能用VHDL 硬件描述语言编辑而成,构成8 位字长的ALU。

参加运算的两个8 位数据分别为A[7..0]和B[7..0],运算模式由S[3..0]的16 种组合决定,而S[3..0]的值由4 位2 进制计数器LPM_COUNTER 产生,计数时钟是Sclk;此外,设M=0,选择算术运算,M=1 为逻辑运算,CN 为低位的进位位;F[7..0]为输出结果,CO 为运算后的输出进位位。

两个8 位数据由总线IN[7..0]分别通过两个电平锁存器74373 锁入,ALU 功能如表1-1 所示。

选择端高电平作用数据S3S2S1S0M=H M=L算术操作逻辑功能Cn=L(无进位)Cn=H(有进位)0000F= A F= A F= A加10001F= A+ B F= A+ B F=(A+ B)加10010F= AB F= A+ B F= A+ B+10011F= 0 F= 减1(2的补码)F= 00100F= AB F= A加AB F= A加AB加10101F= B F=(A+ B)加AB F=(A+ B)加AB+10110F= A⊕ B F= A减B F= A减B减10111F= AB F= A+ B F= (A+ B)减11000F= A + B F= A加AB F= A加AB加11001 F = A⊕ B F= A加B F= A加B加11010F= B F=(A+ B)加AB F= (A+ B)加AB加11011F= AB F= AB F= AB减11100F= 1 F= A加A*F= A加A加11101F= A+ B F=(A+ B)加A F=(A+ B)加A加11110F= A+ B F=(A+ B)加A F=(A+ B)加A加11111F= A F= A F= A减1表1-1三.实验步骤(1)设计ALU 元件在Quartus II 环境下,用文本输入编辑器T ext Editor 输入ALU181.VHD 算术逻辑单元文件,编译VHDL文件,并将ALU181.VHD 文件制作成一个可调用的原理图元件。

OSLab(2)

OSLab(2)

操作系统实验报告哈尔滨工程大学软件学院第二讲操作系统的启动一、实验概述1. 实验名称操作系统的启动2. 实验目的● 跟踪调试EOS在PC机上从加电复位到成功启动的全过程,了解操作系统的启动过程。

● 查看EOS启动后的状态和行为,理解操作系统启动后的工作方式。

3. 实验类型(验证、设计)验证4. 实验内容1.准备实验2.调试EOS操作系统的启动过程2.1使用Bochs做为远程目标机2.2 调试BIOS程序2.3 调试软盘引导扇区程序2.4 调试加载程序2.5 调试内核2.6 EOS启动后的状态和行为二、实验环境操作系统:windos xp工 具:Tevation OS Lab三、实验过程(每次实验不一定下面6条都写,根据实际情况定)1. 设计思路和流程图根据已给的地址,计算高端地址,设计查看内存的调试命令图2.1 EOS启动流程图2. 算法实现无3. 需要解决的问题及解答(1)设计两个查看内存的调试命令,分别验证这两个用户可用区域的高地址端也是空白的第一条命令:0x7a08第二条命令:0x9fe08(2)设计一个查看内存的调试命令,验证上位内存的高地址端已经被系统占用命令:0xffe08(3)设计一个查看内存的调试命令,查看内存中loader程序结束位置的字节码,并与loader.lst文件中最后指令的字节码比较,验证loader程序被完全加载到了正确的位置。

命令:0x1616(4)仔细比较图10-6和图10-5,尝试说明哪个是应用程序的进程,它和系统进程有什么区别,哪个是应用程序的主线程,它和系统线程有什么区别应用程序进程:ID为31的进程为应用程序进程与系统进程的区别:系统进程用于完成操作系统的各种功能的进程,是处于运行状态下的操作系统本身;应用程序进程就是所有由用户启动的进程。

应用程序主线程:PrimaryThreadID=31的是应用程序主线程与系统线程的区别:主线程的优先级别高。

存放在物理内存的低端四、实验体会过本次试验,我对计算机存储结构有了更深的认识,在验证的过程中计算地址时出现了失误,但在和同学讨论中解决了问题,复习了二进制十进制及十六进制之间的转换。

操作系统实验报告Lab2物理内存管理(含challenge)

操作系统实验报告Lab2物理内存管理(含challenge)

Lab2实验报告一、练习0:填写已有实验利用Understand中的Compare完成此练习。

二、练习1:实现firstfit连续物理内存分配算法大体思路:物理内存页管理器顺着双向链表进行搜索空闲内存区域,直到找到一个足够大的空闲区域,这是一种速度很快的算法,因为它尽可能少地搜索链表。

如果空闲区域的大小和申请分配的大小正好一样,则把这个空闲区域分配出去,成功返回;否则将该空闲区分为两部分,一部分区域与申请分配的大小相等,把它分配出去,剩下的一部分区域形成新的空闲区。

其释放内存的设计思路很简单,只需把这块区域重新放回双向链表中即可。

实现目标:重写default_init_memmap(),default_alloc_pages(),default_free_pages()函数。

具体细节:a)default_init_memmap()函数这个函数是用来初始化空闲页链表的。

主要有两个步骤:初始化每一个空闲页,计算空闲页的总数。

注意:1.使用头插法是因为地址是从低地址向高地址增长。

2.p->flags = 0语句已经将PG_reserved标志位置零。

b)default_alloc_pages()函数这个函数是用来分配空闲页的。

主要步骤如下:1.寻找足够大的空闲块1.1.如果找到了,重新设置标志位1.2.从空闲链表中删除此页1.3.判断空闲块大小是否合适1.3.1.如果不合适,分割页块1.3.2.如果合适则不进行操作1.4.计算剩余空闲页个数1.5.返回分配的页块地址备注:在参考答案中,我认为有些语句是冗余的,如图:验证:在第二次重置标志位前后,分别输出标志位的值,发现,flags 并没有发生变化。

然后将这两句话注释,编译后运行,依旧可以得到正确答案。

所以我认为这两句话是没有必要的。

c)default_free_pages()函数这个函数的作用是释放已经使用完的页,把他们合并到freelist中。

操作系统lab2实验报告

操作系统lab2实验报告

操作系统lab2实验报告操作系统 Lab2 实验报告一、实验目的本次实验着重学习操作系统内存管理的相关概念和技术,包括页表的建立和管理,以及虚拟内存系统的实现和优化。

通过完成本实验,我们能够加深对操作系统内存管理机制的理解,并掌握相关的实现方法。

二、实验环境本次实验使用的实验环境为 Linux 操作系统(具体版本号)、GCC 编译器(具体版本号)以及所提供的模拟器。

三、实验内容本次实验主要包括以下几个任务:1. 理解虚拟内存和物理内存的概念,掌握页表的结构和管理方法。

2. 编写代码实现一个简单的页表建立和管理的模拟器,包括页表的初始化、地址映射和页表的更新。

3. 实现一个简单的虚拟内存系统,包括页的加载、替换等操作。

4. 对实现的虚拟内存系统进行性能优化,包括缓存算法的改进、预加载等策略的应用。

四、实验步骤及结果1. 理解虚拟内存和物理内存的概念在本次实验中,我们将使用虚拟内存系统来管理进程的地址空间。

虚拟内存是操作系统提供给进程的一种抽象概念,它为每个进程提供了一个独立的、连续的地址空间。

物理内存是实际存在的计算机内存,由物理地址组成。

2. 编写页表管理模拟器代码根据实验要求,我们需要编写代码模拟页表的建立和管理过程。

首先,我们需要实现页表的初始化函数,用于初始化页表的数据结构。

接着,我们需要实现地址映射函数,用于将虚拟地址映射到物理地址。

最后,我们需要实现页表的更新函数,用于更新页表中的相关信息。

3. 实现虚拟内存系统在本次实验中,我们需要实现一个简单的虚拟内存系统。

虚拟内存系统可以将虚拟地址映射到物理地址,并且可以实现页的加载和替换操作。

我们需要实现页面加载函数,用于将页面加载到内存中。

同时,我们还需要实现页面替换函数,当内存空间不足时,根据特定的算法选择待替换的页,并将其移出内存。

4. 性能优化为了提高虚拟内存系统的性能,我们可以采用一些优化策略。

例如,我们可以改进缓存算法,通过提前缓存一些可能会被访问的页面,减少缺页次数。

Lab2实验报告

Lab2实验报告

In this lab, I define 4 classes to implement the method.1.The first is Good with no attribute, just used to classify it’s a good chip.2.The second is Bad, the same with the Good class, but to express it’s a bad chip;3.The third is Test, used to find a good chip in the chip arrays . and here we use 分而治之法.4.The last is instance, using the good chip chosen in the third class to test other chips and print the outcome whether the chip is bad or good. And we use instanceof sign to test whether our outcome is true or not.(if chip is the instance of Good ,then it’s a good chip, otherwise it’s a bad one and compare with the outcome generated by the method in Test, we can judge whether the method can give what we want)Something added to my code.(1)I use arraylist to implement the array of chips and use two classes good andbad to represent good chips and bad chips.(2)I use true or false to represent 1 and 0 to express the outcome by mutual test.(3)To random the position of my chips, I use 伪随机. At first ,put the array intothe arraylist and then random some position and get the element at thisposition to the last of the array, so that we can get the random configuration of good and bad chips.代码部分//Class 1//define a good object which represent good chips without anyproperties.public class Good {}//Class 2//define a bad object which represent bad chipspublic class Bad {}//Class 3import java.util.ArrayList;public class Test {public static Object ultimate;/** the AtestB method is conformed with the requirement gg istrue ,gb is false, bg is true/false, bb is true/false, which is random because the chip is bad ,it has no ability to judge , and i use true and false to represent 0 and 1*/static boolean AtestB(Object A, Object B) {Good good = new Good();Bad bad = new Bad();if instanceof Good && B instanceof Good)return true;else if ((A instanceof Good && B instanceof Bad))return false;else {// use random to get the outcomeint result = (int) (Math.random() * 2);if (result == 0) {return false;} elsereturn true;}}// use n/2 method 分而治之static void nTest(ArrayList all) {int length = all.size();int divide = length / 2;ArrayList first = new ArrayList();ArrayList last = new ArrayList();ArrayList newList = new ArrayList();/** divide the arraylist all into 2 arraylist and test two objects whose* index are the same*/for (int i = 0; i < divide; i++) {first.add(all.get(i));}for (int i = divide; i < 2 * divide; i++) {last.add(all.get(i));}// if the length is odd, then judge whether divide/2 is evenif (length % 2 == 1) {// if divide/2 is even, then add the last element of "all" which is// left in the above procedure to the newListif (divide % 2 == 0) {newList.add(all.get(2 * divide));}}// if the test is all true and leave either one ,here I choose the// element in first arraylistfor (int i = 0; i < divide; i++) {if (AtestB(first.get(i), last.get(i))&& AtestB(last.get(i), first.get(i))) {newList.add(first.get(i));}}/** if arraylist has odd number, put the last one to temp and add it to* the newlist at last*/int newLength = newList.size();// if the length of the newList is 0,then the last one is a good chip,// and return it// if the length is 1,it must be a good chipif (newLength == 1) {ultimate = newList.get(0);return;}if (newLength == 0) {System.exit(0);}elsenTest(newList);}}//Class 4import java.util.ArrayList;public class Instance {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubArrayList array = new ArrayList();// make sure the good chips are greater than bad chips so that the// outcome is reliableint number = (int) (Math.random() * 1000);// the total number is// produced by randomint badNum = (int) (Math.random() * number); // the total number is// produced by randomif (badNum > number / 2) {System.out.println("the result will beunreliable,please try again!");System.exit(0);}int goodNum = number - badNum;// add good and bad chips into the array in sequence atfirstfor (int i = 0; i < badNum; i++) {array.add(new Bad());}for (int i = badNum; i < number; i++) {array.add(new Good());}// do the random change position so that the position of good and bad// chips are random rather than in sequencefor (int i = 0; i < 1000; i++) {int random = (int) (Math.random() * (number / 2));array.add(array.get(random));array.remove(random);}// output the total number and the good number and bad numberSystem.out.println("The total numbers of chips are " + array.size()+ "\n there are " + goodNum + " good chips. \n there are "+ badNum + " bad chips");Test test = new Test();test.nTest(array);// use the right one chose in the test method to test other chip so that// we can get the entire outcomefor (int i = 0; i < array.size(); i++) {if+ (i + 1)+ "st chip is good ");elseSystem.out.print("The test outcome the " + (i + 1)+ "st chip is bad ");// use the instanceof method to test whether the chip is good or bad// to test the outcome aboveif (array.get(i) instanceof Good)System.out.println("The right outcome the " + (i + 1)+ "st chip is good");elseSystem.out.println("The right outcome the " + (i + 1)+ "st chip is bad");}}}The naïve method which I didn’t write use this method: test an element by all other element of the array in sequence ,record all of the outcome anddo the circulation for every element until you find an element with the outcome like Num(true) >= Num(false).<Num(true) represents the numbers of true outcome , and Num(bad) represents the numbers of bad outcome>For there are N chips, A good chips and B bad chips and A > B, if N is odd, then A >= B+1,if what we test is a good chip ,then at least Numb(true) = A – 1 = Num(false).<all of the good chips say it’s good and all of the bad chips say it’s a bad chip>, if what we choose is a bad chip, then at least Num(false) = A > Num(true) = B – 1. <all of the good chips say it’s bad and all of thebad chips say it’s a good chip>. If N is even , then A >= B + 2, if we choose an good one, the worst case is ,Num(true) = A – 1 >= B + 1>Num(false) = B, if we choose a bad one ,Num(false) = A > Num(true) = B – 1. In conclusion, whether N is old or even ,as long as A > B, if we get the outcome like Num(true) >= Num(false), we can know that the chip is a good one. And we can use it to test all the other chips in the array and print the outcome to be seen by the professor.If we have B > A , the number of bad chips are bigger than that of good chips.If N = odd , B >= A + 1 When test a bad chip ,it’s possible we can get the result like, Num(true) = B – 1 >= Num(false) = A, and when we test a good chip, it’s possible that we can get the result Num(false) = B >= Num(true)= A – 1; if N = even ,B >= A +2, When test a bad chip ,it’s possible we can get the result like, Num(true) = B – 1 > Num(false) = A, and when we test a good chip, it’s possible that we can get the result Num(false) = B >=Num(true) = A – 1; so the outcome we get will be not right.About the b problem , I use Chinese to explain.分而治之法:分情况考虑(1)n为偶数随机的两两配对,则共有n/2对,分别测试<在我的代码里是从中间分成两个array,然后让两个数组里面的下标相同的去比较测试>。

操作系统lab2实验总结——Part1

操作系统lab2实验总结——Part1

操作系统lab2实验总结——Part1这是MIPS虚拟映射布局图,在接下来的实验中,我们需要特别注意的地址分别是kuseg和kseg0区,⾸先列出这两个区域的意义。

MIPS虚存映射布局32位的MIPS CPU最⼤寻址空间为4GB(2^32字节),这4GB虚存空间被划分为四个部分:1. kuseg (TLB-mapped cacheable user space, 0x00000000 - 0x7fffffff):这⼀段是⽤户模式下可⽤的地址,⼤⼩为2G,也就是MIPS约定的⽤户内存空间。

需要通过MMU进⾏虚拟地址到物理地址的转换。

2. kseg0 (direct-mapped cached kernel space, 0x80000000 - 0x9fffffff):这⼀段是内核地址,其内存虚存地址到物理内存地址的映射转换不通过MMU,使⽤时只需要将地址的最⾼位清零(& 0x7fffffff),这些地址就被转换为物理地址。

也就是说,这段逻辑地址被连续地映射到物理内存的低端512M空间。

对这段地址的存取都会通过⾼速缓存(cached)。

通常在没有MMU的系统中,这段空间⽤于存放⼤多数程序和数据。

对于有 MMU 的系统,操作系统的内核会存放在这个区域。

kuseg中有三个⼤⼩为PDMAP(4MB)的区域,分别从0x7f400000开始是ENVS,PAGES和User VPT。

需要注意的是PAGES和User VPT 的关系:User VPT中存放了1024个页表,由于⾃映射的关系,这个页表⾥⼜包括了页⽬录的页表,每⼀个页表中⼜有1024个页表项。

PAGES存放了48个页表,这48个页表映射的内容是16*1024个物理页框的结构体(struct Page)的物理内存。

在lab2实验中,我们只⽤了boot_map_segment函数将PAGES的内容进⾏了映射,并没有操作User VPT的空间。

第⼀幅图将是我们理解整个mm/pmap.c的核⼼,接下来将按照init/init.c中的顺序进⾏逐⼀解释每个函数的细节和整体的启动布局。

OS课程ucore_lab2实验报告

OS课程ucore_lab2实验报告

OS课程ucore_lab2实验报告练习零:填写已有实验 本实验依赖实验1。

请把你做的实验1的代码填⼊本实验中代码中有“LAB1”的注释相应部分。

提⽰:可采⽤diff和patch⼯具进⾏半⾃动的合并(merge),也可⽤⼀些图形化的⽐较/merge⼯具来⼿动合并,⽐如meld,eclipse中的diff/merge⼯具,understand中的diff/merge⼯具等。

其实 lab1 中只有 kern/debug/kdebug.c kern/init/init.c kern/trap/trap.c 被改过了所以只⽤把这三个⽂件复制到lab2中就可以了。

练习⼀:实现 first-fit 连续物理内存分配算法(需要编程) 在实现first fit 内存分配算法的回收函数时,要考虑地址连续的空闲块之间的合并操作。

提⽰:在建⽴空闲页块链表时,需要按照空闲页块起始地址来排序,形成⼀个有序的链表。

可能会修改default_pmm.c中的default_init,default_init_memmap,default_alloc_pages, default_free_pages等相关函数。

请仔细查看和理解default_pmm.c中的注释。

 查看注释后,发现代码已经写了,于是make qemu 了⼀发,发现错了,断⾔失败。

仔细看了后,代码是不完整的。

 断⾔失败之前的检查都是针对页分配成功、失败的测试,从失败的断⾔这⾥开始是对分配的页的位置进⾏的检查。

 实际上,最初的实现 default_*_pages 只是简单的插⼊到链表,根本没有关⼼被插⼊到了哪⾥,所以在多次 alloc/free 之后页块在链表中的位置乱得⼀塌糊涂。

如果需要保序,需要对每个改动链表的地⽅注意⼀下位置。

struct Page {// 页帧的引⽤计数int ref;// 页帧的状态 Reserve 表⽰是否被内核保留另⼀个是表⽰是否可分配uint32_t flags;// 记录连续空闲页块的数量只在第⼀块进⾏设置unsigned int property;// ⽤于将所有的页帧串在⼀个双向链表中这个地⽅很有趣直接将 Page 这个结构体加⼊链表中会有点浪费空间因此在 Page 中设置⼀个链表的结点将其结点加⼊到链表中还原的⽅法是将链表中的 page_link 的地址减去它所 list_entry_t page_link;};// 初始化空闲页块链表static void default_init(void) {list_init(&free_list);nr_free = 0; // 空闲页块⼀开始是0个}// 初始化n个空闲页块static void default_init_memmap(struct Page *base, size_t n) {assert(n > 0);struct Page *p = base;for (; p != base + n; p ++) {assert(PageReserved(p)); // 看看这个页是不是被内核保留的p->flags = p->property = 0;set_page_ref(p, 0);}base->property = n; // 头⼀个空闲页块要设置数量SetPageProperty(base);nr_free += n;// 初始化玩每个空闲页后将其要插⼊到链表每次都插⼊到节点前⾯因为是按地址排序list_add_before(&free_list, &(base->page_link));}// 分配n个页块static struct Page * default_alloc_pages(size_t n) {assert(n > 0);if (n > nr_free) {return NULL;}struct Page *page = NULL;list_entry_t *le = &free_list;// 查找 n 个或以上空闲页块若找到则判断是否⼤过 n 则将其拆分并将拆分后的剩下的空闲页块加回到链表中while ((le = list_next(le)) != &free_list) {// 此处 le2page 就是将 le 的地址 - page_link 在 Page 的偏移从⽽找到 Page 的地址struct Page *p = le2page(le, page_link);if (p->property >= n) {page = p;break;}}if (page != NULL) {if (page->property > n) {struct Page *p = page + n;p->property = page->property - n;SetPageProperty(p);// 将多出来的插⼊到被分配掉的页块后⾯list_add(&(page->page_link), &(p->page_link));}// 最后在空闲页链表中删除掉原来的空闲页list_del(&(page->page_link));nr_free -= n;ClearPageProperty(page);}return page;}// 释放掉 n 个页块static void default_free_pages(struct Page *base, size_t n) {assert(n > 0);struct Page *p = base;for (; p != base + n; p ++) {assert(!PageReserved(p) && !PageProperty(p));p->flags = 0;set_page_ref(p, 0);}base->property = n;SetPageProperty(base);list_entry_t *le = list_next(&free_list);// 合并到合适的页块中while (le != &free_list) {p = le2page(le, page_link);le = list_next(le);if (base + base->property == p) {base->property += p->property;ClearPageProperty(p);list_del(&(p->page_link));}else if (p + p->property == base) {p->property += base->property;ClearPageProperty(base);base = p;list_del(&(p->page_link));}}nr_free += n;le = list_next(&free_list);// 将合并好的合适的页块添加回空闲页块链表while (le != &free_list) {p = le2page(le, page_link);if (base + base->property <= p) {break;}le = list_next(le);}list_add_before(le, &(base->page_link));}成功后会提⽰:然后会在另⼀个地⽅断⾔挂掉,那是接下来的实验了。

Windows操作系统实验二实验报告

Windows操作系统实验二实验报告

Windows操作系统C/C++ 程序实验姓名:_____王晨璐_____学号:____1131000046____班级:____1班_____院系:___信息工程学院_____2015__年_10_月_26_日实验二Windows 2000/xp进程控制一、背景知识二、实验目的三、工具/准备工作四、实验内容与步骤请回答:Windows所创建的每个进程都是以调用CreateProcess()API函数开始和以调用TerminateProcess()或ExitProcess() API函数终止。

1. 创建进程步骤5:编译完成后,单击“Build”菜单中的“Build 2-1.exe”命令,建立2-1.exe可执行文件。

操作能否正常进行?如果不行,则可能的原因是什么?可以正常运行。

清单2-1展示的是一个简单的使用CreateProcess() API函数的例子。

首先形成简单的命令行,提供当前的EXE文件的指定文件名和代表生成克隆进程的号码。

大多数参数都可取缺省值,但是创建标志参数使用了:CREATE_NEW_CONSOLE标志,指示新进程分配它自己的控制台,这使得运行示例程序时,在任务栏上产生许多活动标记。

然后该克隆进程的创建方法关闭传递过来的句柄并返回main() 函数。

在关闭程序之前,每一进程的执行主线程暂停一下,以便让用户看到其中的至少一个窗口。

CreateProcess() 函数有10个核心参数?本实验程序中设置的各个参数的值是:a. LPCSTR lpApplivetionName szFllenameb. LPCSTR lpCommandLine szCmdLinec. LPSECURITY_ATTRIBUTES lpProcessAttributes NULLd. LPSECURITY_ATTRIBUTES lpThreadAttributes NULLe.BOOL bInherithandle Falsef. DWORD dwCreationFlage CREATE_NEW_CONSOLEg. LPVOID ipEnvironment NULLh. LPCTSTR lpCurrentDirectory NULLI. STARTUPINFO lp startupinfo &siJ. LPPROCESS_INFORMATION lpProcessInformation &pi 程序运行时屏幕显示的信息是:提示:部分程序在Visual C++环境完成编译、链接之后,还可以在Windows 2000/xp的“命令提示符”状态下尝试执行该程序,看看与在可视化界面下运行的结果有没有不同?为什么?界面是一样的2. 正在运行的进程步骤10:编译完成后,单击“Build”菜单中的“Build 2-2.exe”命令,建立2-2.exe可执行文件。

lab2-系统加固实验

lab2-系统加固实验

实验二系统加固实验1、实验目的通常按默认方式安装的操作系统,如果不做任何安全加固,那么其安全性难以保证,非常容易被攻击,而且攻击者稍加利用就会变成肉机。

所以保证系统安全性第一步,便是利用操作系统自身功能进行系统加固。

通过该实验,要求学生学会使用操作系统自身的注册表、组策略和关闭不必要的端口进一步增强系统的安全性能。

2、实验环境实验内容一:PC机一台,Windows XP操作系统实验内容二:PC机一台,windows xp操作系统、ScanPort软件实验内容三:PC机一台,windows xp虚拟机、恶意程序一个(附件提供)3、实验内容实验内容一:利用操作系统自身功能加固系统知识准备:注册表介绍:一、注册表根键说明hkey_classes_root包含注册的所有OLE信息和文档类型,是从hkey_local_machine\software\classes复制的。

hkey_current_user包含登录的用户配置信息,是从hkey_users\当前用户子树复制的。

hkey_local_machine包含本机的配置信息。

其中config子树是显示器打印机信息; enum 子树是即插即用设备信息;system子树是设备驱动程序和服务参数的控制集合;software 子树是应用程序专用设置。

hkey_users所有登录用户信息。

hkey_current_config包含常被用户改变的部分硬件软件配置,如字体设置、显示器类型、打印机设置等。

是从hkey_local_machine\config复制的。

二、注册表详细内容Hkey_local_machine\software\microsoft\windows\currentVersion\explorer\usershell folders保存个人文件夹、收藏夹的路径Hkey_local_machine\system\currentControlSet\control\keyboard Layouts保存键盘使用的语言以及各种中文输入法Hkey_users\.Default\software\microsoft\internet explorer\typeURLs保存IE浏览器地址栏中输入的URL地址列表信息。

最新操作系统实验报告实验二

最新操作系统实验报告实验二

最新操作系统实验报告实验二实验目的:1. 熟悉最新操作系统的架构和特性。

2. 掌握操作系统的基本操作和配置方法。

3. 分析操作系统的性能和稳定性。

实验环境:- 硬件环境:Intel Core i7处理器,16GB RAM,256GB SSD。

- 软件环境:最新操作系统版本X.Y.Z,图形界面和命令行界面。

实验步骤:1. 安装最新操作系统X.Y.Z,记录安装过程中的关键步骤和遇到的问题。

2. 配置系统环境,包括网络设置、显示设置、用户账户管理等。

3. 测试文件系统的性能,包括文件的创建、复制、删除和搜索操作。

4. 测试多任务处理能力,通过同时运行多个应用程序来观察系统响应时间和资源分配情况。

5. 检验系统的安全性,包括用户权限管理、防火墙设置和病毒防护功能。

6. 评估系统的稳定性,进行长时间运行测试,记录是否有崩溃或异常行为发生。

7. 对系统进行基准测试,使用专业工具如SPEC CPU测试套件来评估系统性能。

实验结果:1. 安装过程中,系统顺利识别硬件并完成驱动安装,未遇到兼容性问题。

2. 系统配置简便,图形用户界面直观易用,网络配置通过向导快速完成。

3. 文件系统测试显示,读写速度达到预期标准,搜索操作响应迅速。

4. 多任务处理测试中,系统在开启多个资源密集型应用时仍保持流畅,未出现明显延迟。

5. 安全性测试表明,用户权限分级明确,防火墙和病毒防护均能有效工作。

6. 稳定性测试中,系统连续运行72小时无故障,表现出良好的稳定性。

7. 基准测试结果显示,系统性能较前一版本有显著提升,特别是在多线程处理方面。

实验结论:最新操作系统X.Y.Z在本次实验中表现出了良好的性能和稳定性。

系统的用户界面友好,配置和管理方便。

文件系统和多任务处理能力均达到预期目标,安全性和稳定性也符合最新的操作系统标准。

推荐对性能和稳定性有较高要求的用户进行升级。

操作系统实验二实验报告

操作系统实验二实验报告

操作系统实验报告——实验二:线程和管道通信实验一、实验目的通过Linux 系统中线程和管道通信机制的实验,加深对于线程控制和管道通信概念的理解,观察和体验并发进(线)程间的通信和协作的效果,练习利用无名管道进行进(线)程间通信的编程和调试技术。

二、实验说明1) 与线程创建、执行有关的系统调用说明线程是在共享内存中并发执行的多道执行路径,它们共享一个进程的资源,如进程程序段、文件描述符和信号等,但有各自的执行路径和堆栈。

线程的创建无需像进程那样重新申请系统资源,线程在上下文切换时也无需像进程那样更换内存映像。

多线程的并发执行即避免了多进程并发的上下文切换的开销又可以提高并发处理的效率。

pthread 库中最基本的调用。

1.pthread_create 系统调用语法:#include <pthread.h>Int pthread_create(pthread_t *thread,pthread_attr_t *attr,void *(*start_routine)(void *) Void *arg);pthread_create 函数创建一个新的线程。

pthread_create 在thread 中保存新线程的标识符。

Attr 决定了线程应用那种线程属性。

使用默认可给定参数NULL; (*start_routine) 是一个指向新线程中要执行的函数的指针arg 是新线程函数携带的参数。

Pthread_create 执行成功会返回0并在thread 中保存线程标识符。

执行失败则返回一个非0的出错代码2.pthread_exit 系统调用语法:#include <pthread.h>void pthread_exit(void *retval);pthread_exit 函数使用函数pthread_cleanup_push 调用任何用于该线程的清除处理函数,然后中止当前进程的执行,返回retval。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

HUNAN UNIVERSITY操作系统实验报告目录一、内容 (3)二、目的 (3)三、实验设计思想和练习题 (3)练习0:填写已有实验 (3)练习1:实现 first-fit 连续物理内存分配算法(需要编程) (3)练习2:实现寻找虚拟地址对应的页表项(需要编程) (8)练习3:释放某虚地址所在的页并取消对应二级页表项的映射(需要编程) (11)运行结果 (13)四、实验体会 (13)一、内容本次实验包含三个部分。

首先了解如何发现系统中的物理内存;然后了解如何建立对物理内存的初步管理,即了解连续物理内存管理;最后了解页表相关的操作,即如何建立页表来实现虚拟内存到物理内存之间的映射,对段页式内存管理机制有一个比较全面的了解。

二、目的1.理解基于段页式内存地址的转换机制;2.理解页表的建立和使用方法;3.理解物理内存的管理方法。

三、实验设计思想和练习题练习0:填写已有实验使用eclipse中的diff/merge工具将实验1的代码填入本实验中代码中有“LAB1”的注释相应部分。

练习1:实现 first-fit 连续物理内存分配算法(需要编程)在实现first fit 内存分配算法的回收函数时,要考虑地址连续的空闲块之间的合并操作。

提示:在建立空闲页块链表时,需要按照空闲页块起始地址来排序,形成一个有序的链表。

可能会修改default_pmm.c 中的default_init,default_init_memmap,default_alloc_pages, default_free_pages等相关函数。

请仔细查看和理解default_pmm.c中的注释。

请在实验报告中简要说明你的设计实现过程。

请回答如下问题:你的first fit算法是否有进一步的改进空间。

解答:分析思路:(1)数据结构:A.每个物理页利用一个Page结构体表示,查看kern/mm/memlayout.h包括:ref:引用计数,即映射此物理页的虚拟页个数;flags:描述物理页属性,bit 0设置为1,即为“被保留”项,bit 1设置为1,即为空闲项;property:记录某连续内存块的大小,即地址连续的空闲页的个数;page_link:将多个连续内存链接在一起的双向链表指针,即构建双向链接各个Page结构的双向链表。

B.所有的连续内存空闲块可用一个双向链表管理,利用一个free_area_t结构体表示,查看kern/mm/memlayout.h包括:list_entry:双向链表指针,指向空闲的物理页;nr_free:记录当前空闲页的个数的无符号整形变量。

(2)连续物理内存分配思路:物理内存页管理器顺着双向链表进行搜索空闲内存区域,直到找到一个足够大的空闲区域,这是一种速度很快的算法,因为它尽可能少地搜索链表。

如果空闲区域的大小和申请分配的大小正好一样,则把这个空闲区域分配出去,成功返回;否则将该空闲区分为两部分,一部分区域与申请分配的大小相等,把它分配出去,剩下的一部分区域形成新的空闲区。

其释放内存的设计思路是把这块区域重新放回双向链表中。

(3)具体设计:bootloader进行探测物理格局后,利用kern_entry()函数设置堆栈,并临时建立一个段映射关系,调用kern_init()函数输出检查后,pmm_init()函数完成物理内存的管理,假定page_init()函数是按照地址从小到大的顺序传递连续内存空闲块,根据page_init()函数中传递的参数(某个连续的空闲块的起始页,页个数),default_init_memmap()来建立一个连续内存空闲块的双向链表,链表头设free_area.free_list,链表项设Page的base->page_link。

代码分析:(1)default_init_memmap :用于构建空闲页链表;A.步骤:(1)初始化每一个空闲页,注意使用头插法是因为地址是从低到高地址增长;(2)计算空闲页的总数。

B.具体实现:(2)default_alloc_pages :用于为进程分配空闲页;A.步骤:(1)从空闲链表表头开始查找最小的地址,寻找足够大的空闲块;(2)如果找到,获得指向分配的页,重新设置标志位,从空闲链表中删除此页;(3)判断空闲块大小是否合适;(4)如果合适,不操作;如果不合适,分割页块;(5)计算剩余空闲页个数,返回分配的页块地址。

B.具体实现:注:算法改进空间:第一页重置标志位操作被注释后,依然可以编译运行。

(3)default_free_pages :用于释放已经使用完的页,使其合并到free_list中;A.步骤:(1)在free_list中查找合适位置,用以插入;(2)改变被释放页的标志位flags及计数器ref;(3)在free_list中向高地址或第地址合并。

B.具体实现:练习2:实现寻找虚拟地址对应的页表项(需要编程)通过设置页表和对应的页表项,可建立虚拟内存地址和物理内存地址的对应关系。

其中的get_pte函数是设置页表项环节中的一个重要步骤。

此函数找到一个虚地址对应的二级页表项的内核虚地址,如果此二级页表项不存在,则分配一个包含此项的二级页表。

本练习需要补全get_pte函数 in kern/mm/pmm.c,实现其功能。

请回答如下问题:请描述页目录项(Pag Director Entry)和页表(Page Table Entry)中每个组成部分的含义和以及对ucore 而言的潜在用处。

如果ucore执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?解答:分析思路:pde_t为page directory entry,也就是一级页表的表项。

pte_t为page table entry,表示二级页表的表项。

uintptr_t表示为线性地址,由于段式管理只做直接映射,所以它也是逻辑地址。

pgdir(一级页表)给出页表起始地址。

通过查找这个页表,我们需要给出二级页表中对应项的地址。

虽然目前我们只有boot_pgdir一个页表,但是引入进程的概念之后每个进程都会有自己的页表。

有可能根本就没有对应的二级页表的情况,所以二级页表不必要一开始就分配,而是等到需要的时候再添加对应的二级页表。

如果在查找二级页表项时,发现对应的二级页表不存在,则需要根据create参数的值来处理是否创建新的二级页表。

如果create参数为0,则get_pte返回NULL;如果create参数不为0,则get_pte需要申请一个新的物理页(通过alloc_page来实现,可在mm/pmm.h中找到它的定义),再在一级页表中添加页目录项指向表示二级页表的新物理页。

注,新申请的页必须全部设定为零,因为这个页所代表的虚拟地址都没有被映射。

当建立从一级页表到二级页表的映射时,需要注意设置控制位。

这里应该设置同时设置上PTE_U、PTE_W和PTE_P(定义在mm/mmu.h):PTE_U:表示用户态的软件可以读取对应地址的物理内存页内容;PTE_W:表示物理内存页内容可写;PTE_P:表示物理内存页存在如果原来就有二级页表,或者新建立了页表,则只需返回对应项的地址即可。

代码分析:A.步骤:(1)尝试获取页表起始地址;(2)若不成功则直接返回NULL,若成功则申请一个物理页;(3)获得物理页的线性地址,在一级页表中添加页目录项指向表示二级页表的新物理页;(4)返回页表地址。

B.具体实现:问题解答:(1)请描述页目录项(Pag Director Entry)和页表(Page Table Entry)中每个组成部分的含义和以及对ucore而言的潜在用处。

答:高20位表示下一级页表(或物理页表)的基址(4K对齐),后12位为标志位,分别为从低位起第0~6位为ucore内核占用,表示指向的下一级页面的某些特性(是否存在、是否可写……);对于PDE,第7位表示如果pde的PTE_PS位为1,那么pde中所存的就不是下一级页表,而是一张4M页的起始地址;对于PTE,第7、8位强制位0;第9~11位供内核以外的软件使用。

(2)如果ucore执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?答:出现页访问异常会触发缺页中断,缺页中断发生时的事件顺序如下:1) 硬件陷入内核,在内核堆栈中保存程序计数器。

大多数机器将当前指令的各种状态信息保存在特殊的CPU寄存器中。

2) 启动一个汇编代码例程保存通用寄存器和其他易失的信息,以免被操作系统破坏。

3) 当操作系统发现一个缺页中断时,尝试发现需要哪个虚拟页面。

通常一个硬件寄存器包含了这一信息,如果没有的话,操作系统必须检索程序计数器,取出这条指令,用软件分析这条指令,看看它在缺页中断时正在做什么。

4) 一旦知道了发生缺页中断的虚拟地址,操作系统检查这个地址是否有效,并检查存取与保护是否一致。

如果不一致,向进程发出一个信号或杀掉该进程。

如果地址有效且没有保护错误发生,系统则检查是否有空闲页框。

如果没有空闲页框,执行页面置换算法寻找一个页面来淘汰。

5) 如果选择的页框“脏”了,安排该页写回磁盘,并发生一次上下文切换,挂起产生缺页中断的进程,让其他进程运行直至磁盘传输结束。

无论如何,该页框被标记为忙,以免因为其他原因而被其他进程占用。

6) 一旦页框“干净”后(无论是立刻还是在写回磁盘后),操作系统查找所需页面在磁盘上的地址,通过磁盘操作将其装入。

该页面被装入后,产生缺页中断的进程仍然被挂起,并且如果有其他可运行的用户进程,则选择另一个用户进程运行。

7) 当磁盘中断发生时,表明该页已经被装入,页表已经更新可以反映它的位置,页框也被标记为正常状态。

8) 恢复发生缺页中断指令以前的状态,程序计数器重新指向这条指令。

9) 调度引发缺页中断的进程,操作系统返回调用它的汇编语言。

10) 该例程恢复寄存器和其他状态信息。

练习3:释放某虚地址所在的页并取消对应二级页表项的映射(需要编程)当释放一个包含某虚地址的物理内存页时,需要让对应此物理内存页的管理数据结构Page做相关的清除处理,使得此物理内存页成为空闲;另外还需把表示虚地址与物理地址对应关系的二级页表项清除。

请仔细查看和理解page_remove_pte函数中的注释。

为此,需要补全在 kern/mm/pmm.c中的page_remove_pte 函数。

请回答如下问题:数据结构Page的全局变量(其实是一个数组)的每一项与页表中的页目录项和页表项有无对应关系?如果有,其对应关系是啥?如果希望虚拟地址与物理地址相等,则需要如何修改lab2,完成此事?解答:分析思路:使用pte2page宏即可得到从页表项得到对应的物理页面所对应的Page结构体。

得到结构体后,判断此页被引用的次数,如果仅仅被引用一次,对页面引用进行更改,降为零则这个页可以被释放。

相关文档
最新文档