当前位置: 首页 > news >正文

Lab2_Simple Shell_2020

Lab2: 实验目的:给xv6添加新的系统调用

并理解系统调用是如何工作的,并理解xv6内核的一些内部特征

实验准备:

  1. 阅读xv6的第2章以及第4章的4.3,4.3小节
  2. 熟悉下面的源码
  • 用户态相关的代码:user/user.huser/usys.pl
  • 内核态相关的代码:kernel/syscall.hkernel/syscall.h
  • 进程相关的代码:kernel/proc.kernel/proc.c

​ 3. 阅读KR大佬C语言书的如下章节

 2.9 (Bitwise operators) and 5.1 (Pointers and addresses) through 5.6 (Pointer arrays) and 6.4 (pointers to structures) by Kernighan and Ritchie (K&R)

任务1:系统调用跟踪功能 System call tracing (moderate)

In this assignment you will add a system call tracing feature that may help you when debugging later labs. You’ll create a new trace system call that will control tracing. It should take one argument, an integer “mask”, whose bits specify which system calls to trace. For example, to trace the fork system call, a program calls trace(1 << SYS_fork), where SYS_fork is a syscall number from kernel/syscall.h. You have to modify the xv6 kernel to print out a line when each system call is about to return, if the system call’s number is set in the mask. The line should contain the process id, the name of the system call and the return value; you don’t need to print the system call arguments. The trace system call should enable tracing for the process that calls it and any children that it subsequently forks, but should not affect other processes.

在本作业中,你需要添加一个系统调用跟踪功能,该功能可能会在以后调试实验室时对您有所帮助。您将创建一个新的“trace”系统调用来控制跟踪。它应该有一个参数,一个int 类型的“mask”,其bits位说明要跟踪的系统调用。例如,为了跟踪fork系统调用,程序调用trace(1 << SYS_fork),其中SYS_fork是来自kernel/syscall.h的系统调用号。如果在mask中设置了系统调用的编号,则必须修改xv6内核,以便在每个系统调用即将返回时打印出一行数据。该行应包含进程id、系统调用的名称和返回值;不需要打印系统调用参数。trace这个系统调用函数应启用对调用它的进程及其随后fork的任何子进程的跟踪,但不应影响其他进程。

我们提供了一个用户态的trace程序,它运行另一个启用了跟踪的程序(参见user/trace.c)。完成后,您应该看到如下输出:

$ trace 32 grep hello README
3: syscall read -> 1023
3: syscall read -> 966
3: syscall read -> 70
3: syscall read -> 0
$
$ trace 2147483647 grep hello README
4: syscall trace -> 0
4: syscall exec -> 3
4: syscall open -> 3
4: syscall read -> 1023
4: syscall read -> 966
4: syscall read -> 70
4: syscall read -> 0
4: syscall close -> 0
$
$ grep hello README
$
$ trace 2 usertests forkforkfork
usertests starting
test forkforkfork: 407: syscall fork -> 408
408: syscall fork -> 409
409: syscall fork -> 410
410: syscall fork -> 411
409: syscall fork -> 412
410: syscall fork -> 413
409: syscall fork -> 414
411: syscall fork -> 415
...
$ 

在上面的第一个例子中,trace调用grep tracing,而仅仅是read系统调用。32是1<<SYS_read(1<<5 = 2^5=32)的结果。在第二个例子中,trace在跟踪所有系统调用时运行grep;2147583647具有全部31个低位(2^31 = 2147583647)。在第三个示例中,程序没有被跟踪,因此没有打印跟踪输出。在第四个示例中,跟踪usertests(forkforkfork)程序中所有的fork系统调用(包含所有的子进程)。如果你的程序的输出如上所示,则解决方案是正确的(尽管进程ID可能不同)。

我们需要增加一个trace的系统调用,trace 接受一个int型参数,用来设置具体哪些系统调用函数需要跟踪到;

例如 trace 32意思SYS_read 函数需要被跟踪,32是1<<SYS_read(1<<5 = 2^5=32)的结果 ;

具体修改如下所示:

  • Add $U/_trace to UPROGS in Makefile

  • 运行make qemu,你将看到编译器无法编译user/trace.c,因为系统调用的用户空间存根还不存在:将系统调用的原型添加到user/user.h,将存根添加到user/usys.pl,以及对应的syscall编号添加到kernel/syscall.h。Makefile会先调用perl脚本user/usys.pl,它生成user/usys.S,即实际的系统调用存根,它使用RISC-v的ecall指令转换到内核。一旦你修复了编译问题,运行trace32 grep hello README;它将失败,因为您尚未在内核中实现系统调用。

    image-20210514153148919

    image-20210514153233553

    image-20210514153328513

  • kernel/sysproc.c中添加一个sys_trace() 函数,通过在proc结构体的新增加一个变量,我们这里用的是char mask[23]中记住其参数来实现新的系统调用(kernel/proc.h)。这个函数需要从用户空间检索系统调用的参数kernel/syscall.c中,你可以在kernel/sysproc.c中看到它们的使用示例。

    // kernel/sysproc.c 增加下面函数
    uint64
    sys_trace(void)
    {int n;// 获取n之后,如果小于0,也返回-1if(argint(0, &n) < 0 && n < 0)return -1;// 通过n控制哪些系统调用函数需要被trace // n=32是`1<<SYS_read(1<<5 = 2^5=32)`的结果 // 反推的话,n>>1...22; 每次判断n是奇数还是偶数,可以判断当前位是多少// 这里可以用n&1=0 偶数 n&1=1 奇数 来判断奇数偶数struct proc *p=  myproc();char *mask =p->mask;for(int i = 0; i < 23; i++)// syscall num 从0开始{if(n&1)mask[i]='1';elsemask[i]='0';n>>=1;}return 0;
    }

    image-20210514153512603

  • 修改fork()(参见kernel/proc.c)将trace mask参数从父进程复制到子进程。

    image-20210514153708281

  • 修改kernel/syscall.c中的syscall()函数以打印跟踪输出。你需要添加一个syscall名称数组来进行索引。

  // kernel/syscall.cvoidsyscall(void){int num;struct proc *p = myproc();num = p->trapframe->a7;if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {p->trapframe->a0 = syscalls[num]();if('1' == p->mask[num]) // p->mask 只有trace的时候才会修改它,见kernel/sysproc.c->sys_traceprintf("%d: syscall %s -> %d\n", p->pid, syscallnames[num], p->trapframe->a0);} else {printf("%d %s: unknown sys call %d\n",p->pid, p->name, num);p->trapframe->a0 = -1;}}

总结 遇到的一点小坑:

  1. "%d: syscall %s -> %d\n这里冒号后面需要加上空格,第一次没加上空格,死活匹配不过去,发现后被自己气死;

  2. trace children案例有超时时间,31s的时候就time out了,鉴于我ubuntu14,还是虚拟机,碍于性能问题总是跑超时,其实答案是对的,修改gradelib.py, 增加了判题的超时时间,就过去了;

    image-20210514155522566

贴下这道题的完结图:

image-20210514155627914

$ export PATH=$PATH:/home/moocos/riscv-gnu-toolchain/bin/bin //路径可以替换为你自己的路径
//然后编译xv6
$ make
$ make qemu
...
mkfs/mkfs fs.img README user/_cat user/_echo user/_forktest user/_grep user/_init user/_kill user/_ln user/_ls user/_mkdir user/_rm user/_sh user/_stressfs user/_usertests user/_wc user/_zombie user/_cow 
nmeta 46 (boot, super, log blocks 30 inode blocks 13, bitmap blocks 1) blocks 954 total 1000
balloc: first 497 blocks have been allocated
balloc: write bitmap block at sector 45
qemu-system-riscv64 -machine virt -kernel kernel/kernel -m 3G -smp 3 -nographic -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
hart 0 starting
hart 2 starting
hart 1 starting

Sysinfo (moderate)

In this assignment you will add a system call, sysinfo, that collects information about the running system. The system call takes one argument: a pointer to a struct sysinfo (see kernel/sysinfo.h). The kernel should fill out the fields of this struct: the freemem field should be set to the number of bytes of free memory, and the nproc field should be set to the number of processes whose state is not UNUSED. We provide a test program sysinfotest; you pass this assignment if it prints “sysinfotest: OK”.
在本作业中,您将添加一个系统调用sysinfo,用于收集有关正在运行的系统的信息。系统调用有一个参数:一个指向struct sysinfo的指针 (参见kernel/sysinfo.h)。内核应填写此结构的字段:freemem字段应设置为可用内存的字节数,nproc 字段应设置为状态 不是UNUSED的进程数。我们提供了一个测试程序sysinfotest;如果它输出“sysinfotest:OK”,则通过此作业。

一些提示:

  • 按照上次添加systrace的步骤,添加sysinfo
  • 收集空闲内存量,需要在kernel/kalloc.c中添加一个函数,这个函数来获取一个全局变量,标识内存量
  • 收集进程数,需要在kernel/proc.c中添加一个函数,这个函数来获取一个全局变量,标识进程数
  • 然后内核函数sysinfo(info)读取上面两个变量,然后将struct sysinfo 的值从内核空间拷贝到用户空间(copyout),完成调用

具体修改点如下

  • makefile增加_sysinfotest编译项:

    image-20230219114421145

  • user/usys.pl增加sysinfo的入口

    image-20230219114503105

  • user/user.h 增加sysinfo结构体和函数声明

image-20230219114533254

  • 创建user/sysinfo.c ,进入xv6可以执行,sysinfo查看系统内存,相当于新增一个shell函数

    image-20230219114752738

  • kernel/sysproc.c 增加头文件及sysinfo的函数实现,这里是内核态的实现,需要通过argaddr获取用户态调用的传参,并把内核态的数据通过copyout拷贝给用户态

    image-20230219114950679

image-20230219114938723

  • kernel/proc.c 返回系统的进程数量,推荐作法新增函数直接遍历获取。

    image-20230219120340958

  • kernel/kalloc.c 增加函数返回内存使用量

image-20230219120746946

  • kernel/def.h里增加函数声明

    image-20230219120829236

  • kernel/syscall.h 增加系统调用号

image-20230219115754429

  • kernel/syscall.c 增加syscalls和syscallnames的定义

image-20230219115902993

image-20230219120012942

补充trace的修改

  • kernel/proc.h 增加MASKSIZE=24的定义

image-20230219120049248

  • kernel/sysproc.c 同样补充遍历条件

    image-20230219115643648

最后执行结果

image-20230219121359818

一点点反思

侵入式修改_反例

不好的做法,反例:定义一个全局变量,申请的时候++,释放的时候–,侵入式修改,修改了原有代码,后续需求变化还会引起散弹式修改,不好不好

  • kernel/proc.c 返回系统的进程数量

image-20230219120230974

image-20230219120306096

image-20230219120313248

  • 返回系统可用内存

image-20230219120536056

image-20230219120548284

相关文章:

Lab2_Simple Shell_2020

Lab2: 实验目的&#xff1a;给xv6添加新的系统调用 并理解系统调用是如何工作的&#xff0c;并理解xv6内核的一些内部特征 实验准备&#xff1a; 阅读xv6的第2章以及第4章的4.3,4.3小节熟悉下面的源码 用户态相关的代码&#xff1a;user/user.h和user/usys.pl内核态相关的代…...

2023最全电商API接口 高并发请求 实时数据 支持定制 电商数据 买家卖家数据

电商日常运营很容易理解&#xff0c;就是店铺商品维护&#xff0c;上下架&#xff0c;评价维护&#xff0c;库存数量&#xff0c;协助美工完成制作详情页。店铺DSR&#xff0c;好评率&#xff0c;提升客服服务等等&#xff0c;这些基础而且每天都必须做循环做的工作。借助电商A…...

MySQL 的索引类型

1. 按照功能划分 按照功能来划分&#xff0c;索引主要有四种&#xff1a; 普通索引唯一性索引主键索引全文索引 普通索引就是最最基础的索引&#xff0c;这种索引没有任何的约束作用&#xff0c;它存在的主要意义就是提高查询效率。 普通索引创建方式如下&#xff1a; CREATE…...

< Linux > 进程信号

目录 1、信号入门 生活角度的信号 技术应用角度的信号 前台进程 && 后台进程 信号概念 用kill -l命令察看系统定义的信号列表 信号处理的方式 2、信号产生前 用户层产生信号的方式 3、产生信号 3.1、通过终端按键产生信号 3.2、核心转储core dump 3.3、调用系统函数…...

Pyspark基础入门7_RDD的内核调度

Pyspark 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hbase Hi…...

C/C++每日一练(20230307)

目录 1. 国名排序 ★★ 2. 重复的DNA序列 ★★★ 3. 买卖股票的最佳时机 III ★★★ &#x1f31f; 每日一练刷题专栏 C/C 每日一练 ​专栏 Python 每日一练 ​专栏 1. 国名排序 小李在准备明天的广交会&#xff0c;明天有来自世界各国的客房跟他们谈生意&#xff0c…...

一条SQL查询语句是如何执行的?

平时我们使用数据库&#xff0c;看到的通常都是一个整体。比如&#xff0c;你有个最简单的表&#xff0c;表里只有一个ID字段&#xff0c;在执行下面这个查询语句时&#xff1a; mysql> select * from T where ID10&#xff1b; 我们看到的只是输入一条语句&#xff0c;返…...

tcsh常用配置

查看当前的shell类型 在 Linux 的世界中&#xff0c;有着许多 shell 程序。常见的有&#xff1a; Bourne shell (sh) C shell (csh) TC shell (tcsh) Korn shell (ksh) Bourne Again shell (bash) 其中&#xff0c;最常用的就是bash和tcsh&#xff0c;本次文章介绍tcsh的…...

YOLOv5源码逐行超详细注释与解读(2)——推理部分detect.py

前言 前面简单介绍了YOLOv5的项目目录结构&#xff08;直通车&#xff1a;YOLOv5源码逐行超详细注释与解读&#xff08;1&#xff09;——项目目录结构解析&#xff09;&#xff0c;对项目整体有了大致了解。 今天要学习的是detect.py。通常这个文件是用来预测一张图片或者一…...

什么叫个非对称加密?中间人攻击?数字签名?

非对称加密也称为公钥密码。就是用公钥来进行加密&#xff0c;撒子意思&#xff1f; 非对称加密 在对称加密中&#xff0c;我们只需要一个密钥&#xff0c;通信双方同时持有。而非对称加密需要4个密钥&#xff0c;来完成完整的双方通信。通信双方各自准备一对公钥和私钥。其中…...

2023.03.07 小记与展望

碎碎念系列全新改版&#xff01; 以后就叫小记和展望系列 最近事情比较多&#xff0c;写篇博客梳理一下自己3月到5月下旬的一个规划 一、关于毕设 毕设马上开题答辩了&#xff0c;准备再重新修改一下开题报告&#xff0c;梳理各阶段目标。 毕设是在去年的大学生创新训练项目…...

MyBatis源码分析(七)MyBatis与Spring的整合原理与源码分析

文章目录写在前面一、SqlSessionFactoryBean配置SqlSessionFactory1、初识SqlSessionFactoryBean2、实现ApplicationListener3、实现InitializingBean接口4、实现FactoryBean接口5、构建SqlSessionFactory二、SqlSessionTemplate1、初始SqlSessionTemplate2、SqlSessionTemplat…...

基于声网 Flutter SDK 实现多人视频通话

前言 本文是由声网社区的开发者“小猿”撰写的Flutter基础教程系列中的第一篇。本文除了讲述实现多人视频通话的过程&#xff0c;还有一些 Flutter 开发方面的知识点。该系列将基于声网 Fluttter SDK 实现视频通话、互动直播&#xff0c;并尝试虚拟背景等更多功能的实现。 如果…...

IT服务管理(ITSM) 中的大数据

当我们谈论IT服务管理&#xff08;ITSM&#xff09;领域的大数据时&#xff0c;我们谈论的是关于两件不同的事情&#xff1a; IT 为业务提供的大数据工具/服务 - 对业务运营数据进行数字处理。IT 运营中的大数据 – 处理和利用复杂的 IT 运营数据。 面向业务运营的大数据服务…...

Validator校验之ValidatorUtils

注意&#xff1a;hibernate-validator 与 持久层框架 hibernate 没有什么关系&#xff0c;hibernate-validator 是 hibernate 组织下的一个开源项目 。 hibernate-validator 是 JSR 380&#xff08;Bean Validation 2.0&#xff09;、JSR 303&#xff08;Bean Validation 1.0&…...

C++---背包模型---采药(每日一道算法2023.3.7)

注意事项&#xff1a; 本题是"动态规划—01背包"的扩展题&#xff0c;dp和优化思路不多赘述。 题目&#xff1a; 辰辰是个天资聪颖的孩子&#xff0c;他的梦想是成为世界上最伟大的医师。 为此&#xff0c;他想拜附近最有威望的医师为师。 医师为了判断他的资质&…...

Java各种锁

目录 一、读写锁(ReentrantReadWriteLock) 二、非公平锁(synchronized/ReentrantLock) 三、可重入锁/递归锁(synchronized/ReentrantLock) 四、自旋锁(spinlock) 五、乐观锁/悲观锁 六、死锁 1、死锁代码 2、死锁的检测(jps -l 与 jstack 进程号) 七、sychronized-wait…...

TryHackMe-Tardigrade(应急响应)

Tardigrade 您能否在此 Linux 端点中找到所有基本的持久性机制&#xff1f; 服务器已遭到入侵&#xff0c;安全团队已决定隔离计算机&#xff0c;直到对其进行彻底清理。事件响应团队的初步检查显示&#xff0c;有五个不同的后门。你的工作是在发出信号以使服务器恢复生产之前…...

导出GIS | 将EXCEL表格中坐标导出成GIS格式文件

一 前言 EXCEL是我们日常工作学习数据处理的办公软件&#xff0c;操作易上手&#xff0c;几乎人人都会用。EXCEL表格能够处理各种数据&#xff0c;包括经纬度坐标数据&#xff0c;地址数据等等。 有时因工作需要需将表格中地址数据处理为GIS格式的文件&#xff0c;以便能够将数…...

new set数组对象去重失败

我们知道Set是JS的一个种新的数据结构&#xff0c;和数组类似&#xff0c;和数组不同的是它可以去重&#xff0c;比如存入两个1或两个"123"&#xff0c;只有1条数据会存入成功&#xff0c;但有个特殊情况&#xff0c;如果添加到set的值是引用类型&#xff0c;比如数组…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...