s081-2020 Lab2: system call

Lab2: system call

在这里插入图片描述

lab2总体来说还是很简单的,只要我们打通system call的调用链路,就没有问题了。教材第四章中对于xv6处理trap的软硬件过程有详细的讲解,具体的执行流程这里不在赘述,简单讲解一下用户程序执行system call在函数级别的执行路径,当然知道这些已经能够完成该实验了。

我们以System call tracing为例描述整个过程:

首先要在Makefile文件中添加$U/_trace ,使得trace.c能给被正确编译连接到xv6中。

trace.c中的main()函数通过调用系统调用函数trace()来完成system call tracing的目的,为了能够正确调用trace()我们必须user/user.h声明其定义。系统调用用来贯穿用户态与内核态,这一过程是通过汇编代码来控制的,因此trace()的实现就是汇编代码,汇编代码会直接在链接阶段与trace.c链接在一起;实验中是通过脚本自动生成对应的汇编代码的,我们可以在usys.pl中看到相应的模版,在此我们只需要添加entry("trace")即可,表示我们定义了trace()的汇编代码实现。从汇编模版中我们看到在执行ecall指令之前,需要将系统调用号传递给a7,因此我们还需要定义SYS_trace的系统调用号kernel/syscall.h定义了内核为用户进程提供的系统调用,我们只需要为SYS_trace设置一个系统调用号即可。以上就是能够正确编译用户态代码所需要的全部工作,但是编译成功不代表能够正确执行,在xv6中如果调用trace会打印"unknown sys call"的错误,这是因为我们还没有在内核态实现相应的系统调用sys_trace()

SYS_trace是联系用户态系统调用trace()与内核态系统调用sys_trace()的纽带,ecall触发trap后硬件处理机制会将SYS_trace传递到内核态,指令流到达syscall.c中的syscall()syscall()根据该系统调用号执行对应的系统调用;为此我们需要sysproc.c中定义sys_trace(),并且将该函数添加到syscall.c的系统调用表syscalls。至此一个完整的系统调用链路就完成了。

sys_trace

接下来的任务就是实现sys_trace(),其实hits中已经说的很清楚了:

struct proc添加一个字段trace_syscall,用来在syscall()中判断是否需要打印该system call:

// kernel/syscall.c

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]()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值