JOS lab4 用户程序分析

faultread.c faultdie.c:

这两个用户程序一起分析

左右两个用户程序,都试图对非法地址写入数据,但是左边的就会导致 page fault ,触发的是内核trap

而后边的就会进入打印trap frame,导致系统挂掉,而右边的不会,右边的由于有用户空间的处理机制,

还是建议自己一步步跟踪去看.

faultalloc.c faultallocbad.c :

这里还是用户空间直接调用系统调用处理函数,还是通过用户程序触发page fault 之后再用用户空间page fault handler处理异常.和之前的faultread.c faultdie.c是一个原理,换汤不换药啊哈哈...

faultbadhandler.c :

这里由于设置的把 0xDeadBeef当做handler的地址,是错误的,这是个非法地址.

我特意注释了,只要按照我注释的来运行,就可以处理好这里的赋值操作引起的page fault.

同样handler设置不正确的还有

faultevilhandler.c:

这里的问题在于handler的地址 0xF0100020是个内核高地址.非法的,我们设置的用户态page fault handler必须处于用户空间内.不能放在内核地址.

faultnostack.c:

观察各种配置好的 user space page fault handler 处理机制,都有异常栈的设置,但是这里没有,于是,挂.

要知道所有的user space page fault handler都是运行在exception stack里面的,而不是normal user stack.也不是kernel stack.

而且这里仅仅只配置了内核向上衔接处理用户page fault的借口 _pgfault_upcall.连handler都没写.

forktree.c:

这个在lab4实验报告里面有

pingpong.c:

这里很有意思.fork出一个子进程,然后由父进程发送一个值给pid为who的进程(即子进程,这里注意,父进程和子进程的who变量值不同就好.父进程的who是子进程的pid,子进程的who是0).

然后两个进程都落入到while循环,首先子进程接受信息,接受到了就打印这个信息 i.

i++,接着对于子进程来说who值已经改变了,在ipc_recv的时候传参的时候是&who.这里函数内部会把谁传递信息给子进程的pid赋值给who.注意我这里没有特别说明是父进程,而用了"谁传递信息给这个子进程".因为在其他情形中,可能不仅仅只有父进程给这个子进程传递信息.

尔后双方互发信息....每个进程为i值增加1,双方交互十次然后结束.呵呵...所以这个程序看起来就像

双方打乒乓球一样...ping ping pong pong ...

spin.c:

这个用户程序看起来还是很简单的,子进程有点作死,居然死循环.这个时候会如果没有好的调度策略那么这货会一直抢占着CPU,大家也就都别玩了,,,

这样不好...怎么办呢?可以通过一个定时器中来触发外部硬件中断,由这个中断来完成进程的让出.

这里parent process 各种让出CPU,然后又被子进程霸占CPU,等一段时间了定时器开始触发中断,这个时候CPU响应中断.开始处理这个定时器中断,我们就可以在处理机制里面做手脚,怎么做呢?

看下面:

在 trap_dispatch里面添加下面的代码用来检测触发的外部硬件中断是否为定时器中断.

看,我们添加了sched_yield();主动让出这个一直抢占CPU的进程.

由于之前初始化的时间片太短了,可能测试程序的感觉不明显.

我们可以去kern/lapic.c里面修改下面的代码.

注释哪行是实验老师原来设置的默认定时器初始值,现在看到的时我自己设置的0xFFFFFFF

一个大概足够大的数据就好,我没有深究这里的意义.因为这货和CPU的主频速度有关系,是一个不断做减法的过程.(以前玩过单片机还是有好处的哇...)

这里修改过这个参数后去运行spin的话就会发现,child Spinning ...那个地方会有明显的停顿.如果不把时间增加,那地方一闪就过了.这里为什么要设置恰当的时间,实验者可以自己想想 : )

测试完之后记得把TICR的值改回去,不然grade的时候可能时间太长过不了.

先放出来一部分,后面有些再补上

未完待续...

有误解的话,恳请斧正.

时间: 2024-12-17 00:34:38

JOS lab4 用户程序分析的相关文章

MIT 操作系统实验 MIT JOS lab4

MIT JOS lab4 写在前面的碎碎念~ : 经历了LAB 3的洗礼,死磕到了lab 4. 这里还是首先向各位为JOS 实验做过笔记,写过博客,把自己实验代码托管到JOS上面的先行者们致敬! 如果没有这么好的开源环境, 这么好的东西学不来. 珍惜, 不用嘴. Doing is better than saying! -----------------------------------------------------------------------------------------

JOS lab3 部分用户程序分析

在lab 4的分支里面,会有各种好玩的用户程序.如下: 觉得还是有必要一一对其进行简要的分析.自顶向下的了解OS的机制 分析的用户程序顺序随意,不按照难度排序 badsegment.c: 这里的唯一一行嵌入式汇编尝试把 0x28这个数赋值给数据段寄存器 DS 看这里Global describe table -- gdt, 0x28就是对于CPU0来说的TSS0段的选择子. 把TSS0选择子移入ds数据寄存器是违法的,会触发异常保护T_GPFLT 修改各种段寄存器都要满足CPL和DPL关系条件的

关于lab4实验git+近期出国手续办理

1.下载mit jos lab4时遇到问题(关于git操作,使用,还需进一步理解) 遇到的问题 出现未合并(merge)完全的问题,操作:git add kern/init.c 之后在确认提交 方法二(未实现) 删除该本地分支 但由于有问题(merge 冲突)无法删除或者更换分支 关于git待补充 ----------------------------------------------------------------------------------------------------

基于JOS 80x86 的堆栈切换简要分析

这个问题一直困扰很久,发现还是有点粗心,源头--堆栈初始化没怎么搞明白. 这里首先强调,一定一定要搞清楚分段和分页保护的机制. 现有分段,后有分页,分页可有可无,看寄存器cr0是否开启PE位(page enable. 在JOS系统的boot.S里就已经开启了) 文章从三个方面对栈进行分析 0. GDT 全局段寻址描述表 1. 栈的初始化. 2.用户栈到内核栈的切换 3.内核栈到用户栈的切换 0. GDT 全局段寻址描述表 你能看见第0个段这个时候是不允许访问的,GD_KT右移三位变成 (0x8

JOS 用户态page fault保护处理机制分析

常常会在用户态触发page fault,如果直接让其因为page fault跌入内核触发panic目测是不是"太残忍了" 你想想,一个刚学会写C程序的童鞋,就经常干 *(int *)0x00. 当然,我只是比较赤果果的表现而已,这位同学可能经常用各种指针,然后指针为初始化亦或等于NULL的时候,对其进行赋值或解引用.总不至于让一个刚学C的人就把整个系统都给挂了吧?恩.我们需要一种保护机制. 可以在用户态触发page fault,跌入内核时,我们可以做点"手脚",不要让他触发panic. 内核稍作

JOS fork函数 实现机制分析

简直有点小鸡冻哇... 介个地方之前困惑了好一阵...现在叨叨关于fork那些事儿 文章会着重分析fork的两种实现策略: 1. 不使用COW 策略实现dumbfork (很暴力的拷贝) 2. 使用COW技术的fork(写时复制, parent process , child process任意一个进程对共同映射的空间有改动,就发生拷贝动作, 改动了哪页拷贝哪页, 不是全部user space空间的拷贝). 大家都知道, 在Unix类系统里面, 创建一个子进程最常用的就是fork. 而且有个很牛

MIT 6.828 JOS学习笔记17. Lab 3.1 Part A User Environments

Introduction 在这个实验中,我们将实现操作系统的一些基本功能,来实现用户环境下的进程的正常运行.你将会加强JOS内核的功能,为它增添一些重要的数据结构,用来记录用户进程环境的一些信息:创建一个单一的用户环境,并且加载一个程序运行它.你也可以让JOS内核能够完成用户环境所作出的任何系统调用,以及处理用户环境产生的各种异常. Part A: User Environments and Exception Handling 新包含的文件inc/env.h里面包含了JOS内核的有关用户环境(

MIT 6.828 JOS学习笔记2. Lab 1 Part 1.2: The kernel

Lab 1 Part 1: PC bootstrap 我们继续~ PC机的物理地址空间 这一节我们将深入的探究到底PC是如何启动的.首先我们看一下通常一个PC的物理地址空间是如何布局的:                           这张图仅仅展示了内存空间的一部分. 第一代PC处理器是16位字长的Intel 8088处理器,这类处理器只能访问1MB的地址空间,即0x00000000~0x000FFFFF.但是这1MB也不是用户都能利用到的,只有低640KB(0x00000000~0x00

MIT 6.828 JOS学习笔记10. Lab 1 Part 3: The kernel

Lab 1 Part 3: The kernel 现在我们将开始具体讨论一下JOS内核了.就像boot loader一样,内核开始的时候也是一些汇编语句,用于设置一些东西,来保证C语言的程序能够正确的执行. 使用虚拟内存 在运行boot loader时,boot loader中的链接地址(虚拟地址)和加载地址(物理地址)是一样的.但是当进入到内核程序后,这两种地址就不再相同了. 操作系统内核程序在虚拟地址空间通常会被链接到一个非常高的虚拟地址空间处,比如0xf0100000,目的就是能够让处理器