资源

  1. ucore在线实验指导书
  2. 我的ucore实验代码

题目:完善中断初始化和处理

请完成编码工作和回答如下问题:

  1. 中断描述符表(也可简称为保护模式下的中断向量表)中一个表项占多少字节?其中哪几位代表中断处理代码的入口?

  2. 请编程完善kern/trap/trap.c中对中断向量表进行初始化的函数idt_init。在idt_init函数中,依次对所有中断入口进行初始化。使用mmu.h中的SETGATE宏,填充idt数组内容。每个中断的入口由tools/vectors.c生成,使用trap.c中声明的vectors数组即可。

  3. 请编程完善trap.c中的中断处理函数trap,在对时钟中断进行处理的部分填写trap函数中处理时钟中断的部分,使操作系统每遇到100次时钟中断后,调用print_ticks子程序,向屏幕上打印一行文字”100 ticks”。

完成这问题2和3要求的部分代码后,运行整个系统,可以看到大约每1秒会输出一次”100 ticks”,而按下的键也会在屏幕上显示。

【注意】除了系统调用中断(T_SYSCALL)使用陷阱门描述符且权限为用户态权限以外,其它中断均使用特权级(DPL)为0的中断门描述符,权限为内核态权限;而ucore的应用程序处于特权级3,需要采用`int 0x80`指令操作(这种方式称为软中断,软件中断,Trap中断,在lab5会碰到) 来发出系统调用请求,并要能实现从特权级3到特权级0的转换,所以系统调用中断(T_SYSCALL)所对应的中断门描述符中的特权级(DPL)需要设置为3。

解答

问题1的回答

问题1:中断描述符表(也可简称为保护模式下的中断向量表)中一个表项占多少字节?其中哪几位代表中断处理代码的入口?

答:中断描述符表一个表项占8个字节,其结构如下:

  • bit 63..48: offset 31..16
  • bit 47..32: 属性信息,包括DPL、P flag等
  • bit 31..16: Segment selector
  • bit 15..0: offset 15..0

其中第1632位是段选择子,用于索引全局描述符表GDT来获取中断处理代码对应的段地址,再加上第015、48~63位构成的偏移地址,即可得到中断处理代码的入口。

完善idt_init函数

idt_init函数的功能是初始化IDT表。IDT表中每个元素均为门描述符,记录一个中断向量的属性,包括中断向量对应的中断处理函数的段选择子/偏移量、门类型(是中断门还是陷阱门)、DPL等。因此,初始化IDT表实际上是初始化每个中断向量的这些属性。

  1. 题目已经提供中断向量的门类型和DPL的设置方法:除了系统调用的门类型为陷阱门、DPL=3外,其他中断的门类型均为中断门、DPL均为0.

  2. 中断处理函数的段选择子及偏移量的设置要参考kern/trap/vectors.S文件:由该文件可知,所有中断向量的中断处理函数地址均保存在__vectors数组中,该数组中第i个元素对应第i个中断向量的中断处理函数地址。而且由文件开头可知,中断处理函数属于.text的内容。因此,中断处理函数的段选择子即.text的段选择子GD_KTEXT。从kern/mm/pmm.c可知.text的段基址为0,因此中断处理函数地址的偏移量等于其地址本身。

  3. 完成IDT表的初始化后,还要使用lidt命令将IDT表的起始地址加载到IDTR寄存器中。

根据以上分析,及注释中的提示,不难完成编码,如下所示。

extern uintptr_t __vectors[];

/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void idt_init(void) {
uint32_t pos;
uint32_t sel = GD_KTEXT; /* along: how to set istrap and dpl? */
for (pos = 0; pos < 256; pos++) {
SETGATE(idt[pos], 0, sel, __vectors[pos], 0);
} SETGATE(idt[128], 1, sel, __vectors[128], 3); lidt(&idt_pd);
}

lab1_result中的代码如下所示。答案有几处地方比我写得好:

  1. 我定义的sel变量是多余的,浪费内存,直接使用GD_KTEXT即可。
  2. 设置DPL时使用DPL_KERNEL, DPL_USER代替0和3,可读性更好。
  3. 将extern __vectors放在函数内部,使其仅在本函数内可见,结构上更合理。(是吗?)

不过这里有个问题:答案设置系统调用的门描述符时,中断向量为什么是T_SWITCH_TOK(121)而不是T_SYSCALL(128)?

/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void idt_init(void) {
extern uintptr_t __vectors[];
int i;
for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);
}
// set for switch from user to kernel
SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER);
// load the IDT
lidt(&idt_pd);
}

完善trap函数

trap函数只是直接调用了trap_dispatch函数,而trap_dispatch函数实现对各种中断的处理,题目要求我们完成对时钟中断的处理,实现非常简单:定义一个全局变量ticks,每次时钟中断将ticks加1,加到100后打印"100 ticks",然后将ticks清零重新计数。代码实现如下:

    case IRQ_OFFSET + IRQ_TIMER:
if (((++ticks) % TICK_NUM) == 0) {
print_ticks();
ticks = 0;
}

《ucore lab1 exercise6》实验报告的更多相关文章

  1. [操作系统实验lab3]实验报告

    [感受] 这次操作系统实验感觉还是比较难的,除了因为助教老师笔误引发的2个错误外,还有一些关键性的理解的地方感觉还没有很到位,这些天一直在不断地消化.理解Lab3里的内容,到现在感觉比Lab2里面所蕴 ...

  2. Ucore lab1实验报告

    练习一 Makefile 1.1 OS镜像文件ucore.img 是如何一步步生成的? + cc kern/init/init.c + cc kern/libs/readline.c + cc ker ...

  3. ucore操作系统学习(三) ucore lab3虚拟内存管理分析

    1. ucore lab3介绍 虚拟内存介绍 在目前的硬件体系结构中,程序要想在计算机中运行,必须先加载至物理主存中.在支持多道程序运行的系统上,我们想要让包括操作系统内核在内的各种程序能并发的执行, ...

  4. 《ucore lab3》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1:给未被映射的地址映射上物理页 题目 完成do_pgfault(mm/vmm.c)函数,给未被映射的地址映射上物理页.设置访问权限的时候需 ...

  5. 《ucore lab1 exercise5》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 题目:实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_s ...

  6. 《ucore lab8》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1: 完成读文件操作的实现(需要编码) 题目 首先了解打开文件的处理流程,然后参考本实验后续的文件读写操作的过程分析,编写在sfs_inod ...

  7. 《ucore lab7》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1: 理解内核级信号量的实现和基于内核级信号量的哲学家就餐问题(不需要编码) 题目 完成练习0后,建议大家比较一下(可用meld等文件dif ...

  8. 《ucore lab6》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1: 使用 Round Robin 调度算法(不需要编码) 题目 完成练习0后,建议大家比较一下(可用kdiff3等文件比较软件) 个人完成 ...

  9. 《ucore lab5》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1: 加载应用程序并执行(需要编码) 题目 do_execv函数调用load_icode(位于kern/process/proc.c中) 来 ...

  10. 《ucore lab4》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1:分配并初始化一个进程控制块 题目 alloc_proc函数(位于kern/process/proc.c中) 负责分配并返回一个新的str ...

随机推荐

  1. Mathtype新版本

    新版本Mathtype在MS Word 2007不能直接调用.今天发现,可以直接从Windows程序菜单中启动.在独立的窗口下编辑,编辑后粘贴到Word或Tex中. 早年使用Word时,嫌Mathty ...

  2. 《自制编程语言--基于C语言 郑钢》学习笔记

    <自制编程语言>学习笔记 本仓库内容 <自制编程语言>源码 src/sparrow.tgz <自制编程语言>读书笔记 docs/* <自制编程语言>样章 ...

  3. MySQL5.7 基础之二

    设计范式: 第一范式:字段是原子性 第二范式:存在可用主键 第三范式:任何表都不应该有依赖于其它表非主键的字段 创建数据库.设计数据表 字段:字段名.数据类型.约束(通过键来实现,而键其实可以当做索引 ...

  4. FCS省选模拟赛 Day5

    传送门 Solution Code  #include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?( ...

  5. 从一个表中往另外一个表中插入数据用到的SQL

    insert into jdjc_zzjcxm (zj,jcxmmc) select sys_guid(),zbmc from JDJC_WHJXXMMC;

  6. CFD计算过程发散诸多原因分析【转载】

    转载自: http://blog.sina.com.cn/s/blog_5fdfa7e601010rkx.html 今天探讨引起CFD计算过程中发散的一些原因.cfd计算是将描述物理问题的偏微分方程转 ...

  7. jQuery学习笔记——基本了解

    安装 两种方法: 从 jquery.com 下载jQuery. 从 CDN 中载入 jQuery, 如从我的博客中加载 jQuery: <script src="https://blo ...

  8. 微信小程序“一劳永逸”的接口封装

    前言 最近都在研究小程序了,我可以的! 需求 之前都是用vue来开发项目的,接口模块我特意封装了一下.感觉也可以记录一下 小程序的接口虽说简单,但是重复调用那么多,显得不专业(一本正经的胡说八道) 还 ...

  9. Oracle通过一个字段的值将一条记录拆分为多条记录

    前言 之前遇到了一次这样的需求,当时没有记录,这一次又赶上了,简单的记录一下. 本文个人拙见,若有出入,请指出--来自菜的颤抖 场景 表A中存放了集装箱的信息,一个集装箱一条记录,表B中存放了对于集装 ...

  10. Spark(五十一):Spark On YARN(Yarn-Cluster模式)启动流程源码分析(二)

    上篇<Spark(四十九):Spark On YARN启动流程源码分析(一)>我们讲到启动SparkContext初始化,ApplicationMaster启动资源中,讲解的内容明显不完整 ...