MIT JOS LAB3学习笔记

本文详细介绍了MIT JOS操作系统实验的第三部分,涉及用户环境的建立、异常处理、进程管理和系统调用。主要内容包括:初始化用户环境、处理缺页异常、断点异常和系统调用,以及通过编程实现中断描述符表IDT和任务状态段TSS。文章还探讨了中断和异常的基本概念,并分析了如何设置IDT、创建和运行进程。在实验过程中,作者遇到了如缺页异常处理和权限问题,并逐一解决,最终实现了用户进程的正常运行。
摘要由CSDN通过智能技术生成

LAB3概述:

本次操作系统实验,我们对计算机的操作系统进行了初步的探究,通过完成作业和问题,对lab3部分有了较好的理解。Lab3主要实现能运行被保护的用户模式环境(protected user-mode environment,即process)的内核服务。我们将增加数据结构来记录进程、创建进程、为其装载一个程序镜像。我们还要让JOS 内核能够处理进程产生的系统调用和异常。具体来说:

第一部分主要完成用户环境和异常处理,我们主要先为我们的环境申请地址并进行映射,之后改写env.c中的相应函数来使得我们可以让系统进入用户空间执行我们想要的系统调用。接下来我们对处理中断和异常进行了探索,建立了我们自己的中断描述符表IDT,在trapentry.s和trap.c对产生中断的一开始过程深入了解。

第二部分处理缺页错误,断点异常以及系统调用。我们逐个对缺页中断、断点异常、系统调用等等的中断进行处理,通过对应参数调用不同的函数对相应的中断进行对应处理。我们在最后完成了用户进程的启动,以及对页错误和内存的保护。

此外,在完成这两大块内容的同时,对于问题的完成也使我们对于一些基础概念的理解,以及代码部分知识的掌握有了进一步的提升。


作业一


一.准备知识

Env数据结构代表一个进程描述符,定义在env.h中,包括进程的id,父进程的id,执行状态,该进程的寄存器状态,执行的次数等,并使用env_link指向下一个空闲的Env。

所有Env对象存储在envs数组中,该数组定义在env.c的开头。

除此之外curenv代表当前正在执行的进程,env_free_list指向空闲的进程描述符,组成链表,链表的添加与删除均在表头执行。


二.代码展示

修改mem_init() 使之能分配envs数组。这个数组是由NENV个Env结构体组成的。envs数组所在的这部分内存空间应该是用户模式只读的。

如题,类似lab2中分配pages数组,分配空间给数组envs同时初始化。

在lab2中分配pages数组时操作。

类似的分配env数组空间,并初始化

然后可以将虚拟内存的UENVS段映射到envs的物理地址

用到函数boot_map_region(pde_t *pgdir, uintptr_t va, size_t size, physaddr_tpa, int perm);


作业二


一.函数介绍

env_init(): 初始化所有的在envs数组中的 Env结构体,并把它们加入到env_free_list中。还要调用 env_init_percpu,这个函数要配置段式内存管理系统,让它所管理的段,可能具有两种访问优先级其中的一种,一个是内核运行时的0优先级,以及用户运行时的3优先级。

env_setup_vm(): 为一个新的用户环境分配一个页目录表,并且初始化这个用户环境的地址空间中的和内核相关的部分。

region_alloc(): 为用户环境分配物理地址空间。

load_icode(): 分析一个ELF文件,类似于bootloader做的那样,我们可以把它的内容加载到用户环境下。

env_create(): 利用env_alloc函数和load_icode函数,加载一个ELF文件到用户环境中。

env_run(): 在用户模式下,开始运行一个用户环境。

二.代码实现

1)env_init():进程描述符数组初始化


按照注释,遍历数组envs,要把它的id设为0,并且令envs中所有环境都是free状态,然后按序插入链表中。此时注意第一个被使用的是envs[0]。

2)env_setup_vm():初始化进程的虚拟空间。不同的进程有不同的虚拟地址空间,进而就必须有自己的页目录和页表,该函数的任务就是初始化页目录。


本题注释讲的很清楚,The VA space of all envs is identical (same)above UTOP。进程的页目录和内核的页目录(utop之上)可以共用,所以先分配一个空闲页,然后直接copy就可以,我们不需要做任何其他事情。接着增加分配的物理页的引用,将此页的虚拟地址赋值给进程的pgdir,然后使进程有权限操作自己的pgdir。


3)region_alloc():分配物理地址。把起始地址和终止地址对齐,然后以页为单位,一页一页分配内容,并且修改页目录表和页表。

为进程分配物理内存,映射到虚拟内存。round函数对起始地址和终止地址页对齐。

然后就可以以页单位给进程进行内寸分配了。然后修改页目录和页表

4)通过load_icode给相应的进程加载可执行代码。可执行代码的格式是elf格式。

5)env_creat():简单的函数,新建进程,调用env-alloc。然后利用load-icode读取elf。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值