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-lab3/
- License: This work is licensed under CC BY-NC-SA 4.0.