2020 6.s081——Lab2:system calls

2024-06-01 02:28
文章标签 2020 system s081 lab2 calls

本文主要是介绍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;
}

这篇关于2020 6.s081——Lab2:system calls的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1019729

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

Partical System

创建"粒子系统物体"(点击菜单GameObject -> Create Other -> Particle System) 添加"粒子系统组件"(点击Component -> Effects  ->Particle System) 粒子系统检视面板  点击粒子系统检视面板的右上角的"+"来增加新的模块。(Show All Modules:显示全部) 初始化模块: •

小技巧绕过Sina Visitor System(新浪访客系统)

0x00 前言 一直以来,爬虫与反爬虫技术都时刻进行着博弈,而新浪微博作为一个数据大户更是在反爬虫上不遗余力。常规手段如验证码、封IP等等相信很多人都见识过…… 当然确实有需要的话可以通过新浪开放平台提供的API进行数据采集,但是普通开发者的权限比较低,限制也比较多。所以如果只是做一些简单的功能还是爬虫比较方便~ 应该是今年的早些时候,新浪引入了一个Sina Visitor Syst

System.getProperties().

Java.version Java 运行时环境版本 java.vendor Java 运行时环境供应商 java.vendor.url Java 供应商的 URL java.home Java 安装目录 java.vm.specification.version Java 虚拟机规范版本 java.vm.specification.vendor

12C 新特性,MOVE DATAFILE 在线移动 包括system, 附带改名 NID ,cdb_data_files视图坏了

ALTER DATABASE MOVE DATAFILE  可以改名 可以move file,全部一个命令。 resue 可以重用,keep好像不生效!!! system照移动不误-------- SQL> select file_name, status, online_status from dba_data_files where tablespace_name='SYSTEM'

android6/7 system打包脚本

1.android5打包system就是网站上常见的制作ROM必备的解包打包system脚本 指令如下:mkuserimg.sh -s out/target/product/$TARGET_PRODUCT/system out/target/product/$TARGET_PRODUCT/obj/PACKAGING/systemimage_intermediates/system.img

android打包解包boot.img,system.img

原帖地址:http://www.52pojie.cn/thread-488025-1-1.html 转载Mark一下,日后研究 最近工作需要对boot.img,system.img进行破解。顺便将心得分享一下。 我的工作环境是在linux下的。所以工具都是针对linux的。 boot.img破解相关工具: 1、split_boot    perl脚本 2、boot_i

MTK Android P/Q system/vendor/super快速打包

一、Android 新版本默认开启了动态分区,把system vendor  product等分区打包成一个super分区。这对于我们使用替换分区的方法来排查问题不是很方便,直接替换一个super也不知道到底是哪个部分导致的。所以我们需要自己制作super.img来缩小范围。下面讲讲如何快速生成system、vendor、super,以及vbmeta(校验image,不匹配可能会导致不开机) 二

Linux函数fcntl/system学习

本文针对项目中用到的几个函数进行详细分析,并尽可能的添加示例进行验证学习。比如fcntl/ioctl函数、system/exec函数、popen/pclose函数、mmap函数等。 重点参考了《UNP》和《Linux程序设计》第四版。 一、fcntl函数 fcntl函数可以改变或者查看已打开文件的性质。该函数的定义如下: #include <fcntl.h> int fcntl(

【UVA】11400-Lighting System Design(动态规划)

这道题感觉状态式不是很好推。。。 WA了好几次是因为排序的时候出问题了。 这道题出在线性结构里了,先说一下最长上升子序列吧。 dp[i]代表了以array[i]结尾的时候,最长子序列长度。 推导的时候,以起点递增的顺序进行推导。 #include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#i