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.rhkb.cn/news/232740.html

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

相关文章

服务器磁盘挂载及格式化

一边学习,一边总结,一边分享! 写在前面 最近一直折腾组装的电脑,来回折腾了很久关于我花费六千多组了台window+Linux主机,目前基本是可以使用了。对于Windows主机配置基本是没问题,一直在使用,以及桌面化软件,都可以自己安装,只是说这台主机有些软件可能一时半会安装…

互联网分布式应用之SpringDataJPA

SpringDataJPA Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。 课程内容的介绍 1. Spring整合Hibernate 2…

[C#]使用纯opencvsharp部署yolov8-onnx图像分类模型

【官方框架地址】 https://github.com/ultralytics/ultralytics.git 【算法介绍】 YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基础上&#xff0c;并引入了新的功能和改进&#xff0c;以进一步提升性能和灵活性。具体创新包括一个新的骨干网络、一个新…

CSS 压重按钮 效果

<template><view class="cont"><div class="container"><div class="pane"><!-- 选项1 --><label class="label" @click="handleOptionClick(0)":style="{ color: selectedOption ==…

精进单元测试技能 —— Pytest断言的艺术!

本篇文章主要是阐述Pytest在断言方面的应用。让大家能够了解和掌握Pytest针对断言设计了多种功能以适应在不同测试场景上使用。 了解断言的基础 在Pytest中&#xff0c;断言是通过 assert 语句来实现的。简单的断言通常用于验证预期值和实际值是否相等&#xff0c;例如&#…

FlinkSQL中【FULL OUTER JOIN】使用实例分析(坑)

Flink版本&#xff1a;flink1.14 最近有【FULL OUTER JOIN】场景的实时数据开发需求&#xff0c;想要的结果是&#xff0c;左右表来了数据都下发数据&#xff1b;左表存在的数据&#xff0c;右表进来可以关联下发&#xff08;同样&#xff0c;右表存在的数据&#xff0c;左表进…

FlinkAPI开发之数据合流

案例用到的测试数据请参考文章&#xff1a; Flink自定义Source模拟数据流 原文链接&#xff1a;https://blog.csdn.net/m0_52606060/article/details/135436048 概述 在实际应用中&#xff0c;我们经常会遇到来源不同的多条流&#xff0c;需要将它们的数据进行联合处理。所以…

Apache Paimon:Streaming Lakehouse is Coming

摘要&#xff1a;本文整理自阿里云智能开源表存储负责人&#xff0c;Founder of Paimon&#xff0c;Flink PMC 成员李劲松&#xff08;花名&#xff1a;之信&#xff09;、同程旅行大数据专家&#xff0c;Apache Hudi & Paimon Contributor 吴祥平、汽车之家大数据计算平台…

Mybatis实现增删改查的两种方式-配置文件/注解

环境准备 1.数据库表tb_brand -- 删除tb_brand表 drop table if exists tb_brand; -- 创建tb_brand表 create table tb_brand(-- id 主键id int primary key auto_increment,-- 品牌名称brand_name varchar(20),-- 企业名称company_name varchar(20),-- 排序字段ordered int…

[Flutter]WebPlatform上运行遇到的问题总结

[Flutter]WebPlatform上运行遇到的问题总结 目录 [Flutter]WebPlatform上运行遇到的问题总结 写在开头 正文 Q1、不兼容判断 Q2、跨域问题 其他 写在结尾 写在开头 Flutter项目已能在移动端完美使用后&#xff0c;想看看在桌面端等使用情况 基于Flutter3.0后已支持Wi…

前端框架中的状态管理(State Management)

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

李沐-《动手学深度学习》-- 01-预备知识

一、线性代数知识 1. 矩阵计算 a. 矩阵求导 ​ 当y和x分别为标量和向量时候&#xff0c;进行求导得到的矩阵形状&#xff0c;矩阵求导就是矩阵A中的每一个元素对矩阵B中的每一个元素求导 ​ 梯度指向的是值变化最大的方向 ​ 分子布局和分母布局&#xff1a; b. 常识 ax…

知识付费平台搭建?找明理信息科技,专业且高效

明理信息科技知识付费saas租户平台 在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和…

群晖NAS+DMS7.0以上版本+无docker机型安装zerotier

测试机型&#xff1a;群晖synology 218play / DSM版本为7.2.1 因218play无法安装docker&#xff0c;且NAS系统已升级为7.0以上版本&#xff0c;按zerotier官网说法无法安装zerotier, 不过还是可以通过ssh终端和命令方式安装zerotier。 1、在DSM新建文件夹 用于存放zerotier脚…

2023我的编程之旅-地质人的山和水

引言 大家好&#xff0c;我是搞地质的。外行人有的说我们游山玩水&#xff0c;有的说我们灰头土脸&#xff0c;也有的说我们不是科学。 而我说&#xff0c;这是一门穷极一生青春&#xff0c;值得奉献的行业。这是一门贴近民生&#xff0c;又拥抱自然的学科。他的真理性在于探…

进阶学习——Linux系统安全及应用

目录 一、系统安全加固 1.账号安全基本措施 1.1系统账号清理 1.1.1延伸 1.2密码安全控制 1.3命令历史限制 1.4终端自动注销 二、使用su命令切换用户 1.用途及用法 2.密码验证 3.限制使用su命令的用户 4.查看su操作记录 5.sudo&#xff08;superuse do&#xff09;…

stable diffusion 人物高级提示词(一)头部篇

一、女生发型 prompt描述推荐用法Long hair长发一定不要和 high ponytail 一同使用Short hair短发-Curly hair卷发-Straight hair直发-Ponytail马尾high ponytail 高马尾&#xff0c;一定不要和 long hair一起使用&#xff0c;会冲突Pigtails2条辫子-Braid辫子只写braid也会生…

数据库开发必备神器:DataGrip 工具安装指南

DataGrip是一款强大的跨平台数据库集成开发环境&#xff0c;全能数据库工具&#xff0c;支持多种数据库系统&#xff0c;包括MySQL&#xff0c;PostgreSQL&#xff0c;Oracle等&#xff1b;提供智能代码编辑功能&#xff0c;包括语法高亮、代码补全等&#xff0c;提升开发效率。…

Qt/QML编程学习之心得:Linux下Thread线程创建(26)

GUI设计中经常为了不将界面卡死,会用到线程Thread,而作为GUI设计工具,Qt也提供了一个这样的类,即QThread。 QThread对象管理程序中的一个控制线程。线程QThread开始在run()中执行。默认情况下,run()通过调用exec()启动事件循环,并在线程内运行Qt事件循环。 也可以通过…

YTM32的低功耗PowerDown模式及唤醒管理器WKU模块

文章目录 Introduction专门的唤醒源管理器WKU外部的唤醒引脚内部的触发信号 进入PowerDown模式的操作流进入低功耗模式配合使用的其他模块 性能指标低功耗电流唤醒时间 Conclusion Introduction YTM32的低功耗系统中有设计了多种工作模式&#xff0c;功耗从高到低&#xff0c;…