当前位置: 首页 > 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;比如数组…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...