2023年秋冬季开源操作系统训练营第二阶段的日常学习记录
一:**** 二:**** 三:****
在2023a-rcore-put-down-crate目录下:
git clone https://github.com/LearningOS/rCore-Tutorial-Checker-2023A.git ci-user
git checkout ch3
多道程序(Multiprogramming):只有一个程序执行完毕后或主动放弃扫许,处理器才能执行另外一个程序。这不就是独占串行运行么。
让应用在执行 I/O 操作或空闲时,可以主动 释放处理器,让其他应用继续执行。当然执行 放弃处理器的操作算是一种对处理器资源的直接管理,所以应用程序可以发出这样的系统调用,让操作系统来具体完成。这样的操作系统就是支持 多道程序或 协作式多任务的协作式操作系统。 win3.x都算协作吧。
硬件中断机制可随时打断应用程序的执行,并让OS来完成对外设计I/O响应。 时间片 & 任务片 设计可完成硬件中断机制,也更需要第三方来进行机制的完成与监督。 这个第三方大概就是OS或者GC或者托管程序等等。 在编程语言中体现出来的概念应该就是各种锁了吧。
所有应用的 ELF 格式执行文件都经过 objcopy 工具丢掉所有 ELF header 和符号变为二进制镜像文件,随后以同样的格式通过在操作系统内核中嵌入 link_user.S 文件(在此文件中进行序号指定及路径指定),在编译时直接把应用链接到内核的数据段中。不同的是,我们对相关模块进行了调整:在第二章中应用的加载和执行进度控制都交给batch 子模块,而在第三章中我们将应用的加载这部分功能分离出来在 loader 子模块中实现,应用的执行和切换功能则交给 task 子模块。目前应用程序的编址方式是基于绝对位置的,并没做到与位置无关,内核也没有提供相应的地址重定位机制。
所有应用在内核初始化时一并加载到内存需要加载到不同的物理地址,通过os/src/loader.rs/load_apps()实现
执行跳转到应用加载的内存位置需要设置应用程序返回的不同Trap上下文(Trap上下文中保存了放置程序起始地址的epc寄存器内容):
1.跳转到应用程序(编号i)的入口点entiry[i]
2.将使用的栈切换到用户栈stack[i]
上节一个应用会独占 CPU 直到它出错或主动退出。操作系统还是以程序的一次执行过程(从开始到结束)作为处理器切换程序的时间段。为了提高效率,我们需要引入新的操作系统概念任务 、任务切换 、任务上下文。
当程序访问I/O外设或睡眠时,其实是不需要占用处理器的,于是我们可以把应用程序在不同时间段的执行过程分为两类,占用处理器执行有效任务的计算阶段和不必占用处理器的等待阶段。这些阶段就形成了一个我们熟悉的“暂停-继续…”组合的控制流或执行历史。从应用程序开始执行到结束的整个控制流就是应用程序的整个执行过程。
任务切换,在内核中这种机制是在__switch函数中实现的。任务切换支持的场景是:一个应用在运行途中便会主动或被动交出CPU的使用权,此时它只能暂停执行,等到内核重新给它分配处理器资源之后才能恢复并继续执行。
只要任务切换的开销不大,那么处理器的执行效率就会大大提高。当然,这需要应用程序在运行途中能主动交出 CPU 的使用权,此时它处于等待阶段,等到操作系统让它再次执行后,那它就可以继续执行了。
到这里,我们就把应用程序的一次执行过程(也是一段控制流)称为一个任务 ,把应用执行过程中的一个时间片段上的执行片段或空闲片段称为计算任务片
或空闲任务片
。当应用程序的所有任务片都完成后,应用程序的一次任务也就完成了。从一个程序的任务切换到另外一个程序的任务称为任务切换。为了确保切换后的任务能够正确继续执行,操作系统需要支持让任务的执行暂停
和继续
。
“暂停-继续”组合。一旦一条控制流需要支持“暂停-继续”,就需要提供一种控制流切换的机制,而且需要保证程序执行的控制流被切换出去之前和切换回来之后,能够继续正确执行。这需要让程序执行的状态(也称上下文),即在执行过程中同步变化的资源(如寄存器、栈等)保持不变,或者变化在它的预期之内。不是所有的资源都需要被保存,事实上只有那些对于程序接下来的正确执行仍然有用,且在它被切换出去的时候有被覆盖风险的那些资源才有被保存的价值。这些需要保存与恢复的资源被称为 任务上下文 (Task Context) 。
需要结合硬件机制和软件实现来保存和恢复任务上下文。任务的一次切换涉及到被换出和即将被换入的两条控制流(分属两个应用的不同任务),通常它们都需要共同遵循某些约定来合作完成这一过程。
前面已经知道的两种上下文保存/恢复的实例:
第一章应用程序与基本执行环境
中,我们介绍了函数调用与栈
。需要保存和恢复
函数调用上下文
。
第二章批处理系统
中第一次涉及到了某种异常(Trap)
控制流,即两条控制流的特权级切换,需要保存和恢复
系统调用(Trap)上下文
。
任务切换是Trap控制流切换之外的另一种异常控制流,都是描述两条控制流之间的切换,如果将它和Trap切换进行比较,会有如下异同:
1.与Trap切换不同,它不涉及特权级切换。
2.与Trap切换不同,它的一部分是由编译器帮忙完成的。
3.与Trap切换相同,它对应用是透明的。
从实现的角度讲, __switch 函数和一个普通的函数之间的核心差别仅仅是它会 换栈 。
包含持有关系:.data>>TaskManager全局实例TASK_MANAGER>>tasks>>TaskControlBlack>>TaskContext>>(ra寄存器==栈内指针 + sp寄存器==栈指针 + s寄存器s0-11 )
1.任务运行状态:任务从开始到结束执行过程中所处的不同运行状态:未初始化、准备执行、正在执行、已退出
2.任务控制块:管理程序的执行过程的任务上下文,控制程序的执行与暂停
3.任务相关系统调用:应用程序和操作系统之间的接口,用于程序主动暂停 sys_yield 和主动退出sys_exit