OS-lab3
思考题
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,因此如果没有data,load_icode_mapper就无法获得当前进程页目录的地址与asid。
Thinking 3.3
结合 elf_load_seg 的参数和实现,考虑该函数需要处理哪些页面加载的情况。
- 如果
va不与PAGE_SIZE对齐,那么将1多于地址记为offset,并将剩余的binary数据写入对应地址 - 将段内的页映射到物理地址
- 如果该段在内存中的大小小于在文件中的大小,需要用0填充剩余空间
Thinking 3.4
思考上面这一段话,并根据自己在Lab2中的理解,回答
env_tf.cpo_epc存储的是物理地址还是虚拟地址
CPU处理的地址均为虚拟地址,因此这里存储的也是虚拟地址
Thinking 3.5
试找出上述 5 个异常处理函数的具体实现位置。
handle_int的实现位于genex.S中,handle_mod,handle_tlb,handle_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/OS-lab3/
- License: This work is licensed under CC BY-NC-SA 4.0.