【问题标题】:XV6 - Pass parameters to systemcall and get return valueXV6 - 将参数传递给系统调用并获取返回值
【发布时间】:2020-06-19 07:19:29
【问题描述】:

我需要在XV6 中编写一个系统调用,它获取一些整数和一些整数指针作为参数,但我不明白该怎么做。
我读到了argint 和@987654323 @,但我不明白如何使用它们。例如,我不明白它们是否既用于将参数(在用户空间内)传递给系统调用,又用于在sys_namesysproc.c 中的函数名称)中检索它们。

另外,我需要函数返回一个值,不知道怎么把返回值返回给调用函数的用户空间。

【问题讨论】:

    标签: system-calls xv6


    【解决方案1】:

    tldr:

    如果您像这样some_syscall(42) 调用系统调用,则访问42 所要做的就是调用:argint(0, &local_var)。这会将第 0 个 int 参数 42 存储到 local_var 中。

    使用 argptr,你需要给它一个指针的地址和你想要获取的内存字节数。但是,由于 32 位架构中的指针是 4 字节,所以 argint 也可以完成这项工作。

    以下是对其工作原理的高级理解:

    argint 使用一些指针数学访问参数。它访问进程的 trapframe 结构,包含系统调用的用户空间寄存器。陷阱帧从esp 寄存器开始保存函数的参数。它添加了 4 以跳过我认为特定于 xv6 的某些转换中的堆栈上的空字。 4*n 用于访问起始地址后的第 n 个 4 字节参数。

    fetchint 会进行一些错误检查,并将地址实际存储在*ip 指针指定的地址中。

    // Fetch the nth 32-bit system call argument.
    int
    argint(int n, int *ip)
    {
      return fetchint((myproc()->tf->esp) + 4 + 4*n, ip);
    }
    

    syscall.c 中,syscall() 管理将内核空间函数的返回值传递给用户。它访问该用户空间堆栈以将进程的返回值寄存器eax 设置为您的系统调用返回的任何内容。这是该行供参考:

          curproc->tf->eax = syscalls[num]();
    

    这个 github 有时对理解 xv6 很有帮助: https://github.com/YehudaShapira/xv6-explained/blob/master/Explanations.md#getting-arguments-in-system-calls

    【讨论】:

    • 所以当我调用some_syscall(42) 时,42(以及我传递的其他参数,例如整数指针)“自动”进入寄存器,而我唯一需要做的就是做的是提取然后使用argint(对于整数和整数指针)?
    • 正确。这些是由 xv6 设置的,您只需要使用argint。我想你明白这一点,但由于 xv6 是 32 位的,指针和 int 变量只有 4 字节,所以你可以同时使用 argint
    • @Dani 是否回答了您的问题?我将修改答案以包括澄清
    猜你喜欢
    • 2017-08-25
    • 1970-01-01
    • 2019-04-22
    • 2015-01-20
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    相关资源
    最近更新 更多