我知道我们不能直接将参数传递给 xv6 系统调用,我们被迫使用它的内置方法。

但是本站点中的所有示例和问题都是关于如何将整数发送到系统调用。它的答案是使用 argint() 方法。

但我的问题是,是否有将“struct”传递给 xv6 系统调用的方法?是否也有用于此目的的内置方法?

如果有,能否举个简单的例子?

最佳答案

可以通过系统调用传递结构。

虽然不能将结构本身作为系统调用参数传递,但可以传递指向它的指针,并且允许将其用作输入或输出参数。

允许使用数据本身作为参数而不是指向它的指针将破坏系统调用机制的要求——因为必须以通用方式实现传递数据,以允许使用所有数据类型(以及 future 的结构)。

让我们看看系统调用 fstat 的现有实现。

int fstat(int fd, struct stat *st);

fstat 需要一个文件描述符编号作为输入,并使用 struct stat 输出匹配的统计信息。
struct stat {
  short type;  // Type of file
  int dev;     // File system's disk device
  uint ino;    // Inode number
  short nlink; // Number of links to file
  uint size;   // Size of file in bytes
};

尽管 fstat 使用结构指针作为输出参数,但将其用作输入也是类似的。

内核代码中的函数 sys_fstat 开始执行 fstat 系统调用(XV6 的约定是通过 sys_* 函数处理从用户空间获取参数)。
int sys_fstat(void)
{
  struct file *f;
  struct stat *st;

  if(argfd(0, 0, &f) < 0 || argptr(1, (void*)&st, sizeof(*st)) < 0)
    return -1;
  return filestat(f, st);
}

该函数首先获取一个对应的struct file 到第一个fstat 函数参数(使用argf​​d)接收到的文件描述符编号。然后,使用 argptr 获取由第二个 fstat 函数参数接收的 struct stat 指针,并将给定的指针保存在本地(函数作用域)指针变量中。

此时,所有参数都已获取并可被内核实现使用。

注意: 虽然struct stat 指针是一个用户空间指针(位于虚拟空间的下半部分),但内核在这里使用它是安全的,因为当内核为进程的系统调用服务时,它使用进程自己的分页表。

关于c - 将结构传递给 xv6 系统调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53383938/

10-16 06:15