操作系统实验ucore lab4

阅读前注意事项:

1、我的博客从lab2之后,如果没有特殊说明,所有标注的代码行数位置,以labcodes_answer(答案包)里的文件为准!!!因为你以后会发现做实验用meld软件比较费时费力,对于咱们学校的验收不如直接对着答案来;

2、感谢网上的各路前辈大佬们,本人在这学期初次完成实验的过程中,各位前辈们的博客给了我很多有用的指导;本人的博客内容在现有的内容上,做了不少细节的增补内容,有些地方属个人理解,如果有错在所难免,还请各位大佬们批评指正;

3、所有实验的思考题,我把它规整到了文章最后;

4、所有实验均默认不做challenge,对实验评分无影响;

5、湖南大学的实验顺序为1 4 5 6 7 2 3 8,在实验4-7过程中涉及到实验二三的页表虚存问题,当做黑盒处理,没有过多探索。

 

一、实验内容

当一个程序加载到内存中运行时, 首先通过ucore OS的内存管理子系统分配合适的空间, 然后就需要考虑如何分时使用CPU来“并发”执行多个程序, 让每个运行的程序(这里用线程或进程表示) “感到”它们各自拥有“自己”的CPU。

本次实验将首先接触的是内核线程的管理。 内核线程是一种特殊的进程, 内核线程与用户进程的区别有两个:内核线程只运行在内核态,用户进程会在在用户态和内核态交替运行,所有内核线程共用ucore内核内存空间, 不需为每个内核线程维护单独的内存空间,而用户进程需要维护各自的用户内存空间。

 

二、目的

了解内核线程创建/执行的管理过程

了解内核线程的切换和基本调度过程

 

三、实验设计思想和流程

 

练习1:分配并初始化一个进程控制块(需要编码)

alloc_proc函数(位于kern/process/proc.c86行中,参考proc.h文件)负责分配并返回一个新的struct proc_struct结构,用于存储新建立的内核线程的管理信息。ucore需要对这个结构进行最基本的初始化,你需要完成这个初始化过程。

【提示】在alloc_proc函数的实现中,需要初始化的proc_struct结构中的成员变量至少包括:state/pid/runs/kstack/need_resched/parent/mm/context/tf/cr3/flags/name。

 

首先找到kern/process/proc.c,需要填写的alloc_proc函数中有这么一段注释,它主要定义了一个结构体proc_struct,它也说,我们需要初始化这样一个结构体的一个对象并返回它。

这个结构体的详细定义在同一文件夹下的proc.h中的42——57行也能找到:

struct proc_struct {
    enum proc_state state;	        // Process state
    int pid;		                // Process ID
    int runs;		                // the running times of Proces
    uintptr_t kstack;		        // Process kernel stack
    volatile bool need_resched;		// bool value: need to be rescheduled to release CPU?
    struct proc_struct *parent;		// the parent process
    struct mm_struct *mm;			// Process's memory management field
    struct context context;			// Switch here to run process
    struct trapframe *tf;			// Trap frame for current interrupt
    uintptr_t cr3;				// CR3 register: the base addr of Page Directroy Table(PDT)
    uint32_t flags;			        // Process flag
    char name[PROC_NAME_LEN + 1];		// Process name
    list_entry_t list_link;			// Process link list 
    list_entry_t hash_link;			// Process hash list
};

alloc_proc,这个函数的返回语句是“return proc”,其中proc就是这个proc_struct的一个对象。

其实这里我们需要初始化的一个东西就是proc_struct的一个对象,分配的是一个内核线程的PCB,它通常只是内核中的一小段代码或者函数,没有用户空间。而由于在操作系统启动后,已经对整个核心内存空间进行了管理,所以内核中的所有线程都不需要再建立各自的页表,只需共享这个核心虚拟空间就可以访问整个物理内存了。(这里需要指出的一个重点是,虽然名字叫做内核线程,但是内核线程是一种特殊的进程,来自指导书P167)

PCB包括进程状态,进程编号,程序计数器、寄存器等各种参数,和上面这个结构体一比较,可以确定这就是一个标准的PCB,我们需要做的东西就是初始化它,也可以看做给一个新开辟的内核线程(进程)做初始化。

反过来看这个结构体里面定义的PCB参数,经过分析我们可以得到以下含义:

 

state:进程所处的状态,这个在proc.h的第11行——15行有定义,具体如下:

PROC_UNINIT		//未初始状态
PROC_SLEEPING 		//睡眠(阻塞)状态
PROC_RUNNABLE		//运行与就绪态
PROC_ZOMBIE		//僵尸状态

pid:进程id号。这个非常熟悉了。

runs:进程运行的时间,既然任务是初始化,那么runs必须是零。

kstack:记录了分配给该进程/线程的内核桟的位置。这个地方,在没有基于前三个实验代码补全lab4的源代码之前,似乎运行会出问题,如果补全了,运行就不会报错。因为这里记录的是分配给该进程在内存中的栈位置,推测相关操作应该和lab2和lab3有关。

need_resched:是否需要调度,目前实验未到这一步,暂时不管。

parent:用户进程的父进程,这是一个指针变量,记录它的父进程是谁。在所有进程中,只有一个进程没有父进程,就是内核创建的第一个内核线程idleproc。

mm:注释说它负责管理进程的虚拟memory,其实就是内存管理的信息,包括内存映射列表、页表指针等。mm成员变量在lab3中用于虚存管理。但在实际OS中,内核线程常驻内存,不需要考虑swap page问题,mm应该和23有关,暂时不管

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值