MIT 6.s081 实验解析——labs2

系列文章目录

MIT 6.s081 实验解析——labs1
MIT 6.s081 实验解析——labs2


文章目录

  • 系列文章目录
  • 测试判断流程
    • System call tracing
    • sysinfo![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ab9ca34f1fc64b6aa1df74613dc1a397.png)


测试判断流程

  1. 完成代码后将.c文件放入user文件夹中
  2. 在makefile文件的UPROGS处添加要测试的文件,如要添加的是sleep.c,则写为_sleep。
    在这里插入图片描述
  3. 重新编译xv6
make qemu
  1. 退出qemu,在文件夹下输入
./grade-lab-util <文件名>//以sleep为例
./grade-lab-util sleep

System call tracing

在这里插入图片描述

trace 32 grep hello README

以上述指令来说,这个实验想要实现的效果是,跟踪grep hello README过程中所有的系统调用,其中32为掩码,是要跟踪的系统调用种类,将32变为2进制,根据下图,在要跟踪的系统调用位置置1。在这里插入图片描述
所以先更改kernel/proc.h的进程结构体,新增掩码:

    struct proc {...int mask;};

为了实现进程间传递参数,需添加对mask的拷贝,在kernel/proc.c的fork定义中:

    intfork(void){...// Cause fork to return 0 in the child.np->trapframe->a0 = 0;np->mask = p->mask;...}

接下来就是要去完成系统调用 trace 的函数定义,在该系统调用会接收用户态传递的参数,并将其赋值给mask,我们将定义写在kernel/sysproc.c中:

    uint64sys_trace(void){int n;argint(0,&n);//接收参数myproc()->mask = n;//赋给maskreturn 0;}

为了在syscall中能调用sys_trace,我们需要将其函数入口地址存入数组static uint64 (*syscalls[])(void)中,在其末尾加入[SYS_trace] sys_trace,即可。
最后我们要在syscall调用完系统调用后,通过本进程的mask来确认这个系统调用是不是被追踪的,若是则输出相关信息,为了方便信息输出,我们为其定义一个字符串数组,修改的文件为kernel/syscall.c:

    char *str[]={[SYS_fork]    "syscall fork",[SYS_exit]    "syscall exit",[SYS_wait]    "syscall wait",[SYS_pipe]    "syscall pipe",[SYS_read]    "syscall read",[SYS_kill]    "syscall kill",[SYS_exec]    "syscall exec",[SYS_fstat]   "syscall fstat",[SYS_chdir]   "syscall chdir",[SYS_dup]     "syscall dup",[SYS_getpid]  "syscall getpid",[SYS_sbrk]    "syscall sbrk",[SYS_sleep]   "syscall sleep",[SYS_uptime]  "syscall uptime",[SYS_open]    "syscall open",[SYS_write]   "syscall write",[SYS_mknod]   "syscall mknod",[SYS_unlink]  "syscall unlink",[SYS_link]    "syscall link",[SYS_mkdir]   "syscall mkdir",[SYS_close]   "syscall close",[SYS_trace]   "syscall trace",};voidsyscall(void){int num;struct proc *p = myproc();num = p->trapframe->a7; //系统调用号if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {// Use num to lookup the system call function for num, call it,// and store its return value in p->trapframe->a0p->trapframe->a0 = syscalls[num](); //系统调用的返回值if((p->mask >> num) & 1) //若该系统调用被跟踪printf("%d: %s -> %d\n",p->pid,str[num],p->trapframe->a0);//输出信息} else {printf("%d %s: unknown sys call %d\n",p->pid, p->name, num);p->trapframe->a0 = -1;}}

描述一下整个系统调用的流程:核心点就在于可以通过usys.pl文件里对系统调用的定义,使得可以在用户空间调用系统调用。
在这里插入图片描述
在用户空间的trace.c定义了trace调用,然后通过ECALL指令触发向内核态的切换,将对应的系统调用号和参数存入寄存器,切换至内核态之后由syscall函数对调用进行响应,然后调用对应的系统调用。处理完成之后将结果返还给用户空间,再切换回用户态,完成一次系统调用。

sysinfo在这里插入图片描述

整体流程和trace差不多,获取非unused的进程数,核心就是遍历进程结构体数组proc,并判断其元素的state。

    uint64 get_used_proc(){struct proc *p;uint64 n = 0;for(p = proc; p < &proc[NPROC]; p++) {if(p->state != UNUSED) n++;}return n;}

获取空闲内存,通过查看文件kernel/kalloc.c可知每个物理内存页的单位是PGSIZE=4096字节, 以一个单链表的形式管理空闲内存页,我们只需遍历该单链表获取空闲页数,每页计一个PGSIZE即可。

    uint64 get_free_memory(){uint64 n=0;struct run* r = kmem.freelist;while(r){r=r->next;n += PGSIZE;}return n;}

将这些信息填入sysinfo结构体,然后返还给用户空间。

    uint64 sys_sysinfo(){uint64 st;argaddr(0, &st);//获取从用户空间传入的指针。struct sysinfo p;//将信息存在结构体中p.nproc = get_used_proc();p.freemem = get_free_memory();if(copyout(myproc()->pagetable, st, (char *)&p, sizeof(p)) < 0)//拷贝回用户空间return -1;return 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/329001.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySql海量数据存储与优化

一、Mysql架构原理和存储机制 1.体系结构 2.查询缓存 3.存储引擎 存储引擎的分类 innodb&#xff1a;支持事务&#xff0c;具有支持回滚&#xff0c;提交&#xff0c;崩溃恢复等功能&#xff0c;事务安全myisam:不支持事务和外键&#xff0c;查询速度高Memory&#xff1a;利…

应用OpenCV绘制箭头

绘制箭头函数 方法&#xff1a;函数cv2.arrowedLine( ) 语法格式&#xff1a;cv2.arrowedLine(img, pt1, pt2, color[, thickness[, line_type[, shift[, tipLength]]]]) 参数说明&#xff1a; img&#xff1a;要画的直线所在的图像&#xff0c;也称为画布。。 pt1&#x…

西电期末1027.判断同构数

一.题目 二.分析与思路 不用把他转成字符串再转成数字之类的&#xff0c;用数学解决就好&#xff01;找出一个数的最后位就是将其对求余啊&#xff0c;找一个数有几位以前也有过啊&#xff0c;那不就过了嘛&#xff01; 三.代码实现 #include<bits/stdc.h>//万能头 in…

msckf_vio在ubuntu20.04中的编译

1.新建catkin workspace文件夹&#xff0c;并在其中新建src文件夹&#xff0c;并将源码clone至src内。 源码地址&#xff1a;https://github.com/KumarRobotics/msckf_vio 目录层级示意如下&#xff0c;build和devel不必新建&#xff0c;后续指令会自动新建。 2. 在编译之前…

探索网络信息的利器 whois

文章目录 探索网络信息的利器 whois什么是whois命令&#xff1f;如何使用whois命令&#xff1f;注意事项 更多信息 探索网络信息的利器 whois 在网络的世界中&#xff0c;虚虚实实&#xff0c;真真假假&#xff0c;了解域名、IP地址的所有者信息是至关重要的。 Linux系统也提供…

LeetCode 2125. 银行中的激光束数量【数组,遍历】1280

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

1870_使用flx来增强counsel-M-x的模糊匹配功能

Grey 全部学习内容汇总&#xff1a; https://github.com/GreyZhang/editors_skills 1870_使用flx来增强counsel-M-x的模糊匹配功能 这一次算是趁热打铁&#xff0c;把之前优化掉了的counsel-M-x的匹配功能再推进一步。虽然还是没有达到spacemacs中的乱序匹配效果&#xff0c…

第14届蓝桥杯省赛scratch真题+解题思路+详细解析

一、选择题 一共有5道选择题&#xff0c;每题10分&#xff0c;共50分&#xff0c;严禁使用程序验证&#xff0c;选择题不答和答错不得分。 1. 运行以下程序&#xff0c;舞台上能看到几只小猫&#xff1f;&#xff08; &#xff09; A. 4 B. 5 C. 6 D. 7 答案&#xff…

序列模型(3)—— LLM的参数量和计算量

本文说明以下重要结论 设模型参数量为 N N N&#xff0c;训练数据量&#xff08;Token&#xff09;为 D D D&#xff0c;LLM训练中计算量&#xff08;FLOPs&#xff09; C ≈ 6 N D C\approx 6ND C≈6ND 参考&#xff1a; 模型训练计算量到底怎么算分析transformer模型的参数…

主流大语言模型从预训练到微调的技术原理

引言 本文设计的内容主要包含以下几个方面&#xff1a; 比较 LLaMA、ChatGLM、Falcon 等大语言模型的细节&#xff1a;tokenizer、位置编码、Layer Normalization、激活函数等。大语言模型的分布式训练技术&#xff1a;数据并行、张量模型并行、流水线并行、3D 并行、零冗余优…

分布式事务完美解决方案:消息中间件(kafka)+ 本地事物 + 消息校对

前言 分布式事务是要保证多个服务下的多个数据库操作的一致性。分布式事务常见解决方案有&#xff1a;二阶段、三阶段和TCC实现强一致性事务&#xff0c;其实还有一种广为人知的方案就是利用消息队列来实现分布式事务&#xff0c;保证数据的最终一致性&#xff0c;也就是我们常…

Landsat8的辐射定标与大气校正

目录 打开影像辐射定标大气校正计算区域高程计算研究区高程大气校正查看处理结果 打开影像 在文件夹中找到xxx_MTL.txt文件&#xff0c;拖到ENVI中 此处可能会出现无法打开的问题&#xff0c;参考该文章&#xff08;ENVI无法打开Landsat8的头文件问题和解决&#xff09; 辐…