操作系统 lab4 实验报告

练习0

填写已有实验
  本实验依赖实验1~3.请把已做的实验1~实验3的代码填入本实验中代码中有lab1、lab2、lab3的注释相应部分

首先利用meld工具比较两个文件的差异
这里写图片描述

这里写图片描述

  发现缺失的是kdebug.c、trap.c、default_pmm.c、pmm.c、swap_fifo.c vmm.c四个文件的相关代码,补全后进行下一练习

练习1

分配并初始化一个进程控制块(需要编程)
  alloc_proc函数(位于kern/process/proc.c中)负责分配并返回一个新的struct proc_struct结构,用于存储新建立的内核线程的管理信息。ucore需要对这个结构进行最基本的初始化,本练习要求完成这个初始化过程

首先简单说明一下内核线程与用户进程的区别:

  内核线程只运行在内核态。用户进程会在在用户态和内核态交替运行所有内核线程共用ucore内核内存空间,不需为每个内核线程维护单独的内存空间,而用户进程需要维护各自的用户内存空间。

  首先在kern/process/proc.h中定义了进程控制块的结构体proc_struct

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;                       // 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
};

这里简单介绍下各个参数:

  • mm:内存管理的信息,包括内存映射列表、页表指针等,即实验三中的描述进程虚拟内存的结构体. mm 里有个很重要的项pgdir,记录的是该进程使用的一级页表的物理地址。
  • state:进程所处的状态。

    PROC_UNINIT // 未初始状态
    PROC_SLEEPING // 睡眠(阻塞)状态
    PROC_RUNNABLE // 运行与就绪态
    PROC_ZOMBIE // 僵死状态
    
  • pid:进程id号。

  • parent:用户进程的父进程(创建它的进程)。在所有进程中,只有一个进程没有父进程,就是内核创建的第一个内核线程 idleproc。内核根据这个父子关系建立进程的树形结构,用于维护一些特殊的操作,例如确定哪些进程是否可以对另外一些进程进行什么样的操作等等。
  • context:进程的上下文,用于进程切换。 在ucore 中,所有的进程在内核中也是相对独立的(例如独立的内核堆栈以及上下文等等)。使用context保存寄存器的目的就在于在内核态中能够进行上下文之间的切换。
  • tf:中断帧的指针,总是指向内核栈的某个位置:当进程从用户空间跳到内核空间时,中断帧记录了进程在被中断前的状态。当内核需要跳回用户空间时,需要调整中断帧以恢复让进程继续执行的各寄存器值。除此之外,ucore 内核允许嵌套中断。因此为了保证嵌套中断发生时 tf 总是能够指向当前的 trapframe, ucore 在内核桟上维护了 tf 的链。
  • cr3: cr3 保存页表的物理地址,目的就是进程切换的时候方便直接使用 lcr3 实现页表切换,避免每次都根据 mm 来计算 cr3。 mm 数据结构是用来实现用户空间的虚存管理的,但是内核线程没有用户空间,它执行的只是内核中的一小段代码(通常是一小段函数),所以它没有 mm 结构,也就是 NULL。当某个进程是一个普通用户态进程的时候, PCB 中的 cr3 就是 mm 中页表( pgdir)的物理地址;而当它是内核线程的时候, cr3 等于 boot_cr3。 而 boot_cr3 指向了 ucore 启动时建立好的栈内核虚拟空间的页目录表首地址。
  • kstack:每个进程都有一个内核桟,并且位于内核地址空间的不同位置。对于内核线程, 该桟就是运行时的程序使用
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值