MIT6.S081-Syscall Lab

MIT6.S081

MIT6.S081 Fall 2020.

syscall lab

这个实验需要自己实现一些系统功能调用

前置知识

  • xv6的启动过程
  1. Qemu启动RISC-V模拟,在只读内存中读取并运行启动加载程序(boot loader)
  2. CPU在_entry(kernel/entry.S)以机器模式执行,此时没有分页,虚拟地址直接映射
  3. 启动加载程序加载内核到0x80000000
  4. 调用start()函数
  5. 进入内核模式,执行kernel/main.c
  6. userinit()创建第一个进程
  7. exec调用user/inti.c,创建标准输入输出,并启动shell程序
  • 系统功能调用的全过程
  1. 用户态中实现应用程序,调用user.h中的系统调用C接口
  2. 通过usys.S(由usys.pl生成),将系统调用号加载到a7,然后进入内核态
  3. 调用syscall函数,先取出a7得到系统调用号,然后执行syscallnum
  • 系统调用中获取参数
    C接口是int trace(int),系统调用却是uint64 sys_trace(void)
    所以需要用一种方式获取参数
    也就是argaddr和argint,分别获取地址和整数类型参数

如果需要实现一个系统功能调用

  • 用户态
  1. user/user.h里面是用户态的接口
  2. user/usys.pl(perl语言),用于生成usys.S
  • 内核态
  1. kernel/syscall.c和syscall.h
    syscall.h里面定义了系统功能调用号
  2. sysproc.c中增加系统功能的实现
  • 用户态->内核态
  1. kernel/proc.c和proc.h
  • struct proc

  • struct sysinfo

  • struct run & kmem

// 空闲内存链表,每个空闲区大小PGSIZE
struct run {
  struct run *next;
};

// 当前进程空闲内存信息
struct {
  struct spinlock lock;
  struct run *freelist;
} kmem;

trace

根据传入的系统功能调用号,来跟踪进程的系统功能调用情况
调用方式:trace mask command [command args]

根据hints来看
该实验已经实现了一个用户态的trace,但是需要自己添加:

  1. 用户态的接口,user.h中C接口的声明和usys.pl中entry。
  2. 在内核态syscall.h中添加系统调用号;syscall.c中添加sys_trace的声明,并在syscall函数中输出相应的系统功能调用信息
  3. sysproc中添加sys_trace的实现,把mask传递到trace_mask里

sysinfo

实现一个sysinfo的系统调用
sysinfo:

  1. 当前空闲内存的大小freemem
  2. 非UNUSED状态进程数量

添加系统调用的方法和trace差不多
实现sys_sysinfo

  1. 获取用户传入地址addr(用户空间)
  2. 内核空间创建sysinfo,并获取相应参数get_freemem()及get_nproc()
  3. 将sysinfo copyout到addr上(参考sys_ftat)

这个实验思路上不算很难,但是需要去理解xv6内核代码里面定义的一些结构和函数,还是花了挺多时间,也参考了网上的一些教程。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值