xv6 traps 和系统调用

系统调用和 traps 密不可分,系统调用需要用到 traps,所以这里将系统调用和 traps 结合到一起理解,当然重点是 traps。

系统调用相关文件

  • user.h
  • usys.pl
  • syscall.h
  • syscall.c
  • sysproc.c
  • sysfile.c

异常和中断相关文件

  • trampoline.S
  • trap.c
  • proc.h

异常与中断

关于异常和中断的详细内容可以看看[[七、中断与异常]]。这里粗略地讲讲:

上图是异常和中断的程序流,可以看到异常和中断的处理都是暂停当前程序(这里会保存上下文),转而执行另一程序,最后再返回当前程序(恢复上下文)。这种暂停当前程序转而执行另一程序的方式也成为陷入,即 traps。

系统调用的原理也是 traps。因此,这里我们需要把两者结合起来理解。首先从系统调用开始

系统调用

我们先来看一段 lab0 中中编写的简单程序:

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{
   
   
    if (argc < 2) {
   
   
        fprintf(2, "Usage: sleep time\n");
        exit(1);
    }
    
    int time = atoi(argv[1]);
    sleep(time);

    exit(0);
}

在这个简单程序中,我们只是调用了 sleep 函数。sleep 函数允许一个进程暂停执行一段指定的时间,这个过程是由内核完成,因此会涉及系统调用。我们利用 IDE 的功能查看 sleep 函数定义在哪里。

可以看到 sleep 函数定义在 user.h 文件中,其中包含了很多系统调用函数,如下所示:

// user.h 节选
struct stat;
struct rtcdate;
struct sysinfo;

// system calls
int fork(void);
int exit(int) __attribute__((noreturn));
int wait(int*);
int pipe(int*);
int write(int, const void*, int);
int read(int, void*, int);
int close(int);
int kill(int);
int exec(char*, char**);
int open(const char*, int);
int mknod(const char*, short, short);
int unlink(const char*);
int fstat(int fd, struct stat*);
int link(const char*, const char*);
int mkdir(const char*);
int chdir(const char*);
int dup(int);
int getpid(void);
char* sbrk(int);
int sleep(int);
int uptime(void);
int trace(int);
int sysinfo(struct sysinfo *);

当然这些函数在 user.h 中仅仅是函数描述,而非实现,系统调用函数的实现在内核中。下面我们需要清楚调用系统调用函数时,是如何从用户空间陷入内核空间的。

经过查阅我们知道,操作系统会运行一段段 Perl 脚本 usys.pl 来生成 xv6 操作系统用户级系统调用入口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值