操作系统-ucore-lab3
ucosiii移植原理
![ucosiii移植原理](https://img.taocdn.com/s3/m/b547caa9541810a6f524ccbff121dd36a32dc4dc.png)
ucosiii移植原理
uCOSIII(MicroC/OS-III)是一款开源的实时操作系统(RTOS),适用于各种嵌入式系统和实时应用。
uCOSIII的移植原理主要包括以下几个方面:
1. 硬件抽象层(HAL):首先,需要针对特定硬件平台(如STM32、ARM、AVR等)编写硬件抽象层代码。
硬件抽象层的作用是将硬件平台的特性和接口抽象成统一的、易于操作的接口,以便于上层应用程序和实时操作系统进行调用。
2. 移植uCOSIII内核:将uCOSIII内核代码移植到目标硬件平台,主要包括以下几个步骤:
a. 配置uCOSIII内核:根据目标硬件平台的特性,配置uCOSIII内核的参数,如内存大小、任务数量等。
b. 修改内核代码:根据目标硬件平台的实际情况,修改内核代码,以适应不同硬件平台的需求。
这可能包括:修改内存管理代码、时钟管理代码、中断处理代码等。
c. 编写初始化代码:编写初始化代码,用于在系统启动时初始化
内核及其相关组件。
3. 移植uCOSIII的应用实例:根据项目需求,编写基于uCOSIII的应用实例。
这可能包括:编写驱动程序、编写通信协议、编写应用程序等。
4. 集成测试:将编写好的硬件抽象层、内核及应用实例集成到一起,进行系统测试和调试,确保整个系统的稳定性和可靠性。
5. 优化与调试:根据实际运行情况,对系统进行优化和调试,以提高系统的性能和资源利用率。
总之,uCOSIII的移植原理主要包括硬件抽象层的编写、uCOSIII内核的移植、应用实例的编写、集成测试以及优化与调试。
通过这些步骤,可以将uCOSIII成功移植到不同的硬件平台,并应用于各种实时系统。
ucos-iii知识点总结
![ucos-iii知识点总结](https://img.taocdn.com/s3/m/08f2258e011ca300a7c390a3.png)
1、其中最有用的功能应该是时间片轮转法(roundrobin), 这个是uC/OS-II 中不支持的,但是现在已经是uC/OS-III 的一个功能了2、uC/OS-III 被设计用于32 位处理器,但是它也能在16 位或8 位处理器中很好地工作。
3、一共有2 种类型的实时系统:软实时系统和硬实时系统。
硬实时系统中,运算超时是不允许发生的,运算超时会导致严重后果。
但是在软实时系统中,超时不会导致严重后果4、前后台系统:包含一个无限循环的模块实现需要的操作(后台)。
中断处理程序实现异步事件(前台)。
前台也叫做中断级,后台也叫作任务级。
5、临界操作应该在任务级中被执行,不可避免地必须在中断处理程序中执行也要确保是在很短的时间内完成。
因为这会导致ISR 占用更长的时间。
通常的,ISR 中使能相关的信息而在后台程序中执行相应的操作。
6、ucos-iii中的任务(也叫做线程)是一段简单的程序,运行时完全地占用CPU 。
在单CPU 中,任何时候只有1 个任务被执行。
7、内核的责任是管理任务,协调和切换多个任务依次享用CPU 。
让我们感觉是多个CPU 在同时运行,也有利于处理模块化的应用它也负责管理任务间的交流,系统资源的管理(内存和I/O )等。
8、uC/OS-III 是一个抢占式内核,这意味着uC/OS-III 总是执行最重要的就绪任务9、ISR 响应中断请求设备,但是ISR 只做非常少的工作。
ISR 应该标记或发送消息到一个高优先级的任务,让中断能够快速处理完毕10、系统中加入内核需要额外的支出,因为内核提供服务时需要时间去处理。
内核占用CPU 的时间介于2% 到4% 之间。
因为uC/OS-III是一个软件,添加到目标系统中需要额外的ROM 和RAM 。
11、。
uC/OS-III 内核需要1K 到4K 之间的RAM ,加上每个任务自己所需的堆栈空间。
至少有4K 大小RAM 的处理器才有可能成功移植uC/OS-III 。
UCOS III 配置与初始化
![UCOS III 配置与初始化](https://img.taocdn.com/s3/m/2ba3d615b7360b4c2e3f6465.png)
/********************************************************************
********************************************************
void OSIntExit (void)
{
CPU_SR_ALLOC();
*/
if (p_stk != (CPU_STK *)0) {
/*关于 OSCfg_ISRStkBasePtr 我也不是很清楚,不用也行*/ size = OSCfg_ISRStkSize;
/*在 os_cfg_app.c 中有定义 CPU_STK* const OSCfg_ISRStkBasePtr= (CPU_STK*)&OSCfg_ISRStk[0];*/
return;
}
#endif
#if OS_CFG_TMR_EN > 0u
/* Initialize the Timer Manager module
*/
OS_TmrInit(p_err);
if (*p_err != OS_ERR_NONE) {
return;
}
#endif
#if OS_CFG_DBG_EN > 0u OS_Dbg_Init();
}
#endif
OS_IdleTaskInit(p_err); /* 初始化空任务,一般没有别的任务工作的话,就由它来占 CPU,空任务 的优先级要最低*/ if (*p_err != OS_ERR_NONE) {
return; }
OS_TickTaskInit(p_err);
/* 初始化时钟节拍函数
计算机系统基础实验介绍Lab3
![计算机系统基础实验介绍Lab3](https://img.taocdn.com/s3/m/c44b05c8cc7931b764ce150e.png)
Lab3 实验任务(续)
4)任务四:boom(续) 本阶段的实验任务就是构造这样一个攻击字符串,使得 getbuf函数不管获得什么输入,都能将正确的cookie值返回 给test函数,而不是返回值1。除此之外,你的攻击代码应还 原任何被破坏的状态,将正确返回地址压入栈中,并执行ret 指令从而真正返回到test函数。
目标程序bufbomb续?缓冲区攻击从getbuf函数开始函数gets并不判断buf数组是否足够大它只是简单地向目标地址复制全部输入字符串因此输入如果超出预先分配的存储空间边界就会造成缓冲区溢出
计算机系统基础实验介绍Lab3
学术诚信
如果你确实无法完成实验, 你可以选择不 提交。如果抄袭,不管抄袭者还是被抄袭者, 均以零分论处并按作弊处分。
正常情况下,如果你的操作不符合预 期(!success),会看到信息“Better luck next time”,这时你就要继续-8尝-
目标程序BUFBOMB(续)
• 本实验的主要内容从分析test函数开始。
test函数中调用了getbuf函数, getbuf函数的功能是 从标准输入(stdin)读入一个字符串。
熟练运用gdb、objdump、gcc等工具。
-4-
二、实验数据
• /s/1hs2Mw1Q • 下载实验数据包: lab3.tar
在本地目录将数据包解压: tar –xf lab3.tar
数据包中至少包含下面四个文件:
* bufbomb: 可执行程序,攻击所用的目标程序bufbomb。 * bufbomb.c: C语言源程序,目标程序bufbomb的主程序。 * makecookie:可执行程序,该程序基于你的学号产生一个唯一的由8
void fizz(int val) {
清华大学操作系统实验lab1实验报告
![清华大学操作系统实验lab1实验报告](https://img.taocdn.com/s3/m/fb4f31d9195f312b3169a566.png)
练习1、理解通过make生成执行文件的过程。
[练习1.1] 操作系统镜像文件ucore.img 是如何一步一步生成的?在proj1执行命令make V=可以得到make指令执行的过程从这几条指令中可以看出需要生成ucore.img首先需要生成bootblock,而生成bootblock需要先生成bootmain.o和bootasm.o还有sign,这三个文件又分别由bootmain.c、bootasm.S、sigh.c来生成。
ld -m elf_i386 -N -e start -Ttext 0x7C00 obj/boot/bootasm.o obj/boot/bootmain.o –o obj/bootblock.o这句话用于生成bootblock,elf_i386表示生成elf头,0x7C00为程序的入口。
'obj/bootblock.out' size: 440 bytes这句话表示生成的bootblock的文件大小,因为大小不到512字节,所以需要给blootblock填充,填充的功能在sign.c中有所体现,最后两字节设置为了0x55,0xAAbuf[510] = 0x55;buf[511] = 0xAA;FILE *ofp = fopen(argv[2], "wb+");size = fwrite(buf, 1, 512, ofp);[练习1.2] 一个被系统认为是符合规范的硬盘主引导扇区的特征是什么?前面已经提到过:引导扇区的大小为512字节,最后两个字节为标志性结束字节0x55,0xAA,做完这样的检查才能认为是符合规范的磁盘主引导扇区。
Sign.c文件中有作检查:if (size != 512) {fprintf(stderr, "write '%s' error, size is %d.\n", argv[2], size);return -1;}练习2:使用qemu执行并调试lab1中的软件。
uC-OS-III的特点
![uC-OS-III的特点](https://img.taocdn.com/s3/m/0f486cc3dd88d0d233d46aff.png)
uC/OS-III的特点uC/OS-III简介uC/OS-III(Micro C OS Three 微型的C 语言编写的操作系统第3版)是一个可升级的,可固化的,基于优先级的实时内核。
它对任务的个数无限制。
uC/OS-III 是一个第3 代的系统内核,支持现代的实时内核所期待的大部分功能。
例如资源管理,同步,任务间的通信等等。
然而,uC/OS-III 提供的特色功能在其它的实时内核中是找不到的,比如说完备的运行时间测量性能,直接地发送信号或者消息到任务,任务可以同时等待多个内核对象等。
uC/OS-III 是一个可扩展的,可固化的,抢占式的实时内核,它管理的任务个数不受限制。
它是第三代内核,提供了现代实时内核所期望的所有功能包括资源管理、同步、内部任务交流等。
uC/OS-III 也提供了很多特性是在其他实时内核中所没有的。
比如能在运行时测量运行性能,直接得发送信号或消息给任务,任务能同时等待多个信号量和消息队列。
uC/OS-III主要特点1、时间片轮转调度:uC/OS-III 允许多个任务拥有相同的优先级。
当多个相同优先级的任务就绪时,并且这个优先级是目前最高的。
uC/OS-III 会分配用户定义的时间片给每个任务去运行。
每个任务可以定义不同的时间片。
当任务用不完时间片时可以让出CPU 给另一个任务。
2、抢占式多任务处理:uC/OS-III 是一个抢占式多任务处理内核,因此,uC/OS-III 正在运行的经常是最重要的就绪任务。
3、快速响应中断:uC/OS-III 有一些内部的数据结构和变量。
uC/OS-III 保护临界段可以通过锁定调度器代替关中断。
因此关中断的时间会非常少。
这样就使uC/OS-III 可以响应一些非常快的中断源了。
4、确定性的:uC/OS-III 的中断响应时间是可确定的,uC/OS-III 提供的大部分服务的执行时间也是可确定的。
5、易移植的:uC/OS-III 可以被移植到大部分的CPU 架构中。
ucosiii操作系统的执行流程
![ucosiii操作系统的执行流程](https://img.taocdn.com/s3/m/41c7ec6030126edb6f1aff00bed5b9f3f80f7270.png)
ucosiii操作系统的执行流程下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。
文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor.I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!深入解析UCOSIII操作系统执行流程UCOSIII,全称为μC/OS-III,是一款实时嵌入式操作系统,广泛应用于微控制器和嵌入式系统中。
清华大学操作系统lab3实验报告范文
![清华大学操作系统lab3实验报告范文](https://img.taocdn.com/s3/m/3aa86a8c8662caaedd3383c4bb4cf7ec4afeb67a.png)
清华大学操作系统lab3实验报告范文实验3:虚拟内存管理练习1:给未被映射的地址映射上物理页ptep=get_pet(mm->dir,addr,1);if(ptep==NULL){//页表项不存在cprintf("get_pteindo_pgfaultfailed\n"); gotofailed;}if(某ptep==0){//物理页不在内存之中//判断是否可以分配新页if(pgdir_alloc_page(mm->pgdir,addr,perm)==NULL){ cprintf("pgdir_alloc_pageindo_pgfaultfailed\n"); gotofailed;}}ele{if(wap_init_ok){tructPage某page=NULL;ret=wap_in(mm,addr,&page);if(ret!=0){//判断页面可否换入cprintf("wap_inindo_pgfaultfailed\n");gotofailed;}//建立映射page_inert(mm->pgdir,page,addr,perm);wap_map_wappable(mm,addr,page,1);}ele{cprintf("nowap_init_okbutptepi%某,failed\n",某ptep); gotofailed;}}ret=0;failed:returnret;}练习2:补充完成基于FIFO算法_fifo_map_wappable(tructmm_truct某mm,uintptr_taddr,tructPage某page,intwap_in){lit_entry_t某head=(lit_entry_t某)mm->m_priv;lit_entry_t某entry=&(page->pra_page_link);aert(entry!=NULL&&head!=NULL);lit_add(head,entry);return0;}pra_page_link用来构造按页的第一次访问时间进行排序的一个链表,这个链表的开始表示第一次访问时间最近的页,链表的尾部表示第一次访问时间最远的页。
操作系统lab3
![操作系统lab3](https://img.taocdn.com/s3/m/07bab700192e45361066f5c5.png)
HUNAN UNIVERSITY 操作系统实验报告题目:LAB3虚拟内存管理目录一、实验目的 (3)二、实验内容 (3)三、练习题 (3)练习0 (3)练习1 (3)练习2 (6)四、实验总结 (9)一、实验目的了解虚拟内存的Page Fault异常处理实现了解页替换算法在操作系统中的实现二、实验内容本次实验是在实验二的基础上,借助于页表机制和实验一中涉及的中断异常处理机制,完成Page Fault异常处理和FIFO页替换算法的实现,结合磁盘提供的缓存空间,从而能够支持虚存管理,提供一个比实际物理内存空间“更大”的虚拟内存空间给系统使用。
这个实验与实际操作系统中的实现比较起来要简单,不过需要了解实验一和实验二的具体实现。
实际操作系统系统中的虚拟内存管理设计与实现是相当复杂的,涉及到与进程管理系统、文件系统等的交叉访问。
如果大家有余力,可以尝试完成扩展练习,实现extended clock 页替换算法。
三、练习练习0:本实验依赖实验1/2。
请把你做的实验1/2的代码填入本实验中代码中有“LAB1”,“LAB2”的注释相应部分。
根据lab1,2即可完成,此处不再赘述练习1:给未被映射的地址映射上物理页(需要编程)完成do_pgfault(mm/vmm.c)函数,给未被映射的地址映射上物理页。
设置访问权限的时候需要参考页面所在VMA 的权限,同时需要注意映射物理页时需要操作内存控制结构所指定的页表,而不是内核的页表。
注意:在LAB2 EXERCISE 1处填写代码。
执行make qemu后,如果通过check_pgfault函数的测试后,会有“check_pgfault() succeeded!”的输出,表示练习1基本正确。
请在实验报告中简要说明你的设计实现过程。
本实验要求完成do_pgfault函数,作用给未被映射的地址映射上物理页。
具体而言,当启动分页机制以后,如果一条指令或数据的虚拟地址所对应的物理页框不在内存中或者访问的类型有错误(比如写一个只读页或用户态程序访问内核态的数据等),就会发生页错误异常。
LAB3实验报告
![LAB3实验报告](https://img.taocdn.com/s3/m/1f92b745c850ad02de804147.png)
课程实验报告课程名称:计算机组成与原理实验项目名称:LAB3专业班级:智能2班*名:***学号:***************师:**完成时间:2015 年 5 月9 日计算机科学与工程系【实验目的】理解汇编语言,学会使用调试器。
【实验原理】二进制炸弹是作为一个目标代码文件提供给学生们的程序,运行时,它提示用户输入6个不同的字符串。
如果其中任何一个不正确,炸弹就会“爆炸”:打印出一条错误信息。
学生通过反汇编和逆向工程来确定是哪六个字符串,从而解除他们各自炸弹的雷管。
【实验过程】一、准备过程1.先把LAB3文件拷贝到VMware中的ubuntu系统里,然后解压获得3文件,分别为bomb、bomb.c和README-bomblab.txt以及实现基本内容与要求.txt,首先查看实现基本内容与要求与README-bomblab.txt,大致理解意思后,打开.c文件,进去后发现代码不完整,(由于自己C语言能力不强,所以直接把文件拷贝到windows里,用VS2012编译一下,发现很多错误,从而确认代码不完整),从主观上来想,如果代码完整了,那么还需要给其他文件吗?所以,这个.c文件必定是一个不完整的文件,只能用来作为参考。
2.既然不能够直接从.c文件看出问题,那么就需要从bomb程序里找,如何找?貌似也就只能选择反编译了,然后再通过反编译的代码与给出来的.c源代码相结合,来进行拆炸弹。
注:反汇编命令是objdump –d XXX二、开始实验1.用ctrl+alt+t打开终端命令,由于三个文件的位置在桌面/LAB3,所以需要cd Dsktop/LAB3/来进入到相应的目录2.然后用反编译命令objdump -d bomb > out.txt对bomb进行反编译,编译出来的文件存到新建的文件out.txt3.打开out.txt文件,出现了大量汇编代码。
第一关找到第一关<phase_1>的代码,如下:首先看从哪里会调用爆炸的函数,显然,我们知道<explode_bomb>这个函数就是调用爆炸函数,test %eax,%eax与je 8048f83 <phase_1+0x22> 表示,当%eax=0的时候,调用<phase_1+0x22>,也就是不调用炸弹爆炸的函数,所以在调用<strings_not_equal>函数的时候,必须返回%eax为0,而这个函数的作用就是判断字符串是否相等。
uCosIII学习
![uCosIII学习](https://img.taocdn.com/s3/m/4b4f36f8b14e852458fb57cc.png)
uCosIII 学习本人前言:很久没有练习英语了,本想发点时间在工作之余,翻译一下μC/OS III用户手册,发现还是有点吃力,于是乎,参见网络上的嘉兴学院的屈环宇同学的译本,谢谢!前言做为Micrium公司推出的第三代操作系统,μC/OS III 支持现代的实时内核所期待的大部分功能;μC/OS III是一个可裁剪、可固化、基于优先级的实时内核,支持例如资源管理、同步、任务间的通信等等。
同时μC/OS III也具备一些很有特色的功能,是很多的其他的实时内核所不具备的,比如完备的实际测量性能、直接发送信号或消息到任务、任何可同时等待多个内核对象等。
与第二代μC/OS II相比,μC/OS III更加优秀,μC/OS III中删除或更新了μC/OS II中很少使用的一些功能;添加了更高效的功能和服务,比如时间片轮转调度(round robin)等,μC/OS II最多支持64个任务,而μC/OS III在理论上任务数量没有限第一章介绍实时系统软实时系统和硬实时系统的区别在于一旦没有在规定的时间内完成任务所导致后果的严重性。
超过时限后所得到的结果即使正确也可能是毫无作用的。
硬实时系统中,运算超时是不允许发生的。
在很多情况下,超时会导致巨大的灾难,会威胁人们的生命安全。
但是在软实时系统中,超时不会导致严重后果。
前后台系统简单的小型系统设计一般是基于前后台的或者无限循环的系统。
包含一个无限循环的模块实现需要的操作(后台)。
中断处理程序实现异步事件(前台)。
前台也叫做中断级,后台也叫作任务级。
多数高产量低成本微控制器的应用软件(例如微波炉,电话玩具等)都是基于前后台系统的。
实时内核实时内核是一个能管理MPU、MCU、DSP时间和资源的软件。
实时内核的应用包括迅速地响应,可靠地完成工作的各个部分。
ucore文件系统详解
![ucore文件系统详解](https://img.taocdn.com/s3/m/67c8d4c4185f312b3169a45177232f60ddcce7b7.png)
ucore⽂件系统详解最近⼀直在mooc上学习清华⼤学的操作系统课程,也算是复习下基本概念和原理,为接下来的找⼯作做准备。
每次深⼊底层源码都让我深感操作系统实现的琐碎,即使像ucore这样简单的kernel也让我烦躁不已,⽂件系统相⽐于中断⼦系统、调度⼦系统、进程管理⼦系统等等,要复杂很多,因此被称为⽂件系统⽽不是⽂件⼦系统。
参看⽹络上的资料有时会增加我的困惑,很多⼈只是简单转载,很多细节描述的很模糊,实验环境也各不相同,最终很难深⼊理解⽂件系统的本质,参考源码我觉得有点像从三维世界进⼊到⼆维世界,⼀切变得清晰但是却需要消耗更多精⼒,我觉得这样做是值得的,因为如果不能深⼊⽽只是泛泛的理解,对于操作系统这样偏向于⼯程学的东西来说意义不⼤,本⽂的研究内容主要是根据清华⼤学陈渝副教授、向勇副教授在mooc上所讲,以及实验参考书的内容和我⾃⼰在系统上打的log验证过的,如果有读者发现错误还请批评指正。
本篇博客希望尽可能照顾到初学者,但是有些简单原理默认读者已经掌握,很多细节不会展开叙述,读者请⾃⾏Google或者参看Intel Development Manual,实验⽤的源码来⾃于清华⼤学教学操作系统,读者可在github上搜索ucore_os_lab。
附上ucore的实验参考书.综述最初实现⽂件系统是为了实现对磁盘数据的⾼效管理,使得⽤户可以⾼效、快速的读取磁盘上的数据内容。
其实我个⼈觉得⽂件系统就是操作系统内核和外设之间的⼀套输⼊输出协议,我们所采⽤的算法和索引结点的建⽴⽅式都是为了根据实际应⽤情况所设计的⼀套⾼效的协议。
在实现的过程中,我们还要将⽂件系统进⾏分层抽象,也就是实现我们的虚拟⽂件系统,虚拟⽂件系统有对上和对下两个⽅⾯,对上是为了向上层应⽤提供⼀套通⽤的访问接⼝,可以⽤相同的⽅式去访问磁盘上的⽂件(包括⽬录,后⾯会介绍)和外设;对下兼容不同的⽂件系统和外设。
虚拟⽂件系统的层次和依赖关系如下图所⽰:对照上⾯的层次我们再⼤致介绍⼀下⽂件系统的访问处理过程,加深对⽂件系统的总体理解。
嵌入式实时操作系统uCOS-III
![嵌入式实时操作系统uCOS-III](https://img.taocdn.com/s3/m/8377c5725acfa1c7aa00cc42.png)
目录第一部分:μC/OS-III 实时内核μC/OS-III的演变—Jack Ganssle前言第1章概述1-1前后台系统1-2实时内核1-3RTOS(实时操作系统)1-4μC/OS-III1-5μC/OS,μC/OS-II,μC/OS-III特性比较1-6关于本书1-7μC/Probe 调试软件工具1-8本书的常用约定1-9各章内容第2章目录和文件2-1 应用代码2-2 CPU2-3 板级支持包(BSP)2-4 μC/OS-III,与CPU无关的源代码2-5 μC/OS-III,与CPU相关的源代码2-6 μC/CPU,与CPU相关的源代码2-7 μC/LIB,可移植的库函数2-8 小结第3章初识μC/OS-III3-1 单任务应用程序3-2 有内核对象参与的多任务应用程序第4章临界段代码4-1 关中断4-1-1 测量中断关闭时间4-2 给调度器上锁4-2-1 测量调度器锁定时间4-3 μC/OS-III的某些功能会导致临界段代码长度增加4-4 小结第5章任务管理5-1 任务优先级的分配5-2 栈空间大小的确定5-3 任务栈溢出检测5-4 任务管理函数5-5 任务管理的内部原理5-5-1 任务状态5-5-2 任务控制块TCB5-6 系统内部任务5-6-1 空闲任务(OS_IdleTask(),os_core.c)5-6-2 时钟节拍任务(OS_TickTask(), os_tick.c)5-6-3 统计任务(OS_StatTask(),os_stat.c)5-6-4 定时任务(OS_TmrTask(),os_tmr.c)5-6-5 中断服务管理任务(OS_IntQTask(),os_int.c)5-7小结第6章任务就绪表6-1 优先级6-2 就绪任务列表6-3 向就绪任务列表中增加任务6-4小结第7章任务调度7-1 可剥夺型调度7-2 调度点7-3 时间片轮转调度7-4 调度的实现细节7-4-1 OSSched()7-4-2 OSIntExit()7-4-3 OS_SchedRoundRobin()7-5 小结第8章任务切换8-1 OSCtxSw()8-2 OSIntCtxSw()8-3小结第9章中断管理9-1 CPU的中断处理9-2 典型的μC/OS-III中断服务程序9-3 无需内核参与的中断服务程序9-4 多中断优先级的处理器9-5 所有中断源共用中断服务程序9-6 每个中断源都有专用中断服务程序9-7 直接发布和延时发布9-7-1 直接发布9-7-2 延迟发布9-8 直接发布模式和延迟发布模式的对比9-9 时钟节拍(也称为系统节拍)9-10小结第10章任务挂起表10-1 小结第11章时间管理11-1 OSTimeDly()11-2 OSTimeDlyHMSM()11-3 OSTimeDlyResume()11-4 OSTimeSet() 和OSTimeGet()11-5 OSTimeTick()11-6 小结第12章定时器管理12-1 单次定时器12-2 周期定时器(无初始延迟)12-3 周期定时器(有初始延迟)12-4 定时器管理内部机制12-4-1 定时器管理内部机制——定时器状态12-4-2 定时器管理内部机制——OS_TMR12-4-3 定时器管理内部机制——定时器任务12-4-4 定时器管理内部机制——定时器列表12-5 总结第13章资源管理13-1 关中断/开中断13-2 给调度器上锁/开锁13-3 信号量13-3-1 二进制信号量13-3-2 计数型信号量13-3-3 使用信号量的注意事项13-3-4 (用来共享资源的)信号量内部结构13-3-5 优先级反转13-4 互斥型信号量(MUTEX)13-4-1 互斥型信号量内部结构13-5 何时可以用普通信号量替代互斥型信号量13-6 死锁(或称抱死)13-7 小结第14章任务同步14-1 信号量14-1-1 单向同步14-1-2 信用记录14-1-3 多个任务等待同一个信号量14-1-4 信号量的内部结构(以同步为目的)14-2 任务信号量14-2-1 等待任务信号量14-2-2 发布任务信号量14-2-3 双向同步14-3 事件标志组14-3-1 使用事件标志14-3-2 事件标志的内部结构14-4 与多任务同步14-5 小结第15章消息传递15-1 消息15-2 消息队列15-3 任务内建的消息队列15-4 双向同步15-5 流量控制(flow control)15-6 保持数据的可见性15-7 使用消息队列15-8 客户端和服务器15-9 消息队列内部的细节15-10 小结第16 章同时等待多个内核对象16-1 小结第17章存储管理17-1 创建存储分区17-2 从分区中获得存储块17-3 将存储块归还到分区中17-4 使用存储分区17-5 小结第18章移植µC/OS-Ⅲ18-1 约定18-2 μC/CPU18-2-1 CPU_BSP.H18-2-2 CPU_DEF.H18-2-3 CPU_CFG.H18-2-4 CPU_CORE.C18-2-5 CPU_CORE.H18-2-6 CPU.H18-2-7 CPU_C.C18-2-8 CPU_A.ASM18-3 μC/OS-III移植18-3-1 OS_CPU.H18-3-2 OS_CPU_C.C18-3-3 OS_CPU_A.ASM18-3-4 OS_CPU_A.INC18-4 板级支持包(BSP)18-4-1 BSP.C和BSP.H18-4-2 BSP_INT.C和BSP_INT.H18-5 移植的测试18-5-1 创建一个简单的测试工程18-5-2 验证任务级任务切换18-5-3 验证中断级任务切换18-6 小结第19章程序运行时的各类统计信息19-1程序运行时的总体统计19-2 任务运行时的统计19-3 程序运行时和内核对象相关的统计信息19-4 OS_DBG.C –统计19-5 OS_CFG_APP. C –统计19-6 小结附录A μC/OS-III API参考手册A-1 任务管理A-2 时间管理A-3 互斥型信号量——资源管理A-4 事件标志组——同步A-5 信号量——同步A-6 任务信号量——同步A-7 消息队列——消息传递A-8 任务消息队列——消息传递A-9 等待多个对象A-10 定时器A-11 固定大小的存储分区——存储管理A-12 OSCtxSw()A-13 OSFlagCreate()A-14 OSFlagDel()A-15 OSFlagPend()A-16 OSFlagPendAbort()A-17 OSFlagPendGetFlagsRdy()A-18 OSFlagPost()A-19 OSIdleTaskHook()A-20 OSInit()A-21 OSInitHook()A-22 OSIntCtxSw()A-23 OSIntEnter()A-24 OSIntExit()A-25 OSMemCreate()A-26 OSMemGet()A-27 OSMemPut()A-28 OSMutexCreate()A-29 OSMutexDel()A-30 OSMutexPend()A-31 OSMutexPendAbort()A-32 OSMutexPost()A-33 OSPendMulti()A-34 OSQCreate()A-35 OSQDel()A-36 OSQFlush()A-36 OSQPend()A-38 OSQPendAbort()A-32 OSQPost()A-41 OSSched()A-42 OSSchedLock()A-43 OSSchedRoundRobinCfg() A-44 OSSchedRoundRobinYield() A-45 OSSchedUnlock()A-46 OSSemCreate()A-47 OSSemDel()A-48 OSSemPend()A-49 OSSemPendAbort()A-50 OSSemPost()A-51 OSSemSet()A-52 OSStart()A-53 OSStartHighRdy()A-54 OSStatReset()A-55 OSStatTaskCPUUsageInit() A-56 OSStatTaskHook()A-57 OSTaskChangePrio()A-58 OSTaskCreate()A-59 OSTaskCreateHook()A-60 OSTaskDel()A-61 OSTaskDelHook()A-62 OSTaskQFlush()A-63 OSTaskQPend()A-64 OSTaskQPendAbort()A-65 OSTaskQPost()A-66 OSTaskRegGet()A-67 OSTaskRegSet()A-68 OSTaskReturnHook()A-69 OSTaskResume()A-70 OSTaskSemPend()A-71 OSTaskSemPendAbort()A-72 OSTaskSemPost()A-73 OSTaskSemSet()74 OSStatTaskHook()A-75 OSTaskStkChk()A-76 OSTaskStkInit()A-77 OSTaskSuspend()A-78 OSTaskSwHook()A-79 OSTaskTimeQuantaSet()A-80 OSTickISR()A-81 OSTimeDly()A-82 OSTimeDlyHMSM()A-83 OSTimeDlyResume()A-84 OSTimeGet()A-85 OSTimeSet()A-86 OSTimeTick()A-87 OSTimeTickHook()A-88 OSTmrCreate()A-89 OSTmrDel()A-90 OSTmrRemainGet()A-91 OSTmrStart()A-92 OSTmrStateGet()A-93 OSTmrStop()A-94 OSVersion()附录B μC/OS-III配置手册B-1 μC/OS-III的功能(os_cfg.h)B-2μC/OS-III的数据类型(os_type.h)B-3 μC/OS-III的堆栈、池和其他数据类型(os_cfg_app.h)附录C从μC/OS-II 迁移到μC/OS-IIIC-1源文件名称和内容的差异C-2编程约定的变化C-3变量名称的变化C-4 API的变化C-4-1事件标志C-4-2消息邮箱C-4-3存储管理C-4-4互斥型信号量C-4-5消息队列C-4-6信号量C-4-7任务管理C-4-8时间管理C-4-9定时器管理C-4-10其他C-4-11介入函数与系统移植附录D MISRA-C:2004和μC/OS-III D-1 MISRA-C:2004,规则8.5 (强制)D-2 MISRA-C:2004,规则8.12(强制)D-3 MISRA-C:2004,规则14.7 (强制)D-4 MISRA-C:2004,规则15.2 (强制)D-5 MISRA-C:2004,规则17.4 (强制)附录E 参考文献附录F μC /OS-III许可政策致中国读者这本书是很多人多年辛勤劳动的结晶,讲述的是一个最早于1992年发布的实时内核的第三代。
操作系统实验-ucore-lab1
![操作系统实验-ucore-lab1](https://img.taocdn.com/s3/m/fd74a59f6aec0975f46527d3240c844769eaa010.png)
一、通make生成执行文件的过程a)操作系统镜像文件ucore.img是如何一步一步生成的在编译时使用make V=,相当于设置一个标记,使得把make编译执行的过程全部展示出来。
首先,调用了GCC,把一些C的源代码编译成.O的目标文件。
然后,调用了ld,把这些目标文件准换成一个可执行程序,比如下面示例,转换成为了bootloader的一个执行程序bootblock.out。
最后,调用了dd,把bootloader、bootblock和kernel放到虚拟的硬盘uCore.img 里面。
b)硬盘的主引导扇区的特征是什么在sign.c中,先申请了一个512字节的空间buf,然后将buf初始化为全0,再将主引导程序写入这个空间,最后,在buf的最后两个字节写入55AA。
所以硬盘的主引导扇区的特征是主引导扇区的512个字节的最后两个字节是55AA。
二、使用qemu执行并调试lab1中的软件a)从启动开始,单步跟踪BIOS的执行实验远程调用的方法,启动qemu,并让它进入-S状态。
开启另外一个终端,执行gdb命令,绑定端口1234。
在QEMU窗口中使用x/10i $pc 查看最近10条指令的反汇编内容。
在gdb 中使用si命令执行单步,显示位置。
可以看到一启动,就处于0xfffffff0的位置,第一条指令是个长跳转指令。
b)在初始化位置0x7c00设置实地址断点,测试断点正常输入b *0x7c00设置断点,输入c 执行到断点。
输入x/10i $pc 查看最近10条指令的反汇编内容,可以看到qemu执行到断点0x7c00。
断点工作正常。
再次输入c执行,qemu继续工作。
得到结论,断点工作正常。
c)从0x7c00开始跟踪代码运行,将单步跟踪反汇编得到的代码与bootasm.S和bootblock.asm进行比较经过比较发现:gdb得到的反汇编代码与bootasm.S和bootblock.asm中的代码基本相一致。
Ucore-操作系统实验六
![Ucore-操作系统实验六](https://img.taocdn.com/s3/m/b9560415bc64783e0912a21614791711cd797961.png)
Ucore-操作系统实验六
Ucore-操作系统实验六
1、实验背景
1.1 Ucore操作系统简介
1.2 进程调度算法简介
2、实验目的
2.1 理解进程调度算法的概念和原理
2.2 学习设计和实现进程调度算法
2.3 掌握在Ucore操作系统中实现进程调度算法的方法
3、实验要求
3.1 设计一个合适的进程调度算法
3.2 修改Ucore操作系统的源代码,实现设计的进程调度算法
3.3 运行并测试实现的进程调度算法,确保其功能正确性
4、实验内容
4.1 理解Ucore操作系统的进程管理模块
4.2 设计进程调度算法
4.3 修改进程管理模块的源代码,实现进程调度算法
4.4 编译并运行修改后的Ucore操作系统,进行测试和验证
5、实验步骤
5.1 分析Ucore操作系统的进程管理模块,了解其结构和功能
5.2 设计进程调度算法,考虑算法的可行性和性能
5.3 基于设计的算法,修改进程管理模块的源代码,实现进程调度算法
5.4 编译并运行修改后的Ucore操作系统,进行测试和验证
6、实验结果分析
6.1 比较不同进程调度算法在Ucore操作系统中的性能差异
6.2 分析实验结果,总结优缺点
附件:
- Ucore操作系统源代码:zip
法律名词及注释:
1、版权:指对原创作品(如文学、艺术、音乐、软件等)的独特权利保护。
著作权法是一种保护版权的法律。
2、开源:指软件或硬件的设计和制造过程中,公开的原始设计数据、设计文档、设计过程以及产品源代码等。
3、许可证:是指著作权人授予他人使用其作品或知识产权的权利的行为。
操作系统lab3
![操作系统lab3](https://img.taocdn.com/s3/m/e6d1267b8e9951e79b8927aa.png)
xxxx大学《操作系统》课程实验报告实验题目:__________进程间通信______________ 姓名:__ __xx_____ 学号:__xxxxxxxxxxxxx ___班级: __ xxxx_______指导教师: xxx{buf.sem_num = 0;buf.sem_op = -1;buf.sem_flg = SEM_UNDO;if (semop(sem_id, &buf, 1) == -1){perror("Down failed!/n");return 0;}return 1;}int up(int sem_id){buf.sem_num = 0;buf.sem_op = 1;buf.sem_flg = SEM_UNDO;if (semop(sem_id, &buf, 1) == -1){perror("Up failed!/n");return 0;}return 1;}void main(){union semun arg;pid_t producer1, producer2;//两个生产者pid_t consumer1, consumer2, consumer3;//三个消费者int mutex;//互斥信号量int full;int empty;char *buffer;// 共享内存buffer = (char*) mmap(NULL, sizeof(char) * MAX_PRODUCTS,PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);int i;for (i = 0; i < MAX_PRODUCTS; i++)buffer[i] = '\0';// 创建信号量mutex = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);full = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);empty = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);arg.val = 1;if (semctl(mutex, 0, SETVAL, arg) == -1){perror("set the mutex error\n");return;}arg.val = 0;if (semctl(full, 0, SETVAL, arg) == -1){perror("set the full error\n");return;}arg.val = MAX_PRODUCTS;if (semctl(empty, 0, SETVAL, arg) == -1){perror("set the empty error/n");return;}if ((producer1 = fork()) == 0){// 写入大写字母while (1){down(empty);down(mutex);srand(time(NULL));int offset = rand() % 26;char item = 'A' + offset;int j;for (j = 0; j < MAX_PRODUCTS; j++){if (buffer[j] == '\0'){buffer[j] = item;printf("Producer A insert letter: %c\n", item);break;}}up(mutex);up(full);sleep(1);}}else if ((producer2 = fork()) == 0){// 写入小写字母while (1){down(empty);down(mutex);srand(time(NULL));int offset = rand() % 26;char item = 'a' + offset;int j;for (j = 0; j < MAX_PRODUCTS; j++){if (buffer[j] == '\0'){buffer[j] = item;printf("Producer B insert letter: %c\n", item);break;}}up(mutex);up(full);sleep(1);}}else if ((consumer1 = fork()) == 0){// 消费大写字母while (1){down(full);down(mutex);char item;int j;for (j = 0; j < MAX_PRODUCTS; j++){if (buffer[j] >= 'A' && buffer[j] <= 'Z'){item = buffer[j];buffer[j] = '\0';break;}}printf("Consumer A removes letter: %c\n", item); up(mutex);up(empty);sleep(2);}}else if ((consumer2 = fork()) == 0){// 消费小写字母while (1){down(full);down(mutex);char item;int j;for (j = 0; j < MAX_PRODUCTS; j++){if (buffer[j] >= 'a' && buffer[j] <= 'z'){item = buffer[j];buffer[j] = '\0';break;}}printf("Consumer B removes letter: %c\n", item); up(mutex);up(empty);sleep(2);}}else if ((consumer3 = fork()) == 0){// 大小写字母while (1){down(full);down(mutex);char item;int j;for (j = 0; j < MAX_PRODUCTS; j++){if (buffer[j] != '\0'){item = buffer[j];buffer[j] = '\0';break;}}printf("Consumer C removes letter: %c\n", item); up(mutex);up(empty);sleep(2);}}else{// 主进程while (1){int j;printf("Buffer: ");for (j = 0; j < MAX_PRODUCTS; j++){printf("%c ", buffer[j]);}printf(" \n");sleep(10);}}}。
ucore操作系统学习(二)ucorelab2物理内存管理分析
![ucore操作系统学习(二)ucorelab2物理内存管理分析](https://img.taocdn.com/s3/m/e7a95efa6394dd88d0d233d4b14e852458fb39dd.png)
ucore操作系统学习(⼆)ucorelab2物理内存管理分析⼀、lab2物理内存管理介绍 操作系统的⼀个主要职责是管理硬件资源,并向应⽤程序提供具有良好抽象的接⼝来使⽤这些资源。
⽽内存作为重要的计算机硬件资源,也必然需要被操作系统统⼀的管理。
最初没有操作系统的情况下,不同的程序通常直接编写物理地址相关的指令。
在多道并发程序的运⾏环境下,这会造成不同程序间由于物理地址的访问冲突,造成数据的相互覆盖,进⽽出错、崩溃。
现代的操作系统在管理内存时,希望达到两个基本⽬标:地址保护和地址独⽴。
地址保护指的是⼀个程序不能随意的访问另⼀个程序的空间,⽽地址独⽴指的是程序指令给出的内存寻址命令是与最终的物理地址⽆关的。
在实现这两个⽬标后,便能够为多道并发程序运⾏时的物理内存访问的隔离提供⽀持。
每个程序在编译、链接后产⽣的最终机器代码都可以使⽤完整的地址空间(虚拟地址),⽽不需要考虑其它的程序的存在。
ucore通过两个连续的实验迭代,lab2和lab3分别实现了物理内存管理和虚拟内存管理(利⽤磁盘缓存⾮⼯作集内存,扩展逻辑上的内存空间)。
ucore的每个实验都是建⽴在前⼀个实验迭代的基础上的,要想更好的理解lab2,最好先理解之前lab1中的内容()。
lab2在lab1平坦模型段机制的基础上,开启了80386的分页机制,并建⽴了内核页表;同时通过硬件中断探测出了当前内存硬件的布局,并以此为依据根据可⽤的内存建⽴了⼀个物理内存管理框架,通过指定某种分配算法,负责处理所有的物理内存页分配与释放的请求。
lab2的代码结构和执⾏流程与lab1差别不⼤,其主要新增了以下功能: 1. bootmain.S中的物理内存探测 2. 在新增的entry.S内核⼊⼝程序中开启了80386页机制 3. kern_init内核总控函数中通过pmm_init函数进⾏整个物理内存管理器的构建初始化⼆、lab2实验细节分析2.1 物理内存布局探测 为了进⾏物理内存的管理,操作系统必须先探测出当前硬件环境下内存的布局,了解具体哪些物理内存空间是可⽤的。
lab3 介绍
![lab3 介绍](https://img.taocdn.com/s3/m/5deeab08763231126edb1125.png)
引言
新的debug命令 内联汇编简介 重要文件说明 重要数据结构 Struct task_struct v.s. struct Env
重要文件说明
env.c:env的初始化、创建、释放等 trap.c:中断处理相关,包含dispatch trapentry.S:中断入口的生成及中断相关的栈 操作 syscall.c:系统调用相关 *.h:……
图示
Part B
系统调用原理与简单流程
系统调用
系统调用通过软件中断实现
int 0x30
需要在idt中进行相应的设置 传递系统调用号:EAX ;5个参数:EDX, ECX, EBX, EDI, ESI 返回值:EAX
设置idt
参数传递:
思考:为什么用寄存器传参?
系统调用—流程实例1
user/hello.c umain() …… lib/printf.c printf() …… …… …… lib/syscall.c sys_cputs() ……
structenvgccgcc支持在cc代码中嵌入汇编代码这些汇编代码被称作gcc内联汇编gccinlineassembly可以使用内联汇编表达一些cc语言中无法表达的指令允许我们直接在cc代码中使用汇编语言编写简洁高效的代码gccasm或asm用来声明一个内联汇编表达式所以任何一个内联汇编表达式都是以它开头的是必不可少的asmpushleaxntmovl0eaxntpopleax
Lab3 introduction
2010-5
Lab3任务清单
用户环境的建立 实现中断处理
实现系统调用
概要
引言 Part A Part B
引言
新的debug命令 内联汇编简介 重要文件说明 重要数据结构 Struct task_struct v.s. struct Env
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实验报告题目:虚拟内存管理目录一、内容 (2)二、目的 (3)三、实验流程 (3)四、实验环境与结果分析 (3)五、实验体会和思考题 (10)一、内容本次实验是在实验二的基础上,借助于页表机制和实验一中涉及的中断异常处理机制,完成Page Fault异常处理和FIFO页替换算法的实现,结合磁盘提供的缓存空间,从而能够支持虚存管理,提供一个比实际物理内存空间“更大”的虚拟内存空间给系统使用。
这个实验与实际操作系统中的实现比较起来要简单,不过需要了解实验一和实验二的具体实现。
实际操作系统系统中的虚拟内存管理设计与实现是相当复杂的,涉及到与进程管理系统、文件系统等的交叉访问。
如果大家有余力,可以尝试完成扩展练习,实现extended clock页替换算法。
练习1:给未被映射的地址映射上物理页(需要编程)完成do_pgfault(mm/vmm.c)函数,给未被映射的地址映射上物理页。
设置访问权限的时候需要参考页面所在VMA的权限,同时需要注意映射物理页时需要操作内存控制结构所指定的页表,而不是内核的页表。
注意:在LAB2EXERCISE1处填写代码。
执行make qemu后,如果通过check_pgfault函数的测试后,会有“check_pgfault() succeeded!”的输出,表示练习1基本正确。
请在实验报告中简要说明你的设计实现过程。
请回答如下问题:请描述页目录项(Pag Director Entry)和页表(Page Table Entry)中组成部分对ucore实现页替换算法的潜在用处。
如果ucore的缺页服务例程在执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?练习2:补充完成基于FIFO的页面替换算法(需要编程)完成vmm.c中的do_pgfault函数,并且在实现FIFO算法的swap_fifo.c中完成map_swappable和swap_out_vistim函数。
通过对swap的测试。
注意:在LAB2EXERCISE 2处填写代码。
执行make qemu后,如果通过check_swap函数的测试后,会有“check_swap()succeeded!”的输出,表示练习2基本正确。
请在实验报告中简要说明你的设计实现过程。
请在实验报告中回答如下问题:如果要在ucore上实现"extended c lock页替换算法"请给你的设计方案,现有的swap_manager框架是否足以支持在ucore 中实现此算法?如果是,请给你的设计方案。
如果不是,请给出你的新的扩展和基此扩展的设计方案。
并需要回答如下问题需要被换出的页的特征是什么?在ucore中如何判断具有这样特征的页?何时进行换入和换出操作?二、目的了解虚拟内存的Page Fault异常处理实现了解页替换算法在操作系统中的实现三、实验流程本次实验主要完成ucore内核对虚拟内存的管理工作。
其总体设计思路还是比较简单,即首先完成初始化虚拟内存管理机制,即需要设置好哪些页需要放在物理内存中,哪些页不需要放在物理内存中,而是可被换出到硬盘上,并涉及完善建立页表映射、页访问异常处理操作等函数实现。
然后就执行一组访存测试,看看我们建立的页表项是否能够正确完成虚实地址映射,是否正确描述了虚拟内存页在物理内存中还是在硬盘上,是否能够正确把虚拟内存页在物理内存和硬盘之间进行传递,是否正确实现了页面替换算法等。
lab3的总体执行流程如下。
首先是初始化过程。
参考ucore总控函数init的代码,可以看到在调用完成虚拟内存初始化的vmm_init 函数之前,需要首先调用pmm_init函数完成物理内存的管理,这也是我们lab2已经完成的内容。
接着是执行中断和异常相关的初始化工作,即调用pic_init函数和idt_init函数等,这些工作与lab1的中断异常初始化工作的内容是相同的。
在调用完idt_init函数之后,将进一步调用三个lab3中才有的新函数vmm_init、ide_init和swap_init。
这三个函数设计了本次实验中的两个练习。
第一个函数vmm_init是检查我们的练习1是否正确实现了。
为了表述不在物理内存中的“合法”虚拟页,需要有数据结构来描述这样的页,为此ucore建立了mm_struct 和vma_struct数据结构(接下来的小节中有进一步详细描述),假定我们已经描述好了这样的“合法”虚拟页,当ucore访问这些“合法”虚拟页时,会由于没有虚实地址映射而产生页访问异常。
如果我们正确实现了练习1,则do_pgfault函数会申请一个空闲物理页,并建立好虚实映射关系,从而使得这样的“合法”虚拟页有实际的物理页帧对应。
这样练习1就算完成了。
ide_init和swap_init是为练习2准备的。
由于页面置换算法的实现存在对硬盘数据块的读写,所以ide_init 就是完成对用于页换入换出的硬盘(简称swap硬盘)的初始化工作。
完成ide_init函数后,ucore就可以对这个swap硬盘进行读写操作了。
swap_init函数首先建立swap_manager,swap_manager是完成页面替换过程的主要功能模块,其中包含了页面置换算法的实现(具体内容可参考5小节)。
然后会进一步调用执行check_swap函数在内核中分配一些页,模拟对这些页的访问,这会产生页访问异常。
如果我们正确实现了练习2,就可通过do_pgfault来调用swap_map_swappable函数来查询这些页的访问情况并间接调用实现页面置换算法的相关函数,把“不常用”的页换出到磁盘上。
四、实验过程与结果分析(1)给未被映射的地址映射上物理页(需要编程)具体而言,当启动分页机制以后,如果一条指令或数据的虚拟地址所对应的物理页框不在内存中或者访问的类型有错误(比如写一个只读页或用户态程序访问内核态的数据等),就会发生页错误异常。
产生页面异常的原因主要有:1、目标页面不存在(页表项全为0,即该线性地址与物理地址尚未建立映射或者已经撤销);2、相应的物理页面不在内存中(页表项非空,但Present标志位=0,比如在swap分区或磁盘文件上)3、访问权限不符合(此时页表项P标志=1,比如企图写只读页面).do_pgfault()函数从CR2寄存器中获取页错误异常的虚拟地址,根据error code来查找这个虚拟地址是否在某一个VMA的地址范围内,那么就给它分配一个物理页。
struct vma_struct {// the set of vma using the same PDTstruct mm_struct *vm_mm;uintptr_t vm_start; // start addr of vmauintptr_t vm_end; // end addr of vmauint32_t vm_flags; // flags of vma//linear list link which sorted by start addr of vmalist_entry_t list_link;};vm_start和vm_end描述的是一个合理的地址空间范围(即严格确保 vm_start < vm_end 的关系);list_link是一个双向链表,按照从小到大的顺序把一系列用vma_struct表示的虚拟内存空间链接起来,并且还要求这些链起来的vma_struct应该是不相交的,即vma之间的地址空间无交集;vm_flags表示了这个虚拟内存空间的属性,包括#define VM_READ 0x00000001 //只读#define VM_WRITE 0x00000002 //可读写#define VM_EXEC 0x00000004 //可执行vm_mm是一个指针,指向一个比vma_struct更高的抽象层次的数据结构mm_struct而这mm_struct包含所有虚拟内存空间的共同属性,如下:struct mm_struct {// linear list link which sorted by start addr of vmalist_entry_t mmap_list;// current accessed vma, used for speed purposestruct vma_struct *mmap_cache;pde_t *pgdir; // the PDT of these vmaint map_count; // the count of these vmavoid *sm_priv; // the private data for swap manager};mmap_list是双向链表头,链接了所有属于同一页目录表的虚拟内存空间mmap_cache是指向当前正在使用的虚拟内存空间pgdir所指向的就是 mm_struct数据结构所维护的页表map_count记录mmap_list里面链接的vma_struct的个数sm_priv指向用来链接记录页访问情况的链表头最后实现if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) { //目标页面不存在,失败cprintf("get_pte in do_pgfault failed\n");goto failed;}if (*ptep == 0) { //权限不够,也是失败!if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) {cprintf("pgdir_alloc_page in do_pgfault failed\n");goto failed;}}else { //页表项非空,可以尝试换入页面if(swap_init_ok) {struct Page *page=NULL;//根据mm结构和addr地址,尝试将硬盘中的内容换入至page中if ((ret = swap_in(mm, addr, &page)) != 0) {cprintf("swap_in in do_pgfault failed\n");goto failed;}page_insert(mm->pgdir, page, addr, perm);//建立虚拟地址和物理地址之间的对应关系swap_map_swappable(mm, addr, page, 1);//将此页面设置为可交换的 page->pra_vaddr = addr;}else {cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep);goto failed;}}请描述页目录项(Pag Director Entry)和页表(Page Table Entry)中组成部分对ucore 实现页替换算法的潜在用处。