世界,您好!
欢迎使用WordPress。这是您的第一篇文章。编辑或删除它,然后开始写作吧!
BUAA-OS-Probe-Lab4
Lab4 - 系统调用与进程创建Lab4 中主要涉及到以下内容:
系统调用 syscall 的流程
进程间通信机制:ipc
用户进程的创建方式:fork 函数
写时复制 COW 与页写入异常
首先需要明确一件事,这篇文里说的大部分和汇编相关的内容估计都不会考,只是用来全面理解每一步的具体作用而已。所以写了一坨好多都是没营养的东西,请善用目录! 其实最不好理解的部分是在汇编代码和C代码之间切换的部分,可能一些宏定义、编译器的一些操作就会漏掉很多细节。 所以,时不时用用 make objdump 吧!努力成为 buaa-os 领域大神(?
系统调用在计算机组成原理实验 P7 与 Lab3 中,我们大致已经能够理清异常的原因、怎样产生与处理的方式了,但在 MOS 之前提到的异常大多不能由用户主动触发(时钟中断、TLB MISS 等),接下来我们就要深入了解一种特殊的、可以由用户主动发起的异常:系统调用 syscall
异常发生的原因:出现某些不符合操作规范的指令、外部中断、syscall 指令
产生地点(硬件):指令流水至(M级)时 CP0 协处理器分析异常 ...
BUAA-OS-2023-Lab4-1-Exam
中途脑梗了好几次,差点寄了,不过好在这次把题留下来了(
Exam - 进程组 ipc 通信题干
在 Linux 中,进程理论上所拥有的权限与执行它的用户的权限相同。进程运行时能够访问哪些资源或文件,不取决于进程文件的属主属组,而是取决于运行该命令的用户身份的 uid/gid,以该身份获取各种系统资源。
所以我们需要完成同一个进程组ID的不同进程的通信。具体而言,需要做到:
在 Env 结构体中添加 u_int env_gid 字段代表进程所在的进程组,初始值为 0。
实现一个修改 gid 字段的用户态函数:void set_gid(u_int gid);
实现一个仅能向同组块发送消息的用户态函数:int ipc_group_send(u_int whom, u_int val, const void *srcva, u_int perm);
实现 2、3 两点中对应的系统调用函数和调用接口
教程组已经把两个用户态函数实现了,我们只需要考虑系统调用函数 syscall_set_gid 和 syscall_ipc_try_group 即可
具体要求
在内核中为每个进程维护进程 ...
BUAA-OS-2023-Lab3-Exam
这次比较尴尬,做完了忘记保存题目了,结果复盘的时候全程想不起来题目写的是啥
Exam题干我们提出了一种基于多个用户而平均分配的时间片轮转调度算法。对于每个进程来说,它的拥有者(用户,用 0 \sim 4 的数字表示)用一个新增字段 u_int env_user表示。我们要改进的这个调度算法,每次都会运行已经使用过的时间片最少的用户的进程(相同时取 id 小者),进程按在env_sched_list 中的顺序取出,每次运行该用户的第一个进程。
为了记录每个用户已经使用的时间片,我们设置了一个全局数组 static int user_time[],当每次进程时间片耗尽时,对数组进行更新(对应用户加 pri即可)。例如对于如下的三个用户和三个进程,应该有这样的调度顺序(没保存所以只能上手绘图力!)
假装有图.jpg
请你按照这样的提示修改 schedule 函数,使其能满足刚才解释的按用户使用分配的时间片轮转算法。
void schedule(int yield) { static int count = 0; // remaining time slices of curren ...
BUAA-OS-2023-Lab4-Report
BUAA-OS-2023-Lab4-ReportThinking 4.1
思考并回答下面的问题:
内核在保存现场的时候是如何避免破坏通用寄存器的?
系统陷入内核调用后可以直接从当时的$a0-$a3 参数寄存器中得到用户调用msyscall留下的信息吗?
我们是怎么做到让sys 开头的函数“认为”我们提供了和用户调用msyscall 时同样的参数的?
内核处理系统调用的过程对Trapframe 做了哪些更改?这种修改对应的用户态的变化是什么?
在系统发生异常时跳入异常分发程序时,会先调用 SAVE_ALL 宏定义,把所有寄存器(用户态现场)保存在内核栈 KSTACKTOP 下。最后将 sp寄存器指向保存的这个栈帧。这样既能保护用户态时通用寄存器的值不被改变,同样也能在内核态中便捷地调用每个寄存器的值
可以直接调用。系统调用 msyscall 时只通过 SAVE_ALL将寄存器的值复制到了内核栈中,但对寄存器中的值没有做任何处理,仍然保持着用户态进入时的状态。所以这时参数寄存器内数值仍然可用。
在 do_syscall 函数中,我们通过系统调用向量 sys ...
BUAA-OS-Probe-Lab3
Lab3 - 进程与异常Lab3 中主要涉及到以下内容:
进程的创建
时钟中断与内核态
进程调度与进程切换
数据进程控制块 Env
进程控制块与初始化
由于没有在 MOS 操作系统中实现线程,所以进程既是基本的分配单元,也是基本的执行单元。
进程是一个活动中的实体,拥有自己的虚拟地址空间。
程序是非活动的实体,执行中的程序就是进程
进程控制块 - PCBstruct Env { struct Trapframe env_tf;// 保存上下文环境,定义于 trap.h 中 LIST_ENTRY(Env) env_link;// 构建空闲进程链表 env_free_link u_int env_id;// 进程标识符 u_int env_parent_id;// 父进程的进程 id u_int env_status;// 进程块状态位 Pde *env_pgdir;// 进程页目录的虚拟地址 TAILQ_ENTRY(Env) env_sched_link;// 构造调度队列 env_sched_list ...
BUAA-OS-2023-Lab3-Report
BUAA-OS-2023-Lab3-ReportThinking 3.1
Thinking 3.1 请结合MOS 中的页目录自映射应用解释代码中 e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) PTE_V 的含义
根据自映射机制可知, e->env_pgdir[PDX(UVPT)] 指的是进程块 e 的指向用户页表的页目录项,又根据页表映射的要求,这一项的内容应该是用户页表的物理地址,即PADDR(e->env_pgdir) ,再为其置有效位为1,初始化用户页表
Thinking 3.2
elf_load_seg() 以函数指针的形式,接受外部自定义的回调函数 map_page 。请你找到与之相关的 data 这一参数在此处的来源,并思考它的作用。没有这个参数可不可以?为什么?
elf_load_seg() 函数定义位于 lib/elfloader.c 中;使用仅有一处,位于 kern/env.c 的 load_icode() 函数中
首先这里的回调函数是定义在 kern/env.c 的 load_ ...
BUAA-OO-UNIT2-Summary
纸上得来终觉浅,多线程要多测试
博客撰写基本要求:
总结分析三次作业中同步块的设置和锁的选择,并分析锁与同步块中处理语句之间的关系
总结分析三次作业中的调度器设计,并分析调度器如何与程序中的线程进行交互;总结分析三次作业中的调度策略,并分析自己的调度策略是如何适应时间、电量等多个性能指标的
结合线程协同的架构模式(如流水线架构),分析和总结自己
三次作业架构设计的逐步变化和未来扩展能力画UML类图
画UML协作图(sequence diagram)来展示线程之间的协作关系(别忘记主线程)
识别出三次作业稳定的内容和易变的内容,并加以分析
分析自己程序出现过的bug以及自己面对多线程程序的debug方法
心得体会。从线程安全和层次化设计两个方面来梳理自己在本单元三次作业中获得的心得体会
注意:在编写完博客并发布在CSDN之后,请在选择要作为作业提交的博客,点击提交。
架构思路总结本单元作业,我采取了一种专精调度器的路线,调度器知晓程序内几乎所有类、线程的数据,并根据这些数据进行全局的调度,其包括:
为指定请求分派特定的电梯
唤醒、终止特定的电梯线 ...
BUAA-OS-Probe-Lab2
实验细节在进行实验前,建议通读mmu.h和pmap.h文件,了解一些宏定义,对后续工作很有帮助
名称
参数
作用
PADDR
内核虚拟地址kva
将内核虚拟地址kva转成对应的物理地址
KADDR
物理地址pa
将物理地址pa转化为内核虚拟地址
page2pa
页信息结构struct Page
通过空闲页结构得到这一页起始位置的物理地址
pa2page
物理地址pa
通过物理地址pa获取这一页对应的页结构体struct Page
page2kva
页信息结构struct PageInfo
通过空闲页结构得到这一页起始位置的虚拟地址
PDX
线性地址la
获得该线性地址la对应的页目录项索引
PTX
线性地址la
获得该线性地址la在二级页表中对应的页表项索引
PTE_ADDR(pte)
页表项或页目录项的值
获得对应的页表/地址基址(低12位为0,并均为物理地址)
内核启动后的内存分配 - 2.1
我们的操作系统内核启动后需要执行下列三个函数完成内存分配机制的建立
mips_detect_memory():探测硬件可用内存,初始化内存基本变量
mips_vm_init():建立 ...
BUAA-OS-2023-Lab2-Report
BUAA-OS-2023-Lab2-ReportThinking 2.1
虚拟地址在系统中的使用
根据指导书说明:
而在实际程序中,访存、跳转等指令以及用于取指的PC寄存器中的访存地址都是虚拟地址。 我们编写的C程序中也经常通过对指针解引用来进行访存,其中指针的值也会被视为虚拟地址,经过编译后生成相应的访存指令。
故在编写的C程序中指针存储的地址和汇编程序中lw和sw使用的值都是虚拟地址。
Thinking 2.2
链表宏与对应的链表结构
从可重用性的角度,阐述用宏来实现链表的好处。
使用宏进行链表实现,一方面能够规范系统内所有链表的存在形式,达成结构上的统一,易于编码与链表维护; 链表宏中大部分传入的参数并不是链表项整体,而是不包含链表具体存放信息的一个结构体,这个结构体只负责管理链表指针。 我们利用宏对这个结构体进行处理,一方面统一链表操作,不限制可以使用链表的结构类型;另一方面能够降低链表指针与链表内容间不必要的耦合性,维护数据安全;使用预设结构还能保证链表结构的正确性。 查阅资料后得知,除了重用性角度外,使用宏定义还意味着放置在queue.h内的所有宏都是完整的 ...