OS-lab3

OWPETER Lv3

思考题

Thinking 3.1

解释代码中 e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) | PTE_V 的含义。

e->env_pgdir[PDX(UVPT)]可以获得当前进程中UVPT地址的页目录项,其中UVPT是用户页表的起始地址。e->env_pgdir获得进程e的页目录的虚拟地址,通过PADDR函数转换成物理地址,在通过| PTE_V将页目录的物理基地址设置为valuable

Thinking 3.2

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

load_icode函数中调用elf_load_seg时,将进程控制块e传给了参数data,而elf_load_seg又将参数传给load_icode_mapper,因此如果没有dataload_icode_mapper就无法获得当前进程页目录的地址与asid

Thinking 3.3

结合 elf_load_seg 的参数和实现,考虑该函数需要处理哪些页面加载的情况。

  1. 如果va不与PAGE_SIZE对齐,那么将1多于地址记为offset,并将剩余的binary数据写入对应地址
  2. 将段内的页映射到物理地址
  3. 如果该段在内存中的大小小于在文件中的大小,需要用0填充剩余空间

Thinking 3.4

思考上面这一段话,并根据自己在Lab2中的理解,回答env_tf.cpo_epc存储的是物理地址还是虚拟地址

CPU处理的地址均为虚拟地址,因此这里存储的也是虚拟地址

Thinking 3.5

试找出上述 5 个异常处理函数的具体实现位置。

handle_int的实现位于genex.S中,handle_modhandle_tlbhandle_reserved都是通过genex.S中的BUILD_HANDLER宏实现的

Thinking 3.6

阅读 entry.S、genex.S 和 env_asm.S 这几个文件,并尝试说出时钟中断在哪些时候开启,在哪些时候关闭。

env_asm.S中的env_pop_tf调用了RESET_KCLOCK宏,开启了时钟中断。

Thinking 3.7

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

  • 在每个进程执行前调用RESET_KCLOCK宏重置计时器
  • 当进程的时间片到,产生时钟中断,系统PC指向0x80000180进入异常处理程序
  • 由于是0号异常,进入到中断处理函数handle_int
  • 根据STATUS_IM4判断出该中断产生的原因为时钟中断,于是跳转到timer_irq处,timer_irq又调用schedule函数
  • schedule函数通过判断:
    • yield,即进程1是否必须被切换
    • count == 0,即进程时间片是否被用完
    • e == NULL当前是否未调度任何线程
    • e->env_status != ENV_RUNNABLE当前进程状态不再为“执行”
      这四个条件,决定是否进行进程切换。如果进行进程切换,并且当前进程状态依然为执行,那么将进程重新加入调度队列尾部。否则,仅取出调度队列头部进程,将时间片长度设置为进程pri,然后运行该进程

实验难点

我认为本次实验有两个重点,分别为进程创建与进程切换

进程创建

进程创建需要经历以下过程:

  • 使用env_alloc函数建立进程运行环境,具体来说有以下操作:
    • env_free_list中取出一个空闲PCB作为即将创建的进程的进程控制块
    • 调用env_setup_vm建立进程的虚拟地址空间。建立虚拟地址空间的过程就是建立一个页表,并建立页表自映射
    • 调用asid_alloc函数,为新的进程分配一个asid
    • 初始化sp寄存器与cp0_status
    • 最后将PCB从env_free_list中移除

进程切换

此部分可见Thinking 3.7

  • Title: OS-lab3
  • Author: OWPETER
  • Created at : 2025-04-24 22:43:18
  • Updated at : 2025-05-06 22:45:20
  • Link: https://owpeter.github.io/2025/04/24/OS-lab3/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments