我知道我们不能将参数直接传递给xv6系统调用,因此我们不得不使用它的内置方法。
但是此站点中的所有示例和问题都与如何将整数发送给系统调用有关。答案是使用argint()方法。
但是我的问题是,是否有将“ struct”传递给xv6系统调用的方法?是否也有用于此目的的宣传方法?
如果有的话,您能说一个简单的例子吗?
答案 0 :(得分:0)
可以通过系统调用传递结构。
虽然不能将结构本身作为系统调用参数传递,但可以将指针传递给它,并且可以将其用作输入或输出参数。
允许将数据本身而不是其指针用作参数将破坏系统调用机制的要求-因为必须以通用方式实现传递数据的方式,以允许所有数据类型(以及将来的结构)被使用。
让我们看一下系统调用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);
}
此函数首先获取与第一个fstat函数自变量接收到的文件描述符号相对应的结构文件(使用argfd)。然后,使用argptr获取第二个fstat函数参数接收到的struct stat指针,并将给定的指针保存在本地(函数作用域)指针变量中。
这时,所有参数都已获取,并且可由内核实现使用。
注意:尽管struct stat指针是用户空间指针(位于虚拟空间的下半部分),但是内核在这里使用它是安全的,因为当内核处于服务进程的系统调用,它使用进程自己的分页表。
答案 1 :(得分:0)
尽管以上答案是正确的,但我更愿意编写自己的解决方案以使其对其他使用者更有用。
我使用argptr将指向结构的指针传递给我的系统调用。
在sysproc.c中:
int sys_counts (void){
struct countTable *ct;
argptr (0 , (void*)&ct ,sizeof(*ct));
return counts(ct);
}
在proc.c中:
int counts (struct countTable *ct){
for (int i=0 ; i<22 ; i++){
(ct->system_calls)[i] = count_calls[i] ;
}
return 22;
}
最后是我的用户空间程序:
int main (){
struct countTable *ct = malloc (sizeof (struct countTable));
// call system call
counts(ct);
exit();
}