JOS lab3 部分用户程序分析

在lab 4的分支里面,会有各种好玩的用户程序.如下:

觉得还是有必要一一对其进行简要的分析.自顶向下的了解OS的机制

分析的用户程序顺序随意,不按照难度排序

badsegment.c:

这里的唯一一行嵌入式汇编尝试把 0x28这个数赋值给数据段寄存器 DS

看这里Global describe table -- gdt, 

0x28就是对于CPU0来说的TSS0段的选择子.

把TSS0选择子移入ds数据寄存器是违法的,会触发异常保护T_GPFLT

修改各种段寄存器都要满足CPL和DPL关系条件的.必须触发系统调用,进入内核态,才能修改.

当前用户态的段CPL是3,那么就只能修改DPL是3的权限段,不能比这个权限高的,我们这里尝试修改原来的测试badsegment.c

如下:我该成了0x20,用户的数据段描述符.

运行情况,如下:

没有panic了....yes. 继续

breakpoint.c:

int $3尝试调用3号中断.

下面是 运行后挂掉的 trap frame

buggyhello.c:

这里尝试通过系统调用打印地址 0x1出的一个字符.系统完成启动之后,0x200000以下的内容都是empty memory.

这里太明显了,去访问没有映射的指针,会被我们之前lab4写好的 mem_check里的断言挂掉

buggyhello2.c:

这里尝试输出hello标记地址处的字符串,从注释里面会发现,作者的意图是直接销毁这个进程,但是,这里由于我们之前又写了断言在sys_cputs里面,于是这里要注释掉这行断言你才能看到预期的输出

输出如下:

divezero.c:

单步调试跟进去看:

是在指令ldiv的时候触发divide_error的

evilhello.c:

邪恶的hello,究竟怎么个邪恶法.

这里尝试用系统调用输出 0xf010000c地址出的100个字符.

我们知道虚拟地址0xf010000c对应的物理地址是0x10000c,这是刚开始的时候内核的入口地址

由于之前又做好了错误检查的部分.这里需要注释掉下图中的注释部分,不然访问内核高地址的尝试都没门..

这里需要把两个检测项都注释掉,因为,对于用户来说不仅仅内核高地址没有 PTE_U而且没有PTE_P,

输出会发现一开始还是尝试去解释这块地址出的一些数据,解释成字符,不过都是乱码.尔后进程被强制释放.

faultread.c:

这里我们初学C语言的时候,指针没学好,或警惕性不高的时候,没进行非空检查的话,就可能对NULL指针dereference.这是非法的.

上面这个测试程序会直接触发异常,然后挂掉系统.这里我们还没进行到lab 4,没有构建起用户空间触发的page fault的异常处理机制.后续到lab 4我会特别把这里例子再单独开一贴分析

faultreadkernel.c:

下面是尝试读取内核区数据的例子,用户程序是不允许访问这里的数据的

可以和上面那个 faultread.c做比较,上面的是访问0x00这个地址没有映射,于是出现的问题是确实PTE_P

这里的内核地址是有PTE_P,但是这里是不允许用户访问的.protection. 同是page fault,他们之间还是有稍许区别的.

关于 faultwrite.c faultwritekernel.c的分析和上述 faultread.c faultreadkernel.c同理.不再赘述.

hello.c:

深深的无力,感觉没啥好说的,这里就是访问thisenv这个全局变量,指向当前进程的struct env

打印thisenv->env_id.相当于Linux里面的输出进程pid : )

值得说一下的是这里的输出信息,先从内核态通过trap进入了用户态打印输出了hello, world

而后由于thisenv指向的结构体都是由刚开始分配内存的时候envs指向的一连串结构体储存在内核地址内,于是这里需要访问内核,势必触发trap,进入内核态,访问并打印thisenv指针指向的结构体内的成员 env_id

testbss.c:

我们知道,未初始化的的全局变量会放入到可执行程序的bss段.

这里的bigarray就是个例子.分配了很大的空间这个为初始化的全局变量

程序先测试验证,全局未初始化的变量都默认初始值为0.

然后一个个赋值.检测也没问题.前面三个for循环都正常

尝试在申请的数组范围之外写入数据就会触发page fault.因此我们看不到后面的panic输出信息.(这还是在lab3的基础上的分析,因为这里没有用户态的page fault handler,如果是lab 4的话,系统不会这样挂掉,但是如果正常的处理机制还是不应该让程序继续运行了 : )

lab 3的分析告一段落~

时间: 2024-12-04 20:13:52

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

MIT 操作系统实验 MIT JOS lab3

MIT JOS lab3 Allocating the Environments Array In lab 2, you allocated memory in  mem_init()  for the  pages[]  array, which is a table the kernel uses to keep track of which pages are free and which are not. You will now need to modify  mem_init()  

JOS lab4 用户程序分析

faultread.c faultdie.c: 这两个用户程序一起分析 左右两个用户程序,都试图对非法地址写入数据,但是左边的就会导致 page fault ,触发的是内核trap 而后边的就会进入打印trap frame,导致系统挂掉,而右边的不会,右边的由于有用户空间的处理机制, 还是建议自己一步步跟踪去看. faultalloc.c faultallocbad.c : 这里还是用户空间直接调用系统调用处理函数,还是通过用户程序触发page fault 之后再用用户空间page fault

ucore 源码剖析

lab1 源码剖析 从实模式到保护模式 初始化ds,es和ss等段寄存器为0 使能A20门,其中seta20.1写数据到0x64端口,表示要写数据给8042芯片的Output Port;seta20.2写数据到0x60端口,把Output Port的第2位置为1,从而使能A20门. 建立gdt,此处只设置了两个段描述符,分别对应代码段和数据段 gdt: SEG_NULLASM # null seg SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg

MIT-JOS系列5:用户环境(一)

Part A:用户环境和异常处理 用户环境创建 本节中我们将实现一些内核的基本工具来支持受保护的用户进程的运行.我们将增加JOS内核的功能,为它增加一些数据结构来追踪用户进程的一些信息:创建一个单一用户的环境,并在其中加载运行一个程序.我们也会使JOS内核处理用户进程做出的任何系统调用和它导致的任何异常 内核利用ENV数据结构来记录每一个环境的信息.目前我们只创建单一的用户环境,以后再在此基础上设计多用户环境 在kern/env.c中,内核维护以下三个关于环境的全局变量: struct Env

基于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