A Blog of WNico

OS Lab3 实验报告

Lab3

Thinking 3.1

请结合 MOS 中的页目录自映射应用解释代码中 e->env_pgdir[PDX(UVPT)]= PADDR(e->env_pgdir) | PTE_V 的含义

PDX(UVPT) 是 UVPT 所处的页目录号,即UVPT处于第PDX(UVPT)个页目录所映射的4MB空间,因此页目录也被第PDX(UVPT)映射。

将该页目录对应的页目录项映射为页目录的物理基地址,并加上权限位。

Thinking 3.2

elf_load_seg 以函数指针的形式,接受外部自定义的回调函数 map_page。请你找到与之相关的 data 这一参数在此处的来源,并思考它的作用。没有这个参数可不可以?为什么?

data 是传入的进程控制块指针,在 load_icode_mapperload_icode 函数中被调用,在 load_icdoe 函数中 data 被赋予进程控制块的指针 e

需要这个参数以实现进程的内存管理,分配相应的物理页

Thinking 3.3

结合 elf_load_seg 的参数和实现,考虑该函数需要处理哪些页面加载的情况。
  1. 将二进制文件的内容加载到内存中。通过循环来完成,每次循环将一个页面(大小为 BY2PG)映射到内存中。如果二进制文件的大小不是页面大小的倍数,则最后一个页面可能会少于一个页面的大小。
  2. 如果二进制文件的大小小于段的大小,则需要在内存中分配额外的页面,以达到段的大小。这是通过循环来完成的,每次循环将一个页面映射到内存中,直到达到段的大小。
  3. 如果二进制文件在虚拟地址上的起始偏移量不是页面大小的倍数,则需要在虚拟地址上的起始位置处映射一个页面,这是通过第一个循环之前的代码来完成的。

Thinking 3.4

你认为这里的 env_tf.cp0_epc 存储的是物理地址还是虚拟地址?

虚拟地址。epc存储的是发生错误时CPU所处的指令地址,由于CPU使用的都是虚拟地址,因此env_tf.cp0_epc存储的也是虚拟地址

Thinking 3.5

handle_int 位于 genex.S 中

handle_mod 和 handle_tle, handle_sys 通过 genex.S 文件中的 BUILD_HANDLER 实现

Thinking 3.6

阅读 init.c、kclock.S、env_asm.S 和 genex.S 这几个文件,并尝试说出enable_irq 和 timer_irq 中每行汇编代码的作用。
//enable_irq
li      t0, (STATUS_CU0 | STATUS_IM4 | STATUS_IEc)
// 将 t0 赋值为 0x10008001,其中 IM4 表示开启中断,IEc 表示开启异常
mtc0    t0, CP0_STATUS
// 将 t0 赋给 SR 寄存器,从而开启中断和异常
jr      ra
// 返回

//timer_irq
sw      zero, (KSEG1 | DEV_RTC_ADDRESS | DEV_RTC_INTERRUPT_ACK)
// 将 0 写入 RTC 中断寄存器,从而清除时钟中断
li      a0, 0
// 将 0 赋值给 a0 寄存器
j       schedule
// 进入调度函数

Thinking 3.7

阅读相关代码,思考操作系统是怎么根据时钟中断切换进程的。

当内核创建新进程时,将其插入调度链表的头部,在其不再被阻塞或已结束时,将其从调度链表中移除。当时间片用完后,我们将当前进程插入调度链表的尾部,并从调度链表的头部取出一个就绪的进程进行切换。

本页的评论功能已关闭