mit6.s081 lab2 System calls

2024-03-11 06:32
文章标签 system s081 mit6 lab2 calls

本文主要是介绍mit6.s081 lab2 System calls,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

添加mit仓库

  • 添加remote
git remote add mit git://g.csail.mit.edu/xv6-labs-2020
  • 从mit拉取分支
git fetch mit
git checkout syscall
chapter 2
System call tracing

写一个程序追踪另一个程序所调用的system call,打印追踪的syscall的syscall num, syscall num, 以及调用syscall的返回值,需要注意的是如果mask中标识需要追踪trace,那么第一次调用trace时也需要打印trace syscall的追踪信息

$ 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

主要进行以下修改:
1.在Makefile中添加trace程序
2.user/trace.c中已经完成了trace程序,但是syscall trace还没有完成,所以这个exercise的主要工作为完成syscall trace
3.在kernel/proc.h中process的结构体中增加mask成员,用于记录需要追踪哪些syscall
3.在kernel/sysproc.c中完成sys_trace(),sys_trace就是trace syscall实际执行的函数,sys_trace函数的主要工作是修改process中的mask,从user space中获取trace syscall的参数的方式为使用argint函数(如argint(0, &mask)),argint实际上是从process的trapframe中获取对应位置的寄存器内容
4.修改fork()(kernel/proc.c),创建新的process继承父process的mask值
5.修改syscall()(kernel/syscall.c),这部分要做的工作是声明一个syscall name string数组,用于根据syscall num获取对应的syscall名。另外一个工作是获取当前process的mask值,判断当前调用的syscall是否是需要追踪的,如果需要追踪则将对应的信息打印出来

  • kernel/sysproc.c
uint64 sys_trace(void) {int mask = 0;if (argint(0, &mask) < 0)return -1;myproc()->mask = mask;return 0;
}
  • kernel/syscall.c
    添加sys_systrace的函数声明
extern uint64 sys_trace(void);

在函数指针数组syscalls中添加sys_trace函数指针

[SYS_trace]   sys_trace,

修改函数syscall

char* system_call_name[] = {"","fork","exit","wait","pipe","read","kill","exec","fstat","chdir","dup","getpid","sbrk","sleep","uptime","open","write","mknod","unlink","link","mkdir","close","trace",
};void
syscall(void)
{int num;struct proc *p = myproc();num = p->trapframe->a7;if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {p->trapframe->a0 = syscalls[num]();int mask = p->mask;if ((mask >> num) & 0x1) {printf("%d: syscall %s -> %d\n", p->pid, system_call_name[num], p->trapframe->a0);}} else {printf("%d %s: unknown sys call %d\n",p->pid, p->name, num);p->trapframe->a0 = -1;}
}
  • 在kernel/syscall.h中增加
#define SYS_trace  22
  • 在user/user.h中增加
int trace(int);
  • 在usys.pl中增加
entry("trace");

usys.pl中生成user mode下的system call的内容,具体为设置对应syscall num到寄存器a7中,然后调用ecall

Sysinfo

这部分的内容是实现sysinfo syscall,sysinfo用于收集系统中的信息,包括系统中空闲内存的大小(byte),以及系统中的进程数量,这两项信息在struct sysinfo(kernel/sysinfo.h)中记录

  • sysinfo的用户态调用函数的原型为int sysinfo(struct sysinfo *),在此syscall中的工作为传入sysinfo结构,并将结果填充到该sysinfo结构中
  • 首先要添加syscall的声明,步骤与trace相同
  • 然后是在kernel/kalloc.c中添加获取空闲内存容量的函数,根据kmalloc.c中的其他函数可知在系统中维护了一条空闲链表,每个链表节点为一个PGSIZE的页,所以获取空闲内存容量就是遍历空闲链表,获取空闲链表节点数量,空闲内容容量为空闲链表节点数量 * PGSIZE,在遍历空闲链表的过程中需要对空闲链表进行上锁
// 获取空闲内存容量
uint64 get_free_memory_info() {struct run *r;int freelist_size = 0;acquire(&kmem.lock);r = kmem.freelist;while (r) {freelist_size++;r = r->next;}uint64 res = freelist_size * PGSIZE;release(&kmem.lock);return res;
}
  • 在kernel/proc.c中添加获取系统中的process数量的函数,在proc.c中维护了一个数组struct proc proc[NPROC],遍历此数组,如果proc的state不为UNUSED那么说明这是一个有效的proc,统计有效的proc数量并返回
uint64 get_proc_num() {struct proc *p;uint64 proc_num = 0;for (p = proc; p < &proc[NPROC]; p++) {if (p->state != UNUSED)proc_num++;}return proc_num;
}
  • 在kernel/defs.h中对以上两个函数进行声明
  • 在kernel/sysproc.c中实现sys_sysinfo函数,在该函数中获取用户传入的sysinfo结构体的指针(user_info)可以使用argaddr实现,首先在函数声明一个sysinfo kernel_info,通过上述的两个函数获取系统中空闲内存容量以及进程数量,填充kernel_info,然后需要将kernel_info的内容拷贝到user_info中,这里涉及到kernel space到user space的内存拷贝操作,可以参考sys_fstat() (kernel/sysfile.c)和filestat() (kernel/file.c) 中的做法,使用copyout进行拷贝,copyout的参数依次为当前process的pagetable,user space的目标内存起始地址,kernel space的拷贝内存气势地址,需要拷贝的长度
uint64 sys_sysinfo(void) {uint64 user_info;if (argaddr(0, &user_info) < 0)return -1;struct sysinfo kernel_info;kernel_info.freemem = get_free_memory_info();kernel_info.nproc = get_proc_num();struct proc *p = myproc();if (copyout(p->pagetable, user_info, (char*)&kernel_info, sizeof(kernel_info)) < 0)return -1;return 0;
}

请添加图片描述

这篇关于mit6.s081 lab2 System calls的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

解决PHP Warning: strftime(): It is not safe to rely on the system's timezone set

当运行一些程序时,在httpd日志中会有如下警告日志: PHP Warning:  strftime(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set(