2020 6.s081——Lab2:system calls

news2025/1/18 17:03:30

左岸的一座白色环形阶梯

浪人正在用和弦练习忧郁

晨曦下的少女听着吉他旋律

在许愿池边巴洛克式的叹息

——许愿池的希腊少女

完整代码见:SnowLegend-star/6.s081 at syscall (github.com)

System call tracing (moderate)

这个实验要求我们跟踪系统调用。

感觉实验说明对mask的解释有点语焉不详,研究了好一番才明白mask的作用:把mask转换为32-bit的二进制数n,第ni 位为1就跟踪编号为i的syscall。而且说明里面应该还有个错误,int类型的最大正数应为“2147483647”,而实验说明里搞了个这数,我也是看半天没反应过来,可恶。

       读懂了实验要求,就可以着手实验部分了。根据hints,我们可以大致设计如下实现流程:

       ①确定syscall函数名sys_trace

       ②在syscall.h中给sys_trace设定一个系统调用编号

       ③在syscall.c中注册sys_trace,同时建立一个指针数组*syscallsName[]来记录系统调用的函数名称。

       ④在user.h中定义函数trace(int),在usys.pl中设置sys_trace的调用入口。

       ⑤完成sys_trace在各个头文件的声明之后,在struct proc中添加一个成员mask,从而能够使父进程将mask传递给子进程。

       确定好大致流程后,进行sys_trace()的实现工作。这里说一点,貌似系统调用函数都是不用传参的,大概是为了保证操作系统的isolation。用户空间与内核空间的传参会有专门的实验函数维护。那么问题来了,我们得想办法从用户空间吧mask拿过来。我们注意到hints里有这句话

The functions to retrieve system call arguments from user space are in kernel/syscall.c, and you can see examples of their use in kernel/sysproc.c

结合xv6文档的4.4节

The functions argint, argaddr, and argfd retrieve the n ’th system call argument from the trap frame as an integer, pointer, or a file descriptor.

看完上面两点之后就大致有点头绪了,然后我们在sysproc.c文件里面浏览一番,看看有没有哪些函数调用了argint()这种函数。可以发现调用形式都是argint(0,&argument)。这就好办了,我们来个argint(0,&mask)应该就可以从用户空间里获得mask。Ok,现在有了mask这个参数,剩下的就是把它传递给当前进程了。

还是观察sysproc.c内部的那些函数,用相对敏锐的注意力察觉到myproc()可能有点作用。浏览一番定义果真是获取当前进程的函数。那么sys_trace到这里也就结束了。最后在syscall.c函数里面修改打印内容即可。当然,这里得用上a0和a7这两个寄存器,xv6文档内部也有提到,就略过不表了。

此时再顺便把进程相关的结构体浏览一番(proc.h),对进程的处理有个大致的了解后为第二个实验打下基础。

sys_trace()如下
 

//跟踪系统调用情况
uint64
sys_trace(void){
  int mask;
  if(argint(0,&mask)<0)
    return -1;
  myproc()->mask=mask;
  return 0;
}

Sysinfo (moderate)

完成这个实验之前也可以自己设计个大致流程,和sys_trace比较相似,就不再赘述了。我们观察struct sysinfo这个结构体,可以确定主要任务就是获取它其中的两个成员: freemen和nproc。这里定义两个函数kfmstat()和sum_USED来分别统计系统剩余内存和process->state不为UNUSED

kfmstat()根据hints可以在kalloc.c中实现。在完成它之前,我们还是老样子观察下kalloc.c里的其他函数是怎么实现的。可以发现系统用freelist来维护内存分配。那kfmstat()的实现核心也就呼之欲出了——遍历一遍freelist。

Tips: freelist中,每个内存节点的大小都是4096B

收集进程数则是在proc.c中实现,这里还有个现成的函数procdump()统计系统状态。其实偷懒点直接改造procdump()都行。由于太过简单就略过不表。

这个实验最难的地方是在sys_sysinfo自己的函数体。在sys_sysinfo()内部调用完上述两个函数初始化sysINFO后,我们要怎么把这个结构体给传递到用户空间呢?

我们按照hints查看sys_fstat()  (kernel/sysfile.c)和filestat() ( kernel/file.c ),可以发现一条及其重要的注释

先通过argaddr()函数得到用户空间

sysinfo(info)

传过来的这个地址,存放在uint64类型的变量中。(注意,用户空间传过来的地址一定要放在uint64类型的变量中,不可以放在struct sysinfo类型中)然后再使用copyout函数把内容从内核空间拷贝进用户空间中。

我们进入vm.c中查看下copyout()的实现方法

// Copy from kernel to user.
// Copy len bytes from src to virtual address dstva in a given page table.
// Return 0 on success, -1 on error.
int
copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len)

接下来就可以顺便将内核空间中的sysINFO传递出去了。

在完成这个lab的时候,我突然想到一个问题,用户空间中使用的函数是trace(int n),但是内核空间使用的却是sys_trace(void),那用户空间传递的这个n到底是怎么被内核接收到的呢?

其实这个问题的答案在上面已经提到过了,sys_trace(void)不能直接通过传参的方式接收来自用户空间的参数,是通过argint()等函数来接收来自用户空间的参数

最后,我有一个问题始终没有得到解决。当我使用argaddr来接收参数时

argaddr(1,&sysINFO_user)

如果把第一个参数设置为1则会报错

我的猜测由于argaddr第一个参数其实是和寄存器相关的,传参时系统会默认按序使用寄存器。那么来自用户空间的sysinfo地址就被存在第一个寄存器a0里面了,而不是存在第二个寄存器a1内部。                                          

见Xv6-2020文档的4.4节

The functions argint, argaddr, and argfd retrieve the n ’th system call argument from the trap frame as an integer, pointer, or a file descriptor

sys_info()如下

uint64
sys_sysinfo(void){
  struct sysinfo sysINFO;
  struct proc *p=myproc();
  uint64 sysINFO_user;    //user pointer to struct sysinfo     
  sysINFO.freemem=kfmstat();  //刚才用sys_checkmem是有问题的
  sysINFO.nproc=sum_UNUSED();

  // printf("In kernel, available memory: %dB\n", sysINFO.freemem);
  // printf("In kernel, UNUSED process: %d\n", sysINFO.nproc);

  if(argaddr(0,&sysINFO_user)<0)
    return -1;
  // sysINFO_user=(struct sysinfo)sysINFO_user;
  // printf("The sysinfo from user space: \n")
  // printf("available memory: %d",sysINFO_user);
  if(copyout(p->pagetable, sysINFO_user, (char *)&sysINFO, sizeof(sysINFO)) < 0)
    return -1;

  return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件设计师,下午题 ——试题六

模型图 简单工厂模式 工厂方法模式抽象工厂模式生成器模式原型模式适配器模式桥接模式组合模式装饰&#xff08;器&#xff09;模式亨元模式命令模式观察者模式状态模式策略模式访问者模式中介者模式 简单工厂模式 工厂方法模式 抽象工厂模式 生成器模式 原型模式 适配器模式 桥…

nodemcu32s 和 mini D1 组局域网并用 webSocket 通信

实现思路 使用 mini D1 来搭建一个 webSocket 服务&#xff0c;然后使用 nodemcu32 连接&#xff0c;然后就可以进行通信了。 服务端代码&#xff08;mini D1&#xff09; 在代码中主要是需要控制好 loop 函数中的延时&#xff0c;也就是最后一行代码 delay&#xff0c;如果…

大模型时代的具身智能系列专题(六)

UCSD 王小龙组 王小龙是UCSD电子与计算机工程系的助理教授。他曾在加州大学伯克利分校与Alexei Efros和Trevor Darrell一起担任博士后研究员&#xff0c;在CMU RI获得了机器人学博士学位&#xff0c;师从Abhinav Gupta。他的研究重点是通过视频和物理机器人交互数据来学习3D和…

【AIGC】大型语言模型在人工智能规划领域模型生成中的探索

大型语言模型在人工智能规划领域模型生成中的新应用 一、引言二、LLM在规划领域模型生成中的潜力三、实证分析&#xff1a;LLM在规划领域模型生成中的表现四、代码实例&#xff1a;LLM在规划领域模型生成中的应用五、结论与展望 一、引言 随着人工智能技术的迅猛发展&#xff0…

yolov5-ros模型结合zed2相机部署在 Ubuntu系统

前言 本篇文章主要讲解yolov5-ros模型结合zed2相机进行实时检测&#xff0c;经改进实现了红绿灯检测&#xff0c;并输出检测类别与置信度&#xff01; 目录 一、环境配置二、zed2驱动安装三、yolov5-ros功能包配置四、运行官方权重文件四、运行自己权重文件 一、环境配置 1、…

分享6个打开就能让人眼前一亮的网站,每次浏览都像发现新大陆~

1、ZLibrary zh.zlibrary-be.se/ ZLibrary是一个广受欢迎的在线图书馆&#xff0c;它提供了一个庞大的电子书和文章资源库&#xff0c;数量超过千万。这个平台覆盖了国内外众多领域的电子书资源&#xff0c;几乎可以满足用户98%以上的搜索需求&#xff0c;无论是学术研究、文…

Netty中半包粘包的产生与处理:短连接、固定长度、固定分隔符、预设长度;redis、http协议举例;网络数据的发送和接收过程

目录 粘包、半包 相关概念 网络数据发送和接收过程 Netty半包粘包解决方案 ByteBuf获取和默认大小 短链接 固定长度 固定分隔符 预设长度 常见协议代码举例 redis协议 http协议 参考链接 粘包、半包 相关概念 程序处理过程中我们会通过缓冲区接收数据&#xff0c…

input输入框的一些复习

<template><div><div style"text-align: center;margin: 10px 0;"><span style"font-size: 15px;font-weight: bold;">input输入框的基本应用</span></div><el-descriptions :column"3" size"defau…

Golang dlv远程debug

1. 前期准备 1.1. dlv安装 1.1.1. go install安装 go install github.com/go-delve/delve/cmd/dlvlatest1.1.2. 手动安装 下载 linuxx86 架构 二进制文件 &#x1f4ce;dlv.linux.x86.zip zip文件&#xff0c;下载后&#xff08; 如果没权限&#xff0c;记得 执行chmod ax…

linux下使用cmake-gui编译WXQT

一.编译环境 操作系统&#xff1a;Ubuntu 22.04.3 LTS wxWidgets源码&#xff1a;wxWidgets-3.1.5 编译工具&#xff1a;CMake-gui qt版本&#xff1a;5.13.2 二.编译步骤 1.将源码解压。 2.打开CMake-gui&#xff0c;并设置好源码目录和构建目录 3.点击configure 会弹出…

【c++入门】this指针

this指针引出&#xff1a; 我们知道一个类可以有多个实例化对象&#xff0c;但是这多个实例化对象所调用的成员函数是在公共代码区&#xff1b; 我们先来定义一个Date类&#xff1a; class Date { public:void init(int year, int month, int day){_year year;_month month;…

excel怎么对非数字求和汇总?

如&#xff1a;学生小王的成绩为&#xff1a;A&#xff0c;A&#xff0c;A&#xff0c;A&#xff0c;B&#xff0c;B-……想得到的成绩汇总求和为&#xff1a;2A,2A,1B,1B- 如果在低版本里&#xff0c;用公式计算可能相当复杂&#xff0c;但是有了TEXTJOIN函数和UNIQUE函数&…

一、实现一个简单的 Google Chrome 扩展程序

目录 &#x1f9ed; 效果展示 # 图示效果 a. 拓展程序列表图示效果&#xff1a; b. 当前选项卡页面右键效果&#xff1a; c. 拓展程序消息提示效果&#xff1a; &#x1f4c7; 项目目录结构 # 说明 # 结构 # 文件一览 ✍ 核心代码 # manifest.json # background.j…

数据结构算法 数组的实现与练习(C语言实现,Java实现)

文章目录 数据结构数组(顺序表)特点使用Java实现更高级的数组C语言实现总结优点缺点 例题[26. 删除有序数组中的重复项](https://leetcode.cn/problems/remove-duplicates-from-sorted-array/)[1. 两数之和](https://leetcode.cn/problems/two-sum/)[27. 移除元素](https://lee…

阿里云部署nodejs

目录 1、安装node.js 1-1 进入opt/software 1-2 下载node.js安装包 1-3 解压 2 配置环境变量 2-1 vim中配置环境变量 2-2 命令行中保存环境变量 2-3 检查安装版本 2-3 更换镜像 3、上传node.js项目 1-1 启动项目 1-2 配置对应的安全组 ​编辑 4、pm2启动多个node项…

Scroll 上的明星项目Pencils Protocol ,缘何被严重低估?

近日&#xff0c;完成品牌升级的 Pencils Prtocol 结束了 Season 2 并无缝开启了 Season 3&#xff0c;在 Season 3 中&#xff0c;用户可以通过质押系列资产包括 $ETH、$USDT、$USDC、$STONE 、$wrsETH、$pufETH 等来获得可观收益&#xff0c;并获得包括 Scroll Marks、 Penci…

二叉树的前序遍历(oj题)

一、题目链接&#xff1a; https://leetcode-cn.com/problems/binary-tree-preorder-traversal/ 二、题目思路 先调用二叉树节点计算函数&#xff0c;得到二叉树的总结点数。然后申请该大小的数组空间。 再使用前序遍历&#xff0c;依次访问每个结点的数据&#xff0c;依次存…

01-1.2.3 算法的空间复杂度

什么是空间复杂度&#xff1f; 代码在运行之前需要先装入内存&#xff0c;程序代码需要占一定的位置&#xff08;在这边假设是100B&#xff09; 定义的变量和参数i&#xff0c;n都需要占用内存空间 //算法一——逐步递增型 void loveYou(int n) { //n为问题规模int i 1; /…

Notepad++ 常用

File Edit search view Encoding Language Settings Tools Macro Run Plugins Window 文件 编辑 搜索 视图 编码 语言 设置 工具 宏 运行 插件 窗口 快捷方式 定位行 &#xff1a;CTRL g查找&#xff1a; CTRL F替换&am…

未来已来, AI将作为超级工具?

人工智能时代已来 1.AI将作为超级工具&#xff1a;AI是推动全产业数字化转型的高效工具&#xff0c;机遇比互联网时代大10倍&#xff0c;但只有1/3的机会留给初创企业。 2.硅谷AI市场分类中&#xff0c;特别看好开源平台&#xff0c;其将为初创企业和大企业提供更多选择。 3.…