zoukankan      html  css  js  c++  java
  • 北航操作系统实验2019:Lab4-1代码实现参考

    北航操作系统实验2019:Lab4-1代码实现参考

    部分实现参考自Github前辈们的项目,经过一定程度的勘误。

    5月4日 勘误 删除了进程间通信中操作就绪状态链表的内容
    5月15日 勘误 加入了sys_ipc_can_send里复制页面的内容

    如果这份代码中存在任何问题或错误,请务必不吝在评论区指出。

    Exercise 4.1

    // user/syscall_wrap.S
    LEAF(msyscall)
        // TODO: 执行syscall指令,然后从函数返回
        syscall
        jr ra
        nop
    END(msyscall)
    

    Exercise 4.2

    // lib/syscall.S
    NESTED(handle_sys,TF_SIZE, sp)
        SAVE_ALL                            // 用于保存现场的宏
        CLI                                 // 关闭全局中断
        nop
        .set at                             // 恢复$at寄存器的使用
    
        // TODO: 取出EPC的值,计算一个合理的值(+4)后存回去
        lw t1, TF_EPC(sp)
        addiu t1, t1, 4
        sw t1, TF_EPC(sp)
    
        // TODO: 将系统调用号的值存入a0。
        // 此处因为本身系统调用号就在a0中,所以什么都不做。
    
        addiu   a0, a0, -__SYSCALL_BASE     // a0 <- 相对系统调用号
        sll     t0, a0, 2                   // t0 <- 相对系统调用号乘4
        la      t1, sys_call_table          // t1 <- 系统调用表的基地址
        addu    t1, t1, t0                  // t1 <- 特定系统调用的入口
        lw      t2, 0(t1)                   // t2 <- 读取特定系统调用的函数入口
    
        lw      t0, TF_REG29(sp)            // t0 <- 用户栈顶
        lw      t3, 16(t0)                  // t3 <- syscall的第5个参数
        lw      t4, 20(t0)                  // t4 <- syscall的第6个参数
    
        // TODO: 在当前栈内分配6个参数的空间,并将6个参数复制到合理的位置。
    	// 六个参数的位置分别是:前4个参数在a0~a3,第5、6个参数在栈内偏移16、20的位置。
    	//lw a0, TF_REG4(sp) ----- 我本地测试,这行加上之后,第二部分会7/8,不加则8/8
        addiu sp, sp, -24
        sw t3, 16(sp)
        sw t4, 20(sp)
    
        jalr    t2                          // 调用sys_*函数
        nop
    
        // TODO: 恢复当前的内核栈指针
        addiu sp, sp, 24
    
        sw      v0, TF_REG2(sp)             // 将sys_*函数的返回值存入待恢复现场的v0寄存器
    
        j       ret_from_exception          // 从异常状态中返回
        nop
    END(handle_sys)
    

    Exercise 4.3~4.6

    // lib/syscall_all.c
    void sys_yield(void)
    {
            struct Trapframe *src = (struct Trapframe *)(KERNEL_SP - sizeof(struct Trapframe));
            struct Trapframe *dst = (struct Trapframe *)(TIMESTACK - sizeof(struct Trapframe));
    
            bcopy((void*)src, (void*)dst, sizeof(struct Trapframe));
            sched_yield();
    }
    
    int sys_mem_alloc(int sysno, u_int envid, u_int va, u_int perm)
    {
            struct Env *env;
            struct Page *ppage;
            int ret;
            ret = 0;
    
            if (va >= UTOP || va < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_alloc - va illegal
    ");
                    return -E_UNSPECIFIED;
            }
    
            if ((perm & PTE_COW) || !(perm & PTE_V)) {
                    printf("Error in lib/syscall_all.c, sys_mem_alloc - perm illegal
    ");
                    return -E_INVAL;
            }
    
            if (envid2env(envid, &env, 0) < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_alloc - envid illegal
    ");
                    return -E_BAD_ENV;
            }
    
            if (page_alloc(&ppage) < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_alloc - memory insufficient
    ");
                    return -E_NO_MEM;
            }
    
            if (page_insert(env->env_pgdir, ppage, va, perm) < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_alloc - pgdir insert failed
    ");
                    return -E_NO_MEM;
            }
    
            return 0;
    }
    
    
    int sys_mem_map(int sysno, u_int srcid, u_int srcva, u_int dstid, u_int dstva, u_int perm)
    {
            int ret;
            u_int round_srcva, round_dstva;
            struct Env *srcenv;
            struct Env *dstenv;
            struct Page *ppage;
            Pte *ppte;
    
            ppage = NULL;
            ret = 0;
            round_srcva = ROUNDDOWN(srcva, BY2PG);
            round_dstva = ROUNDDOWN(dstva, BY2PG);
    
            if (srcva >= UTOP || dstva >= UTOP || srcva < 0 || dstva < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_map - va illegal
    ");
                    return -E_UNSPECIFIED;
            }
    
            if (!(perm & PTE_V)) {
                    printf("Error in lib/syscall_all.c, sys_mem_map - perm illegal
    ");
                    return -E_INVAL;
            }
    
            if (envid2env(srcid, &srcenv, 0) < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_map - srcid illegal
    ");
                    return -E_BAD_ENV;
            }
    
    
            if (envid2env(dstid, &dstenv, 0) < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_map - dstid illegal
    ");
                    return -E_BAD_ENV;
            }
    
            if ((ppage = page_lookup(srcenv -> env_pgdir, round_srcva, &ppte)) == 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_map - pgdir insert failed
    ");
                    return -E_UNSPECIFIED;
            }
    
            if (page_insert(dstenv -> env_pgdir, ppage, round_dstva, perm) < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_map - dstid illegal
    ");
                    return -E_NO_MEM;
            }
    
            return ret;
    }
    
    int sys_mem_unmap(int sysno, u_int envid, u_int va)
    {
            int ret = 0;
            struct Env *env;
    
            if (va >= UTOP || va < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_unmap - va illegal
    ");
                    return -E_INVAL;
            }
    
            if (envid2env(envid, &env, PTE_V) < 0) {
                    printf("Error in lib/syscall_all.c, sys_mem_unmap - envid illegal
    ");
                    return -E_INVAL;
            }
    
            page_remove(env -> env_pgdir, va);
    
            return ret;
    }
    

    Exercise 4.7

    // lib/syscall_all.c
    void sys_ipc_recv(int sysno, u_int dstva)
    {
            if (dstva >= UTOP) {
                    return;
            }
            curenv -> env_ipc_recving = 1;
            curenv -> env_ipc_dstva = dstva;
            curenv -> env_status = ENV_NOT_RUNNABLE;
            sys_yield();
    }
    
    int sys_ipc_can_send(int sysno, u_int envid, u_int value, u_int srcva, u_int perm)
    {
    
            int r;
            struct Env *e;
            struct Page *p;
            Pte *ppte;
    
            if (srcva >= UTOP || srcva < 0) {
                    return -E_INVAL;
            }
    
            if (envid2env(envid, &e, 0) < 0) {
                    return -E_INVAL;
            }
    
            if (e -> env_ipc_recving == 0) {
                    return -E_IPC_NOT_RECV;
            }
    
            if (srcva != 0) {
                    e -> env_ipc_perm = perm|PTE_V|PTE_R;
                    if((p=page_lookup(curenv->env_pgdir,srcva,0))<=0){
                            return -E_INVAL;
    	        }else if(page_insert(e->env_pgdir,p,e->env_ipc_dstva,perm)<0){
    		        printf("dst pot failed.
    ");
    		        return -E_INVAL;
    	        }
            }
            e -> env_ipc_recving = 0;
            e -> env_status = ENV_RUNNABLE;
            e -> env_ipc_value = value;
            e -> env_ipc_from = curenv -> env_id;
    
            return 0;
    }
    

    一并需要修改的地方

    // Lab3: lib/sched.c
    void sched_yield(void)
    {
            static struct Env *cur = NULL;
            static u_int curtime = 0;
            static int x = 0;
            while (curtime <= 0 || cur && cur -> env_status != ENV_RUNNABLE) {
                    if (cur != NULL) {
                            LIST_REMOVE(cur, env_sched_link);
                            LIST_INSERT_HEAD(&env_sched_list[1-x], cur, env_sched_link);
                    }
                    while ((LIST_FIRST(&env_sched_list[x])) == NULL) {
                            x = 1 - x;
                    }
                    cur = LIST_FIRST(&env_sched_list[x]);
                    curtime = cur -> env_pri;
            }
            curtime--;
            env_run(cur);
    }
    
  • 相关阅读:
    《Cracking the Coding Interview》——第12章:测试——题目2
    《Cracking the Coding Interview》——第12章:测试——题目1
    《Cracking the Coding Interview》——第10章:可扩展性和存储空间限制——题目7
    《Cracking the Coding Interview》——第10章:可扩展性和存储空间限制——题目6
    了解/从事机器学习/深度学习系统相关的研究需要什么样的知识结构?
    luoguP1025+codevs 1039 数的划分 x
    luogu P1223 排队接水 x
    luogu P1181 数列分段Section I x
    luogu P2661 信息传递 x
    luoguP1186 玛丽卡 x
  • 原文地址:https://www.cnblogs.com/sharinka0715/p/10792755.html
Copyright © 2011-2022 走看看