我知道我们无法将参数直接传递给xv6系统调用,我们被迫使用它内置于方法中。
但是这个站点中的所有例子和问题都是关于如何发送整数到系统调用。答案是使用argint()方法。
但我的问题是,是否存在将"struct“传递给xv6系统调用的问题?是否也有任何用于此目的的占线方法?
如果有的话,你能说一个简单的例子吗?
发布于 2018-11-24 07:22:40
通过系统调用传递结构是可能的。
虽然不能将结构本身作为系统调用参数传递,但传递指向它的指针是可能的,并允许将其用作输入或输出参数。
允许使用数据本身而不是指向数据的指针将破坏系统调用机制的要求,因为必须以通用方式实现传递数据,以允许使用所有数据类型(以及未来的结构)。
让我们看看系统调用fstat的现有实现。
int fstat(int fd, struct stat *st);fstat需要一个文件描述符号作为输入,并使用struct输出匹配的统计信息。
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使用struct指针作为输出参数,但使用它作为输入将是类似的。
内核代码中的函数sys_fstat启动fstat系统调用的实现(XV6 6的惯例是处理通过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)接收的文件描述符号对应的struct文件。然后,使用argptr获取由第二个fstat函数参数接收的struct指针,并将给定的指针保存在本地(函数范围)指针变量中。
此时,所有参数都被获取,并可由内核实现使用。
备注:虽然struct指针是一个用户空间指针(位于虚拟空间的下半部分),但是内核在这里使用它是安全的,因为当内核为进程‘系统调用服务时,它使用的是进程自己的分页表。
发布于 2018-11-24 16:58:06
虽然上面的答案是正确的,但我更喜欢写我自己的解决方案,以使它更适用于其他viwers。
我使用argptr将一个指向结构的指针传递给我的系统调用。
在syspro.c中:
int sys_counts (void){
struct countTable *ct;
argptr (0 , (void*)&ct ,sizeof(*ct));
return counts(ct);
}在pro.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();
}发布于 2022-01-23 11:56:00
虽然其中一个答案是可以接受的,但我写的答案是清晰和完整的。
请注意,直接将参数传递给系统调用是不可能的。我们将用argptr来做这件事。
在用户空间中,我们定义了要使用的结构。在像test.c这样的用户级别文件中。
#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);
}在proc.c中,我们可以编写系统调用的功能:
int doSomeWork(void *data){
// cast to (struct Data *)
struct Data *my_data = (struct Data *)data;
...
// work with my_data
...
return 0;
}为了使syspro.c和proc.c内部可以访问数据结构,我们在Defs.h中定义了数据结构:
struct Data
{
...
int id; // some fields
...
};https://stackoverflow.com/questions/53383938
复制相似问题