zoukankan      html  css  js  c++  java
  • xv6 系统调用

    1. 系统调用的实现

      开发程序需所有的接口在user.h中,包含两部分system call和ulib

      user.h中的系统接口函数在usys.S中通过汇编实现

    #define SYSCALL(name) 
      .globl name; 
      name: 
        movl $SYS_ ## name, %eax; 
        int $T_SYSCALL; 
        ret
    
    SYSCALL(fork)
    .......

      把系统调用ID放入eax中,使用int T_SYSCALL中断

    2. int 指令

      int n 指令是调用n号中断的中断过程。最终效果和函数调用类似,中断过程执行结束过后返回。

    3. xv6 中断处理

      在tvinit中生成了中断描述表(IDT),然后在idtinit中加载该中断描述表,注册0-255中断的处理过程。在tvinit函数中我们可以看到T_SYSCALL中断要求的调用权限是 DPL_USER,所有我们可以在用户空间调用T_SYSCALL中断。

      每个中断的处理过程在vectors.S(vector.pl生成)中实现,压入不同参数过后执行alltraps。在alltraps中准备参数trapframe,然后调用c实现的函数trap。

      trap函数实现如下:

      

    void trap(struct trapframe *tf)
    {
      if(tf->trapno == T_SYSCALL){
        if(myproc()->killed)
          exit();
        myproc()->tf = tf;
        syscall();
        if(myproc()->killed)
          exit();
        return;
      }
        .....
    }

      当中断是T_SYSCALL时执行函数syscall, syscall根据eax中的系统调用id,确定具体函数,执行相应函数,把执行结果放入eax中。

    void syscall(void)
    {
      int num;
      struct proc *curproc = myproc();
    
      num = curproc->tf->eax;
      if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
        curproc->tf->eax = syscalls[num]();
      } else {
        cprintf("%d %s: unknown sys call %d
    ",
                curproc->pid, curproc->name, num);
        curproc->tf->eax = -1;
      }
    }

    //TODO trapframe 是如何构建的

    参考:https://th0ar.gitbooks.io/xv6-chinese/content/content/chapter0.html

  • 相关阅读:
    宝藏 题解
    Xorequ 题解
    2020.12.26 模拟赛 题解
    数据结构 100 题 1~10 线段树
    关于模拟退火
    诗意狗 题解
    Keyboading 思路
    体育成绩统计/ Score
    【(抄的)题解】P5686 [CSP-SJX2019]和积和
    【笔记】简单博弈
  • 原文地址:https://www.cnblogs.com/hygblog/p/9337643.html
Copyright © 2011-2022 走看看