lab4到目前为止,我们可以或许启动多个CPU,让多个CPU同时处置惩罚多个历程。实现了中断处置惩罚,并且实现了用户级页面故障机制以及写时复制fork。1. 时钟中断和抢占
但是,我们的历程调度不是抢占式的,现在每个历程只有在发生中断的时间,才会被调度(调用shed_yeild),这样就有可能会有历程一直占用CPU不放。我们希望可以或许让各个历程平分CPU,在各个时间片上处置惩罚自己的任务。
于是实验室 4 的最后一部门,我们的任务就是修改内核,实现抢占式多历程调度,并实现历程间通信机制(IPC)。
手册:1.1 中断管理
与 xv6 Unix 相比,我们在 JOS 中做了一个关键的简化。在内核中,外部装备中断始终处于禁用状态(与 xv6 一样,在用户空间中处于启用状态)。外部中断由 %eflags 寄存器(参见 inc/mmu.h)的 FL_IF 标志位控制。该位被设置时,外部中断被启用。 虽然可以通过多种方式修改该位,但为了简化操作,我们将仅通过在进入和离开用户模式时保存和恢复 %eflags 寄存器的过程来处置惩罚它。
您必须确保在用户环境中运行时设置 FL_IF 标志,以便在中断发生时将其转达给处置惩罚器,并由您的中断代码进行处置惩罚。 否则,中断将被屏蔽或忽略,直到中断被重新启用。我们在启动加载程序的第一条指令中就屏蔽了中断,到目前为止,我们还从未重新启用过中断。
我们在启动加载程序的第一条指令中就屏蔽了中断,到目前为止,我们还从未重新启用过中断。
接下来的任务,我们要美满外部中断的管理,
外部中断(即装备中断)称为 IRQ。有 16 个可能的 IRQ,编号从 0 到 15。从 IRQ 编号到 IDT 条目之间的映射关系并不固定。picirq.c 中的 pic_init 将 IRQ 0-15 映射到 IDT 条目 IRQ_OFFSET 至 IRQ_OFFSET+15。Exercise 13
在 inc/trap.h 中,IRQ_OFFSET 被定义为十进制 32。因此,IDT 项 32-47 对应 IRQ 0-15。例如,时钟中断是 IRQ 0,因此 IDT[IRQ_OFFSET+0](即 IDT[32])包含内核中时钟中断处置惩罚程序例程的地点。选择这个 IRQ_OFFSET,是为了避免装备中断与处置惩罚器异常重叠,以免造成混淆。(事实上,在早期运行 MS-DOS 的 PC 中,IRQ_OFFSET 实际上为 0,这确实造成了处置惩罚硬件中断和处置惩罚处置惩罚器异常之间的大量混淆!)。
与 xv6 Unix 相比,我们在 JOS 中做了一个关键的简化。在内核中,外部装备中断始终处于禁用状态(与 xv6 一样,在用户空间中处于启用状态)。外部中断由 %eflags 寄存器(参见 inc/mmu.h)的 FL_IF 标志位控制。该位被设置时,外部中断被启用。 虽然可以通过多种方式修改该位,但为了简化操作,我们将仅通过在进入和离开用户模式时保存和恢复 %eflags 寄存器的过程来处置惩罚它。
您必须确保在用户环境中运行时设置 FL_IF 标志,以便在中断发生时将其转达给处置惩罚器,并由您的中断代码进行处置惩罚。 否则,中断将被屏蔽或忽略,直到中断被重新启用。我们在启动加载程序的第一条指令中就屏蔽了中断,到目前为止,我们还从未重新启用过中断。
在吸取到中断请求并处置惩罚完成后,向本地高级可编程中断控制器(Local Advanced Programmable Interrupt Controller, LAPIC)发送一个 EOI 命令,通知 LAPIC 中断处置惩罚已完成。这是为了释放中断控制器的资源,以便处置惩罚下一个中断。但是好奇怪,进入trapentry.S 时间,从来没见过我们自动清零IF啊,为什么CPU自动关闭吸取外部中断了呢?
中断门和陷阱门的区别在于对 IF(中断启用标志)的影响。矢量通过中断门的中断会重置 IF,从而防止其他中断干扰当前中断处置惩罚程序。随后的 IRET 指令将 IF 恢复为堆栈上 EFLAGS 映像中的值。通过陷阱门的中断不会改变 IF。功能上的区别是这样,那格式上呢?
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |