JOS lab4 Preemptive Multitasking Part C

Part C: Preemptive Multitasking and Inter-Process communication (IPC)这最后一个部分需要修改内核来抢占那些不配合的环境,并且允许进程之间显式地传递消息。时钟中断和抢占user/spin测试程序fork出一个子进程,子进程获得CPU控制之后执行一个死循环。父进程和kernel都不能重新获得CPU了。这从保护操作系统免受用户态环境的bug和恶意代码来看明显不是一个理想情况,因为任何的用户态环境都可以轻松地让系统停滞。为了让kernel可以
摘要由CSDN通过智能技术生成

Part C: Preemptive Multitasking and Inter-Process communication (IPC)

这最后一个部分需要修改内核来抢占那些不配合的环境,并且允许进程之间显式地传递消息。

时钟中断和抢占

user/spin测试程序fork出一个子进程,子进程获得CPU控制之后执行一个死循环。父进程和kernel都不能重新获得CPU了。这从保护操作系统免受用户态环境的bug和恶意代码来看明显不是一个理想情况,因为任何的用户态环境都可以轻松地让系统停滞。为了让kernel可以抢占用户环境,强制接管CPU控制,我们必须扩展JOS kernel支持来自时钟硬件的外部硬件中断。

中断规则

外部中断称作IRQ。总共有16个IRQ,分别标记为从0到15号IRQ。从IRQ到IDT表项的映射不是固定的。picirq.c中的pic_init把0到15号映射到IRQ_OFFSETIRQ_OFFSET+15
inv/trap.h之中,IRQ_OFFSET被设置为十进制数32,因此IDT表从从32到47对应IRQ0到15.这么选择是为了让硬件中断和处理器异常区分开不至于造成困惑。
在JOS中,相比于xv6 Unix,我们做了一个关键简化。在kernel中外部中断总是被关掉的。外部中断由eflags寄存器中的FL_IF位控制。当这个位被设置的时候,外部中断被打开。我们将会只通过保存和恢复eflags寄存器的方式来修改FL_IF位。
需要确保在用户环境运行的时候FL_IF标志位是开启的,这样可以当中断来的时候进入kernel通过中断处理程序处理。否则,中断被屏蔽或忽略,直到中断被重新启用。我们在bootloader中最开始的指令中屏蔽了中断,到目前为止还没有重新开启过。
Exercise 13 要求修改kern/trap.c以及kern/trapentry.S来初始化IDT中恰当的表项。并且修改kern/env.c中的env_alloc()来确保用户环境运行的时候中断总是开启的。
并且把sched_halt()中的sti指令去掉注释,这样空闲的CPU就不会屏蔽中断了。
注意处理器在调用硬件中断处理程序的时候不会向内核栈压入错误码。
env.c

// Enable interrupts while in user mode.
	// LAB 4: Your code here.
	e->env_tf.tf_eflags |= FL_IF;

trapentry.S

	TRAPHANDLER_NOEC(IRQ_0, IRQ_OFFSET + 0)
	TRAPHANDLER_NOEC(IRQ_1, IRQ_OFFSET + 1)
	TRAPHANDLER_NOEC(IRQ_2, IRQ_OFFSET + 2)
	TRAPHANDLER_NOEC(IRQ_3, IRQ_OFFSET + 3)
	TRAPHANDLER_NOEC(IRQ_4, IRQ_OFFSET + 4)
	TRAPHANDLER_NOEC(IRQ_5, IRQ_OFFSET + 5)
	TRAPHANDLER_NOEC(IRQ_6, IRQ_OFFSET + 6)
	TRAPHANDLER_NOEC(IRQ_7, IRQ_OFFSET + 7)
	TRAPHANDLER_NOEC(IRQ_8, IRQ_OFFSET + 8)
	TRAPHANDLER_NOEC(IRQ_9, IRQ_OFFSET + 9)
	TRAPHANDLER_NOEC(IRQ_10, IRQ_OFFSET + 10)
	TRAPHANDLER_NOEC(IRQ_11, IRQ_OFFSET + 11)
	TRAPHANDLER_NOEC(IRQ_12, IRQ_OFFSET + 12)
	TRAPHANDLER_NOEC(IRQ_13, IRQ_OFFSET + 13)
	TRAPHANDLER_NOEC(IRQ_14, IRQ_OFFSET + 14)
	TRAPHANDLER_NOEC(IRQ_15, IRQ_OFFSET + 15)

trap.c

	void IRQ_0();
	void IRQ_1();
	void IRQ_2();
	void IRQ_3();
	void IRQ_4();
	void IRQ_5();
	void IRQ_6();
	void IRQ_7();
	void IRQ_8();
	void IRQ_9();
	void IRQ_10();
	void IRQ_11();
	void IRQ_12();
	void IRQ_13();
	void IRQ_14();
	void IRQ_15();
		SETGATE(idt[IRQ_OFFSET + 0], 0, GD_KT, &IRQ_0, 0);
	SETGATE(idt[IRQ_OFFSET + 1], 0, GD_KT, &IRQ_1, 0);
	SETGATE(idt[IRQ_OFFSET + 2], 0, GD_KT, &IRQ_2, 0);
	SETGATE(idt[IRQ_OFFSET + 3], 0, GD_KT, &IRQ_3, 0);
	SETGATE(idt[IRQ_OFFSET + 4], 0, GD_KT, &IRQ_4, 0);
	SETGATE(idt[IRQ_OFFSET + 5]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值