《ucore lab1 exercise6》实验报告
资源
题目:完善中断初始化和处理
请完成编码工作和回答如下问题:
中断描述符表(也可简称为保护模式下的中断向量表)中一个表项占多少字节?其中哪几位代表中断处理代码的入口?
请编程完善kern/trap/trap.c中对中断向量表进行初始化的函数idt_init。在idt_init函数中,依次对所有中断入口进行初始化。使用mmu.h中的SETGATE宏,填充idt数组内容。每个中断的入口由tools/vectors.c生成,使用trap.c中声明的vectors数组即可。
请编程完善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表实际上是初始化每个中断向量的这些属性。
题目已经提供中断向量的门类型和DPL的设置方法:除了系统调用的门类型为陷阱门、DPL=3外,其他中断的门类型均为中断门、DPL均为0.
中断处理函数的段选择子及偏移量的设置要参考kern/trap/vectors.S文件:由该文件可知,所有中断向量的中断处理函数地址均保存在__vectors数组中,该数组中第i个元素对应第i个中断向量的中断处理函数地址。而且由文件开头可知,中断处理函数属于.text的内容。因此,中断处理函数的段选择子即.text的段选择子GD_KTEXT。从kern/mm/pmm.c可知.text的段基址为0,因此中断处理函数地址的偏移量等于其地址本身。
完成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中的代码如下所示。答案有几处地方比我写得好:
- 我定义的sel变量是多余的,浪费内存,直接使用GD_KTEXT即可。
- 设置DPL时使用DPL_KERNEL, DPL_USER代替0和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》实验报告的更多相关文章
- [操作系统实验lab3]实验报告
[感受] 这次操作系统实验感觉还是比较难的,除了因为助教老师笔误引发的2个错误外,还有一些关键性的理解的地方感觉还没有很到位,这些天一直在不断地消化.理解Lab3里的内容,到现在感觉比Lab2里面所蕴 ...
- Ucore lab1实验报告
练习一 Makefile 1.1 OS镜像文件ucore.img 是如何一步步生成的? + cc kern/init/init.c + cc kern/libs/readline.c + cc ker ...
- ucore操作系统学习(三) ucore lab3虚拟内存管理分析
1. ucore lab3介绍 虚拟内存介绍 在目前的硬件体系结构中,程序要想在计算机中运行,必须先加载至物理主存中.在支持多道程序运行的系统上,我们想要让包括操作系统内核在内的各种程序能并发的执行, ...
- 《ucore lab3》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1:给未被映射的地址映射上物理页 题目 完成do_pgfault(mm/vmm.c)函数,给未被映射的地址映射上物理页.设置访问权限的时候需 ...
- 《ucore lab1 exercise5》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 题目:实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_s ...
- 《ucore lab8》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 完成读文件操作的实现(需要编码) 题目 首先了解打开文件的处理流程,然后参考本实验后续的文件读写操作的过程分析,编写在sfs_inod ...
- 《ucore lab7》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 理解内核级信号量的实现和基于内核级信号量的哲学家就餐问题(不需要编码) 题目 完成练习0后,建议大家比较一下(可用meld等文件dif ...
- 《ucore lab6》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 使用 Round Robin 调度算法(不需要编码) 题目 完成练习0后,建议大家比较一下(可用kdiff3等文件比较软件) 个人完成 ...
- 《ucore lab5》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 加载应用程序并执行(需要编码) 题目 do_execv函数调用load_icode(位于kern/process/proc.c中) 来 ...
- 《ucore lab4》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1:分配并初始化一个进程控制块 题目 alloc_proc函数(位于kern/process/proc.c中) 负责分配并返回一个新的str ...
随机推荐
- 区块链阶段1-Linux基础- 2 Linux文件系统
2.1 什么是文件系统 文件系统是操作系统在磁盘或分区上组织文件的方法和数据结构.负责对磁盘空间进行组织和分配,存储文件数据,并对其提供保护和检索服务.学习Linux,首先需要了解整个 Linux 文 ...
- TCP协议怎么工作的?
三次握手过程: 第一次 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认:SYN:同步序列编号(Synchronize Sequence N ...
- UDF-C_UDMI【转载】
UDF定义变量的输出 使用宏: C_UDMI( c, thread, index) 自变量类型:cell_t c Thread *thread int index ...
- LCT 总结
刚开始学lct花了一晚上研究模板,调出来就感觉不怎么难打了. 对板子的浅显理解: lct维护树形联通块,通过splay维护实链,可以把需要的路径变换到一颗splay上维护. splay中的关系只依赖实 ...
- NoSql数据库Redis系列(4)——Redis数据持久化(AOF)
上一篇文章我们介绍了Redis的RDB持久化,RDB 持久化存在一个缺点是一定时间内做一次备份,如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失).对于数据完整性要求很严 ...
- 【软工实践】Alpha冲刺(3/6)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 对推送模块进行详细划分 基于用户的协同过滤,寻找更感兴趣的话题 学习API文档 ...
- vue+elementui搭建后台管理界面(4使用font-awesome)
使用font-awesome npm install --save font-awesome 修改 src/main.js 增加 import 'font-awesome/scss/font-awes ...
- Ubuntu -- unknown error: Chrome failed to start: exited abnormally (Driver info: chromedriver=...)
#添加沙盒模式 chrome_options.add_argument("--no-sandbox")
- Preventing CSRF With Ajax
https://stackoverflow.com/a/24394578/3782855 You don't need the ValidationHttpRequestWrapper solutio ...
- 【maven】在pom.xml中引入对json-lib的依赖dependency
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</art ...