北航操作系统实验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\n");
return -E_UNSPECIFIED;
} if ((perm & PTE_COW) || !(perm & PTE_V)) {
printf("Error in lib/syscall_all.c, sys_mem_alloc - perm illegal\n");
return -E_INVAL;
} if (envid2env(envid, &env, 0) < 0) {
printf("Error in lib/syscall_all.c, sys_mem_alloc - envid illegal\n");
return -E_BAD_ENV;
} if (page_alloc(&ppage) < 0) {
printf("Error in lib/syscall_all.c, sys_mem_alloc - memory insufficient\n");
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\n");
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\n");
return -E_UNSPECIFIED;
} if (!(perm & PTE_V)) {
printf("Error in lib/syscall_all.c, sys_mem_map - perm illegal\n");
return -E_INVAL;
} if (envid2env(srcid, &srcenv, 0) < 0) {
printf("Error in lib/syscall_all.c, sys_mem_map - srcid illegal\n");
return -E_BAD_ENV;
} if (envid2env(dstid, &dstenv, 0) < 0) {
printf("Error in lib/syscall_all.c, sys_mem_map - dstid illegal\n");
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\n");
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\n");
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\n");
return -E_INVAL;
} if (envid2env(envid, &env, PTE_V) < 0) {
printf("Error in lib/syscall_all.c, sys_mem_unmap - envid illegal\n");
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.\n");
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);
}

北航操作系统实验2019:Lab4-1代码实现参考的更多相关文章

  1. 北航操作系统实验2019:Lab4-1流程梳理

    北航操作系统实验2019:Lab4-1流程梳理 前言 操作系统的实验课实在令人头秃.我们需要在两周时间内学习相关知识.读懂指导书.读懂代码.补全代码.处理玄学bug和祖传bug,以及回答令人窒息的思考 ...

  2. [操作系统实验lab3]实验报告

    [感受] 这次操作系统实验感觉还是比较难的,除了因为助教老师笔误引发的2个错误外,还有一些关键性的理解的地方感觉还没有很到位,这些天一直在不断地消化.理解Lab3里的内容,到现在感觉比Lab2里面所蕴 ...

  3. sdut oj 操作系统实验--SSTF磁盘调度算法【操作系统算法】

    操作系统实验--SSTF磁盘调度算法 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 磁盘调度在多道程序设计的计算机系统中,各个进 ...

  4. Lab_0操作系统实验准备(全)

    一.实验介绍 实验目的: 知识储备: 二.相关下载 1.下载镜像文件 这个镜像文件是vdi类型的,只能用visualbox下载 链接:https://pan.baidu.com/s/1L7WX6ju4 ...

  5. 操作系统实验(一)-Shell编程

    操作系统实验:Shell编程 emmmmm,实验前老师发了一份实验说明,里面有教怎么配置虚拟机Ubuntu.这里就不做过多叙述,需要说明的是,kali和ubuntu都可以以shell运行这个C语言程序 ...

  6. 操作系统实验一:进程管理(含成功运行C语言源代码)

    目录 操作系统实验一:进程管理 1.实验目的 2.实验内容 3.实验准备 3.1.1进程的含义 3.1.2进程的状态 3.1.3进程状态之间的转换 3.2 进程控制块PCB 3.2.1进程控制块的作用 ...

  7. [No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

    操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock 可以操刀了—从纸上到实际 从Linux 0.11 那里学点东西… 读磁盘 ...

  8. [Java] 实验5參考代码

    实验4月3日晚截止,实验截止后将在此给出完整的參考代码. 1. 怎样使用以下的代码模板: 1.1 在eclipse中创建相应名称的类     1.2 将代码拷贝到类文件中 1.3 在//todo凝视中 ...

  9. [Java] 实验6參考代码

    1. 大家的.java程序都须要在一个"缺省包"(default package)下编写\执行\提交,不要去命名新的package     - 系统不支持package contr ...

随机推荐

  1. TMapCoordinate

    MapPiter.Location := TMapCoordinate.Create(59.965, 30.35); MapPiter.Zoom := 10;

  2. Apache ZooKeeper 单机、集群部署文档

    简介: Apache ZooKeeper 是一个分布式应用的高性能协调服务,功能包括:配置维护.统一命名.状态同步.集群管理.仲裁选举等. 下载地址:http://apache.fayea.com/z ...

  3. Maven编译并打包Mahout CDH版源码

    目录 1. 问题描述 最近在使用Mahout里的推荐算法进行实验,由于业务需求,需要修改Mahout源码,将原本输出到HDFS上的结果输出到HBase中.由于Mahout发布的源码都是Maven项目, ...

  4. Attribute与元数据

    在MSDN中,Attribute被定义为“是被指定给某一声明的一则附加的声明性信息”. 我们可以通过Attribute来定义设计层面的信息以及运行时(run-time)信息,也可以利用Attribut ...

  5. tar使用

    [tar使用] 1..tar.gz文件 压缩:tar -czvf dstFileName.tar.gz a.txt b.txt …… 解压:tar -xzvf fileName.tar.gz 2..t ...

  6. MYSQL TIMESTAMP with implicit DEFAULT value is deprecated.

    TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp se ...

  7. S导入部门数据 更新父部门、责任人

    导入部门数据分两步骤,EXCEL模板可以一样 一.导入部门主数据,导入时选择INSERT (注意以下还有问题,父区域会自动带出一个值) [Public] ConnectString=host=&quo ...

  8. R_CNN

    https://blog.csdn.net/briblue/article/details/82012575 背景本篇论文的题目是 <Rich feature hierarchies for a ...

  9. Search Quick Union Find(图的存储结构)

    Quick Find:适用于search频繁的情况 每个节点有一个id值,id相同表示两个节点相连通.在union时要将等于某一个id值都改成另一个id值 Quick Union: 适用于union频 ...

  10. JVM配置参数

    .堆内存相关的JVM参数 —Xms 初始堆大小 —Xmx 最大堆大小 —Xss 线程栈大小 —XX:MinHeapFreeRatio 设置堆空间最小空闲比例 —XX:MaxHeapFreeRatio ...