2020 6.s081——Lab2:system calls

左岸的一座白色环形阶梯

浪人正在用和弦练习忧郁

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

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

——许愿池的希腊少女

完整代码见: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.mzph.cn/pingmian/19919.shtml

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

相关文章

平衡二叉树的应用举例

AVL 是一种自平衡二叉搜索树&#xff0c;其中任何节点的左右子树的高度之差不能超过 1。 AVL树的特点&#xff1a; 1、它遵循二叉搜索树的一般属性。 2、树的每个子树都是平衡的&#xff0c;即左右子树的高度之差最多为1。 3、当插入新节点时&#xff0c;树会自我平衡。因此…

R语言绘图 --- 饼状图(Biorplot 开发日志 --- 2)

「写在前面」 在科研数据分析中我们会重复地绘制一些图形&#xff0c;如果代码管理不当经常就会忘记之前绘图的代码。于是我计划开发一个 R 包&#xff08;Biorplot&#xff09;&#xff0c;用来管理自己 R 语言绘图的代码。本系列文章用于记录 Biorplot 包开发日志。 相关链接…

JDBC入门基础

目录 JDBC的基本概念 快速入门&#xff08;基本步骤&#xff09; 创建数据库 注册驱动&#xff08;可以省略不写&#xff09; 获取连接对象 获取执行SQL语句的对象 编写SQL语句&#xff0c;并执行&#xff0c;以及接收返回的结果 处理结果&#xff0c;遍历结果集和 释放资源&…

数据流通与智能家居的未来

在科技飞速发展的今天&#xff0c;智能家居逐渐融入我们的日常生活&#xff0c;改变了传统的居住方式。智能生态网络&#xff08;IEN&#xff09;作为智能家居的核心&#xff0c;集成了家庭内的各种智能设备和传感器&#xff0c;实现了对家庭环境的智能化管理。而数据要素流通则…

ESP32入门:1、VSCode+PlatformIO环境搭建(离线快速安装)

文章目录 背景安装vscode安装配置中文 安装Platform IO安装PIO 新建ESP32工程参考 背景 对于刚接触单片机的同学&#xff0c;使用vscodeplatformIO来学习ESP32是最方便快捷的&#xff0c;比IDF框架简单&#xff0c;且比arduino文件管理性能更好。但是platformIO安装较为麻烦&a…

电子阅览室能给孩子做什么

电子阅览室为孩子提供了很多活动和资源&#xff0c;可以为他们提供以下服务&#xff1a; 1. 提供电子书籍和儿童读物&#xff1a;电子阅览室通常提供大量的电子书籍和儿童读物&#xff0c;供孩子选择阅读。 2. 提供儿童学习资源&#xff1a;专久智能电子阅览室可以提供各种学习…

CraftCMS ConditionsController.php 代码执行漏洞(CVE-2023-41892)

0x01 产品简介 Craft CMS是一个开源的内容管理系统,它专注于用户友好的内容创建过程,逻辑清晰明了,是一个高度自由,高度自定义设计的平台吗,可以用来创建个人或企业网站也可以搭建企业级电子商务系统。 0x02 漏洞概述 Craft CMS在4.4.15版本之前存在远程代码执行漏洞,…

[论文笔记]MemGPT: Towards LLMs as Operating Systems

引言 今天介绍一篇论文MemGPT: Towards LLMs as Operating Systems。翻过过来就是把LLM看成操作系统。 大语言模型已经在人工智能领域引起了革命性的变革&#xff0c;但受到有限上下文窗口的限制&#xff0c;在扩展对话和文档分析等任务中的效用受到了阻碍。为了能够利用超出…

4月啤酒品类线上销售数据分析

近期&#xff0c;中国啤酒行业正处于一个重要的转型期。首先&#xff0c;消费者对高品质啤酒的需求不断增加&#xff0c;这推动了行业向高端化、场景化和社交化的方向发展。精酿啤酒作为这一趋势的代表&#xff0c;其发展势头强劲&#xff0c;不仅满足了消费者对品质化、个性化…

蓝桥杯2024国赛--备赛刷题题单

1.游戏&#xff08;单调队列&#xff09; 注意如果结果是分数&#xff0c;直接设置变量为double&#xff0c;最好不要使用把int类型乘1.0变成分数来计算。 #include <iostream> #include <queue> using namespace std; const int N1e510; //滑动窗口大小为k,最大值…

2024上海中小学生古诗文大会方案已发布,家长孩子最关心10个问题

昨天&#xff08;2024年5月30日&#xff09;下午15点&#xff0c;上海中小学生古诗文大会组委会通过两个公众号发布了《2024上海中小学生古诗文大会系列活动方案出炉》的推文&#xff08;下称《方案》&#xff09;。如我之前的分析和预测&#xff0c;5月份会发布今年的中小学生…

邮件服务器部署

目录 介绍 资源列表 基础环境 关闭防火墙 关闭内核安全机制 修改主机名 一、部署DNS服务器 mail节点操作 修改DNS地址 二、部署postfix和dovecot 安装软件包 修改postfix配置文件 重启postfix服务和开机自启 修改dovecot配置文件 重启dovecot服务和开机自启 创…

微服务:一篇博客带你学会Gateway(路由、过滤、跨域问题配置)

文章目录 Gateway搭建路由断言工厂路由过滤器全局过滤器过滤器执行顺序网关的core跨域配置跨域问题配置 Gateway 网关功能&#xff1a; 身份认证、权限校验服务路由、负载均衡请求限流 搭建 gateway也算一个服务 所以创建gateway子模块 引入依赖 <dependency><gro…

AIGC智能办公实战 课程,祝你事业新高度

在数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到我们生活的方方面面&#xff0c;从智能家居到自动驾驶&#xff0c;从医疗诊断到金融分析&#xff0c;AI助手正在改变我们的工作方式和生活质量。那么&#xff0c;你是否想过自己也能从零开始&#xff0c;…

Redis学习笔记【实战篇--短信登录】

开篇导读 实战篇有什么样的内容 短信登录 这一块我们会使用redis共享session来实现 商户查询缓存 通过本章节&#xff0c;我们会理解缓存击穿&#xff0c;缓存穿透&#xff0c;缓存雪崩等问题&#xff0c;让小伙伴的对于这些概念的理解不仅仅是停留在概念上&#xff0c;更…

音视频直播(一)

协议基础篇 直播协议基础推流与拉流推流拉流 直播传输协议RTMP传输协议 && HTTP-FLV协议为什么RTMP做推流&#xff0c;反而很少做拉流&#xff1f;HTTP-FLV协议 RTSP协议HLS协议SRT协议 WebRTC协议应用于直播 直播协议基础 从网络上搜寻到的有关推流与拉流的示意图 从…

Java项目对接redis,客户端是选Redisson、Lettuce还是Jedis?

JAVA项目对接redis&#xff0c;客户端是选Redisson、Lettuce还是Jedis&#xff1f; 一、客户端简介1. Jedis介绍2. Lettuce介绍3. Redisson介绍 二、横向对比三、选型说明 在实际的项目开发中&#xff0c;对于一个需要对接Redis的项目来说&#xff0c;就面临着选择合适的Redis客…

如何从浅入深理解transformer?

前言 在人工智能的浩瀚海洋中&#xff0c;大模型目前无疑是其中一颗璀璨的明星。从简单的图像识别到复杂的自然语言处理&#xff0c;大模型在各个领域都取得了令人瞩目的成就。而在这其中&#xff0c;Transformer模型更是成为大模型技术的核心。 一、大模型的行业发展现状如…

QT5:调用qt键盘组件实现文本框输入

目录 一、环境与目标 二、Qt VirtualKeyboard 1.勾选Qt VirtualKeyboard 2.ui设计流程 3.注意事项及问题点 三、参考代码 参考博客 一、环境与目标 qt版本&#xff1a;5.12.7 windows 11 下的 Qt Designer &#xff08;已搭建&#xff09; 目标&#xff1a;创建一个窗…

二叉树的顺序实现-堆

一、什么是堆 在数据结构中&#xff0c;堆&#xff08;Heap&#xff09;是一种特殊的树形数据结构&#xff0c;用数组存储&#xff0c;通常被用来实现优先队列。 堆具有以下特点&#xff1a; 堆是一棵完全二叉树&#xff08;Complete Binary Tree&#xff09;&#xff0c;即…