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
};
# include "types.h"
# include "stat.h"
# include "user.h"
struct Data
{
...
int id; // some fields
...
};
int main(int argc, char *argv[])
{
struct Data *data = malloc(sizeof(struct Data));
// call the systemcall
doSomeWork((void *)data);
exit();
}
在syspro.c中,我们定义了系统调用并使用argptr获取参数:
int sys_doSomeWork(void){
struct Data *data;
argptr(0, (void *)&data, sizeof(*data));
return doSomeWork((void *)data);
}
在pro.c中,我们可以编写系统调用的功能:
int doSomeWork(void *data){
// cast to (struct Data *)
struct Data *my_data = (struct Data *)data;
...
// work with my_data
...
return 0;
}
3条答案
按热度按时间jvidinwx1#
可以通过系统调用传递结构。
虽然不能将结构本身作为系统调用参数传递,但传递指向它的指针是可能的,并且允许将其用作输入或输出参数。
允许使用数据本身作为参数,而不是指向它的指针将破坏系统调用机制的要求-因为传递数据必须以通用的方式实现,以允许使用所有数据类型(以及未来的结构)。
让我们来看看系统调用fstat的现有实现。
Fstat需要一个文件描述符号作为输入,并使用struct stat输出匹配的统计信息。
尽管fstat使用结构指针作为输出参数,但使用它作为输入将是相似的。
内核代码中的函数sys_fstat启动fstat系统调用的实现(XV6的约定是通过sys_*函数处理从用户空间获取参数)。
该函数首先获取与第一个fstat函数参数(使用argfd)接收的文件描述符号相对应的结构文件。然后,使用argptr获取第二个fstat函数参数接收的struct stat指针,并将给定的指针保存在本地(函数作用域)指针变量中。
此时,所有参数都已获取并可由内核实现使用。
**注意:**虽然struct stat指针是一个用户空间指针(位于虚拟空间的下半部分),但内核在这里使用它是安全的,因为当内核为进程的系统调用提供服务时,它使用进程自己的分页表。
3wabscal2#
虽然上面的答案是正确的,但我更喜欢编写自己的解决方案,使其更适用于其他Viwers。
我使用argptr将指向结构的指针传递给系统调用。
在sysproc.c中:
在pro.c中:
最后在我的用户空间程序中:
col17t5w3#
虽然其中一个答案是可以接受的,但我写的答案是清楚和完整的。
请注意,直接将参数传递给系统调用是不可能的。我们将使用argptr来实现这一点。
在用户空间中,我们定义了一个我们想要使用的结构。在像test.c这样的用户级文件中
在syspro.c中,我们定义了系统调用并使用argptr获取参数:
在pro.c中,我们可以编写系统调用的功能:
为了使数据结构可以在syspro.c和pro.c中访问,我们在Defs.h中定义了数据结构: