操作系统lab4实验报告
本次实验将接触的是内核线程的管理。内核线程是一种特殊的进程,内核线程与用户进程的区别有两个:内核线程只运行在内核态而用户进程会在在用户态和内核态交替运行;所有内核线程直接使用共同的ucore
内核内存空间,不需为每个内核线程维护单独的内存空间而用户进程需要维护各自的用户内存空间。
在本次实验完成之后,为了加深理解,我这里简单将之前的所有代码又重新阅读并梳理了一遍,简单作了下总结。
这里主要是从kern_init
函数的物理内存管理初始化开始的,截图如下:
按照函数的次序我进行了简单的总结如下:
- 1、
pmm_init()
- (1) 初始化物理内存管理器。
- (2) 初始化空闲页,主要是初始化物理页的 Page 数据结构,以及建立页目录表和页表。
- (3) 初始化 boot_cr3 使之指向了 ucore 内核虚拟空间的页目录表首地址,即一级页表的起始物理地址。
- (4) 初始化第一个页表 boot_pgdir。
- (5) 初始化了GDT,即全局描述符表。
- 2、
pic_init()
- 初始化8259A中断控制器
- 3、
idt_init()
- 初始化IDT,即中断描述符表
- 4、
vmm_init()
- 主要就是实验了一个 do_pgfault()函数达到页错误异常处理功能,以及虚拟内存相关的 mm,vma 结构数据的创建/销毁/查找/插入等函数
- 5、
proc_init()
- 这个函数启动了创建内核线程的步骤,完成了 idleproc 内核线程和 initproc 内核线程的创建或复制工作,这是本次实验分析的重点,后面将详细分析。
- 6、
ide_init()
- 完成对用于页换入换出的硬盘(简称 swap 硬盘)的初始化工作
- 7、
swap_init()
- swap_init() 函数首先建立完成页面替换过程的主要功能模块,即 swap_manager ,其中包含了页面置换算法的实现
练习0 填写已有实验
同样我们运用meld
软件进行比较。大致截图如下:
经过比较和修改,我将我所需要修改的文件罗列如下:
default_pmm.c
pmm.c
swap_fifo.c
vmm.c
trap.c
练习1 分配并初始化一个进程控制块
操作系统是以进程为中心设计的,所以其首要任务是为进程建立档案,进程档案用于表示、标识或描述进程,即进程控制块。这里需要完成的就是一个进程控制块的初始化。
而这里我们分配的是一个内核线程的PCB
,它通常只是内核中的一小段代码或者函数,没有用户空间。而由于在操作系统启动后,已经对整个核心内存空间进行了管理,通过设置页表建立了核心虚拟空间(即boot_cr3
指向的二级页表描述的空间)。所以内核中的所有线程都不需要再建立各自的页表,只需共享这个核心虚拟空间就可以访问整个物理内存了。
首先在kern/process/proc.h
中定义了PCB
即进程控制块的结构体proc_struct
,如下:
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;