操作系统实验报告(lab3)


操作系统实验

Lab3


目录

1.思考题解答
2.难点分析
3.思考体会


思考题解答

Thinking 3.1

e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) | PTE_V;

大小为4MB(0x7fc000000 - 0x80000000)是保存该进程页表项的区域,其中 UVPT = 0x7fc00000。
采用页表自映射的方式:页目录的 4KB 空间在这 4MB 空间之中,该页目录中有一项指向的空间是页目录的头地址,该项即为第PDX(UVPT) 项,将页目录本身的物理地址映射给这一页目录项实现自映射。

Thinking 3.2

在 env.c 文件的 load_icode 函数中,调用了 elf_load_seg 函数,形参 map_page 和 data 对应的实参分别是 load_icode_mapper函数和 e(进程控制块)。
不可以没有该参数,因为该参数的作用是作为回调函数的参数传入,函数会对其进行分配物理页面建立映射的操作。

Thinking 3.3

va 和 va + bin_size 的关系可能有:

va + bin_size 和 va + sig_size 的关系可能有:

Thinking 3.4

env_tf.cp0_epc 存储的是程序入口,而各个进程的程序入口相同,所以这是虚拟地址。

Thinking 3.5

handle_int (kern/genex.S)

NESTED(handle_int, TF_SIZE, zero)
    mfc0    t0, CP0_CAUSE
    mfc0    t2, CP0_STATUS
    and     t0, t2
    andi    t1, t0, STATUS_IM4
    bnez    t1, timer_irq
    // TODO: handle other irqs
timer_irq:
    sw      zero, (KSEG1 | DEV_RTC_ADDRESS | DEV_RTC_INTERRUPT_ACK)
    li      a0, 0
    j       schedule
END(handle_int)

handle_mod、handle_tlb、handle_sys通过genex.S文件中的宏函数BUILD_HANDLER实现:

BUILD_HANDLER tlb do_tlb_refill

#if !defined(LAB) || LAB >= 4
BUILD_HANDLER mod do_tlb_mod
BUILD_HANDLER sys do_syscall
#endif

Thinking 3.6

LEAF(enable_irq)
    li      t0, (STATUS_CU0 | STATUS_IM4 | STATUS_IEc)
    //赋值 t0 = 0x10001001
    mtc0    t0, CP0_STATUS
    //#将 CP0 的 SR 寄存器中第1、12、28位 置为1,作用是开启全局中断使能和始终中断使能,并允许用户态使用CP0
    jr      ra
    //返回
END(enable_irq)
timer_irq:
    sw      zero, (KSEG1 | DEV_RTC_ADDRESS | DEV_RTC_INTERRUPT_ACK)
    //写入0,响应时钟中断
    li      a0, 0
    //向 schedule 中传入 0
    j       schedule
    //跳转到 schedule 函数

Thinking 3.7

  • 当线程被创建并置为 RUNNABLE 时,将其插入到 env_sched_list 的头部。
  • 每次运行前检查正需要运行的进程时间片是否用完。
  • 用完若状态仍为 RUNNABLE 则将其插入到 env_sched_list 的尾部,否则直接移出可执行线程队列。继续运行队列头部的线程。
  • 若未用完则继续执行。

难点分析

  • 页表自映射的机制较为抽象,在 lab2 的扩展部分,第一次接触到了页表自映射的概念,由于对二级页表的处理较为生疏,理解该映射机制存在一定难度;该机制实际上是将页目录、页表、其他虚拟页一视同仁,都采用相同的映射机制进行访问,唯一需要注意的是为了实现该机制,各个页表占用的总 4MB 空间要求连续存储
  • 对中断处理函数的理解有一定难度,主要操作位,结合中断允许控制位和中断标志位对是否中断及中断类型进行判断,通过进程调度的方式来处理中断。
  • 调度函数的编写容易出错,由于进程是可以创建进程的,故一个进程需要执行时,需先将其从可执行线程链表中立即取出,若执行后再取出,可能会导致其他进程获取到相同的子进程。

思考体会

本次作业要求填补的函数难度不高,但透彻理解线程的创建过程和中断的处理机制还是有一定挑战的;经历 lab2 对内存管理的熟悉后,完成 lab3 实验的压力降低了很多;后续需要加强对进程在内存中执行的细节的了解和理解。


文章作者: Argithun
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Argithun !