扩展练习 Challenge 1(需要编程)

扩展proj4,增加syscall功能,即增加一用户态函数(可执行一特定系统调用:获得时钟计数值),当内核初始完毕后,可从内核态返回到用户态的函数,而用户态的函数又通过系统调用得到内核态的服务(通过网络查询所需信息,可找老师咨询。如果完成,且有兴趣做代替考试的实验,可找老师商量)。需写出详细的设计和分析报告。完成出色的可获得适当加分。

提示:
规范一下 challenge 的流程。

kern_init 调用 switch_test,该函数如下:

  1. static void
  2. switch_test(void) {
  3. print_cur_status(); // print 当前 cs/ss/ds 等寄存器状态
  4. cprintf("+++ switch to user mode +++\n");
  5. switch_to_user(); // switch to user mode
  6. print_cur_status();
  7. cprintf("+++ switch to kernel mode +++\n");
  8. switch_to_kernel(); // switch to kernel mode
  9. print_cur_status();
  10. }

switchto* 函数建议通过 中断处理的方式实现。主要要完成的代码是在 trap 里面处理 T_SWITCH_TO* 中断,并设置好返回的状态。

在 lab1 里面完成代码以后,执行 make grade 应该能够评测结果是否正确。

扩展练习 Challenge 2(需要编程)

用键盘实现用户模式内核模式切换。具体目标是:“键盘输入3时切换到用户模式,键盘输入0时切换到内核模式”。
基本思路是借鉴软中断(syscall功能)的代码,并且把trap.c中软中断处理的设置语句拿过来。

注意:

 1.关于调试工具,不建议用lab1_print_cur_status()来显示,要注意到寄存器的值要在中断完成后tranentry.S里面iret结束的时候才写回,所以再trap.c里面不好观察,建议用print_trapframe(tf)

 2.关于内联汇编,最开始调试的时候,参数容易出现错误,可能的错误代码如下

  1. asm volatile ( "sub $0x8, %%esp \n"
  2. "int %0 \n"
  3. "movl %%ebp, %%esp"
  4. : )

要去掉参数int %0 \n这一行

3.软中断是利用了临时栈来处理的,所以有压栈和出栈的汇编语句。硬件中断本身就在内核态了,直接处理就可以了。

  1. 参考答案在mooc_os_lab中的mooc_os_2014 branch中的labcodes_answer/lab1_result目录下