1. Preview

1.1 xv6-book Chap2

xv6-book的第二章和lecture3的内容类似,主要介绍了操作系统的组织结构,从物理资源的抽象、用户态/内核态、系统调用、微内核/宏内核以及代码层面展开

xv6-book的4.3、4.4节讲的是如何进行系统调用

1.2 code

了解xv6启动过程

_entry.S中将stack0+4096赋给栈指针寄存器sp,使得其指向栈顶,然后call start

start => main => userinit => initcode.S => init.c

2 System call tracing

trace是一个工具,能够记录指定的系统调用。

 $ trace 32 grep hello README3: syscall read -> 10233: syscall read -> 9663: syscall read -> 703: syscall read -> 0
 # 命令的格式$ trace [MASK] [OPTIONS...] # 其中[MASK]是一个数字n; 如果 (n >> i) & 1 == 1 表示i号系统调用需要trace# 输出的形式[pid]: syscall <name> -> <return_value>

首先需要明确的是trace也是一个系统调用,所以就需要大概明白从用户态调用trace工具到内核调用对应的系统调用的过程。

根据手册的指示大概能够推测出来

1、在命令行中输入:trace 32 grep hello README 后,实际上是执行 /user/trace.c 文件。过程就是 先执行 trace 函数,然后再执行后面的命令。

2、这个 trace 函数是需要在 /user/user.h 文件中定义原型的,之后好像就找不到对应的实现了。其实之后的实现是在内核态了,需要先陷入内核,手册中说要在 /user/usys.pl 中定义一个 stub: entry("trace"),这个stub会在 user/usys.S 生成一段汇编代码:进行系统调用。

3、其中的ecall指令就会调用 /kernel/syscall.c 中的 syscall 函数,执行对应的系统调用函数 sys_<name>

然后就可以开始根据手册的提示写代码了...

  1. 在 kernel/sysproc.c 中增加 sys_trace() 函数

  2. 要在 proc 结构体中增加一个新的变量存储 trace 的参数

  3. 修改 syscall() 函数来打印 trace 输出

  4. 修改 fork() 函数使得 trace 的参数从父进程拷贝到子进程

 // 在 kernel/sysproc.c 中增加 sys_trace 函数uint64sys_trace(void){int n;if( argint(0, &n) < 0 ){return -1;}// parse the `n` to get which sys_call need to be tracedstruct proc* p = myproc();p->trace_mask = n;return 0;}
// 修改 kernel/syscall.c 中的 syscall 函数voidsyscall(void){int num;struct proc *p = myproc();​num = p->trapframe->a7; // a7: sys_call numberif(num > 0 && num < NELEM(syscalls) && syscalls[num]) {p->trapframe->a0 = syscalls[num]();// add the trace checkif( (( p->trace_mask >> num ) & 1) == 1 ){ // need to traceprintf("%d: syscall %s -> %d\n", p->pid, sys_call_names[num], p->trapframe->a0);}} else {printf("%d %s: unknown sys call %d\n",p->pid, p->name, num);p->trapframe->a0 = -1;}}

测试结果

注意第四个测试有可能会超时,需要修改 gradelib.py 文件的第 428 行 扩大时间限制

3 Sysinfo

还是实现一个系统调用,在内核填上 struct sysinfo 的两个字段,并拷贝回用户空间,主要过程:

  1. trace那样,在对应位置增加系统调用所需的相关信息。

  2. kernel/proc.c 中增加一个统计 not UNUSED process 的函数

  3. kernel/kalloc.c 中增加一个统计 free memory 的函数

  4. 理解 copyout 函数,在系统调用中将 struct sysinfo 从内核空间 拷贝入 用户空间

核心代码

// need to copy the sysinfo struct from kernel space to user spaceuint64sys_sysinfo(void){uint64 addr;if( argaddr(0, &addr) < 0 ){return -1;}struct sysinfo si;si.nproc = notunusedproc();si.freemem = freemem();struct proc* p = myproc();if( copyout(p->pagetable, addr, (char *)(&(si)), sizeof(si)) < 0 ){return -1;}return 0;}

统计 不是 UNUSED 的 进程数量,只需要遍历 proc 数组即可。

 uint64notunusedproc(void){int num = 0;for(int i = 0; i < NPROC; i++){if(proc[i].state != UNUSED){num++;}}return num;}

统计 free memory,需要读一下 kalloc.c 的代码,会发现 在 kalloc 函数中,如果 kmem.freelist 不为空的话就会分配一个 PGSIZE 的内存空间,所以只需要统计 kmem.freelist 链表长度即可。

 uint64freemem(void){struct run* r = kmem.freelist;int num = 0;while(r){r = r->next;num++;}return num * PGSIZE;}

测试结果

Lab2: System Call相关推荐

  1. 6.S081——Lab2——system calls

    0.Briefly Speaking 这是6.S081的第二个实验,目的主要是自己实现一些系统调用,上一个实验更多的是使用已有的设施去实现一些功能各异的程序,这需要我们对系统调用的过程有更加深入的理解 ...

  2. Lab system calls

    6s081 Lab2: system calls 一开始看的时候看见这两个实验都是moderate,还以为挺简单.结果因为对xv6 book不熟悉,没有弄明白整个系统调用的过程,花了很多的时间去理解x ...

  3. MIT 6.S081 Lab4 traps

    #Lab4: traps #Source #My Code #Motivation #Backtrace (moderate) #Motivation #Solution #S0 - RISC-V 栈 ...

  4. XV6实验(2020)

    XV6实验记录(2020) 环境搭建 参考连接 Lab guidance (mit.edu) 6.S081 / Fall 2020 (mit.edu) xv6 book中文版 Lab1:Xv6 and ...

  5. 操作系统实验_Chcore -- 上交IPADS操作系统银杏书配套Lab实验笔记 - Lab2内存管理(一)...

    实验为IPADS<现代操作系统原理与实现>配套实验,慕课上有完整的课程教学视频,以下为个人实验过程和踩坑记录. 物理内存布局 当bootloader和内核被加载到内存中的时候,物理内存到底 ...

  6. sv_labs学习笔记——sv_lab3(System Verilog)

    这里我们在前两个lab的基础上继续完善,搭建一个数据接受的功能.在lab2 中我们实现了相关发送信息的打印,选择发送接受的端口,完善发送时序,在这一小节中将实现对端口发送数据的回收,然后进行比较发送的 ...

  7. sv_labs学习笔记——sv_lab2(System Verilog)

    该博文在lab1的基础上,根据说明以及solution里的文件,实现了接口发送时序.简单对代码进行分析.分析的内容在文章的注释区中.对于不是很清楚的语法进行解释.最后在原文件的基础上给出增加了相关打印 ...

  8. EE308 LAB2

    EE308 LAB2 LAB2 Progress Logging Ⅰ. Use Git to conduct version control 1. Create Github Repository 2 ...

  9. 软件构造 Lab-2 Report

    文章目录 1 实验目标概述 2 实验环境配置 3 实验过程 3.1 Poetic Walks 3.1.1 Get the code and prepare Git repository 3.1.2 P ...

最新文章

  1. 卷积神经网络为什么能称霸计算机视觉领域?
  2. MyBatis Generator模板
  3. 前端学习(3074):vue+element今日头条管理-删除文章处理完成
  4. 去超市一定要存包吗_去东京一定要去的富士河口湖
  5. bambook引起的adb启动异常的问题
  6. 万物皆可Graph | 当推荐系统遇上图神经网络(四)
  7. C#中获得窗体的句柄
  8. ColorUI使用与技巧
  9. 搜狗微信临时链接转换成永久链接
  10. 麻省理工学院公开课:算法导论
  11. 解决Gitlab的The remote end hung up unexpectedly错误
  12. MAXON宣布任命高级领导人员
  13. uniapp禁止单页面侧滑返回
  14. 分布式存储系统 之 数据备份
  15. 蓝光影视媒体菜单结构浅析[原版加字幕保留花絮/主菜单/弹出菜单并分割对应PS3]...
  16. 罗素:自由主义的十诫
  17. kelvin模型蠕变方程_基于改进Kelvin模型的三维蠕变损伤模型研究
  18. Repeater用法(
  19. AlphaGo Zero 模型框架
  20. Laravel8.x+AntDesign+Vue智慧社区台管理系统框架

热门文章

  1. 浙江大学百人计划研究员申文博:容器场景下的内核安全
  2. Android Launcher开发(五)添加应用程序桌面快捷方常见问题及解决方案
  3. 原来我依旧那么思念你
  4. 希尔(Shell sort)算法
  5. 01-0003 C++诸多排序算法,前来报到~
  6. qt蓝牙开发基本步骤
  7. jpane1_java – 如何将数据从一个JPanel传递给其他...
  8. 我在富士康挨踢了七年(五. 激情与暴力)
  9. 公钥密码体制及RSA公钥加密算法(下)
  10. 使用Serv-U搭建FTP服务器并公网访问