操作系统实验报告 lab5

本次实验旨在深入理解操作系统中用户进程的创建、系统调用的执行流程,包括idt_init、trip_dispatch、alloc_proc、do_fork函数的分析,以及load_icode在加载应用程序中的作用。实验内容涵盖进程复制、系统调用服务如fork、exec、wait、exit的实现。通过实践,加深了对ucore中系统调用框架和进程管理的理解。
摘要由CSDN通过智能技术生成

实验目的:
1.了解第一个用户进程创建过程
2.了解系统调用框架的实现机制
3.了解ucore如何实现系统调用sys_fork/sys_exec/sys_exit/sys_wait来进行进程管理

练习0 填写已有实验

利用meld软件进行对比,截图如下
这里写图片描述
找到要修改的地方:

proc.c
default_pmm.c
pmm.c
swap_fifo.c
vmm.c
trap.c
kdebug.c

题目并没有结束,还要将代码进一步改进

idt_init函数

    /* LAB5 YOUR CODE */   
         //you should update your lab1 code (just add ONE or TWO lines of code), let user app to use syscall to get the service of ucore  
         //so you should setup the syscall interrupt gate in here  
        extern uintptr_t __vectors[];  
        int i;  
        for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {  
            SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);  
        }  
    SETGATE(idt[T_SYSCALL], 1, GD_KTEXT, __vectors[T_SYSCALL], DPL_USER);//设置相应中断门即可  
    lidt(&idt_pd);  

改进SETGATE(idt[T_SYSCALL], 1, GD_KTEXT, __vectors[T_SYSCALL], DPL_USER);//设置相应中断门即可
在上述代码中,可以看到在执行加载中断描述符表lidt指令前,专门设置了一个特殊的中断描述符idt[T_SYSCALL],它的特权级设置为DPL_USER,中断向量处理地址在__vectors[T_SYSCALL]处。这样建立好这个中断描述符后,一旦用户进程执行“INT T_SYSCALL”后,由于此中断允许用户态进程产生(注意它的特权级设置为DPL_USER),所以CPU就会从用户态切换到内核态,保存相关寄存器,并跳转到__vectors[T_SYSCALL]处开始执行,形成如下执行路径:
vector128(vectors.S)--\>
\_\_alltraps(trapentry.S)--\>trap(trap.c)--\>trap\_dispatch(trap.c)----\>syscall(syscall.c)-

在syscall中,根据系统调用号来完成不同的系统调用服务。

trip_dispatch函数



    /* LAB5 YOUR CODE */  
            /* you should upate you lab1 code (just add ONE or TWO lines of code): 
             *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1 
             */  
            ticks ++;  
            if (ticks % TICK_NUM == 0) {  
                assert(current != NULL);  
                current->need_resched = 1;//时间片用完设置为需要调度  
            }  

代码改进current->need_resched = 1;//时间片用完设置为需要调度

alloc_proc函数

    //LAB5 YOUR CODE : (update LAB4 steps)  
        /* 
         * below fields(add in LAB5) in proc_struct need to be initialized   
         *       uint32_t wait_state;                        // waiting state 
         *       struct proc_struct *cptr, *yptr, *optr;     // relations between processes 
         */  
        proc->state = PROC_UNINIT;//设置进程为未初始化状态
        proc->pid = -1;          //未初始化的进程id=-1
        proc->runs = 0;          //初始化时间片
        proc->kstack = 0;      //初始化内存栈的地址
        proc->need_resched = 0;   //是否需要调度设为不需要
        proc->parent = NULL;      //置空父节点
        proc->mm = NULL;      //置空虚拟内存
        memset(&(proc->context), 0, sizeof(struct context));//初始化上下文
        proc->tf = NULL;      //中断帧指针设置为空
        proc->cr3 = boot_cr3;      //页目录设为内核页目录表的基址
        proc->flags = 0;      //初始化标志位
        memset(proc->name, 0, PROC_NAME_LEN);//置空进程名
        proc->wait_state = 0;  //初始化进程等待状态  
        proc->cptr = proc->optr = proc->yptr = NULL;//进程相关指针初始化  

代码改进
proc->wait_state = 0; //初始化进程等待状态
proc->cptr = proc->optr = proc->yptr = NULL;//进程相关指针初始化

实验涉及到用户进程,所以会用涉及调度问题,进程相关指针会被初始化

do_fork函数

    //LAB5 YOUR CODE : (update LAB4 steps)  
       /* Some Functions 
        *    set_links:  set the relation links of process.  ALSO SEE: remove_links:  lean the relation links of process  
        *    ------------------- 
        *    update step 1: set child proc's parent to current process, make sure current process's wait_state is 0 
        *    update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process 
        */  
        if ((proc = alloc_proc()) == NULL) {  
            goto fork_out;  
        }  
        proc->parent = current;  
        assert(current->wait_state == 0); //确保当前进程为等待进程  
        if (setup_kstack(proc) != 0) {  
            goto bad_fork_cleanup_proc;  
        }  
        if (copy_mm(clone_flags, proc) != 0) {  
            goto bad_fork_cleanup_kstack;  
        }  
        copy_thread(proc, stack, tf);  
        bool intr_flag;  
        local_intr_save(intr_flag);  
        {  
            proc->pid = get_pid();  
            hash_proc(proc);  
            set_links(proc);//设置进程的相关链接  
        }  
        local_intr_restore(intr_flag);  
        wakeup_proc(proc);  
    ret = proc->pid;  

代码改进
assert(current->wait_state == 0); //确保当前进程为等待进程

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值