有没有办法在Minix 3中访问和修改系统调用中的用户数据?我可以在这里使用sys_datacopy()吗?为什么我的尝试不起作用?

Goo*_*eds 5 linux pointers kernel system-calls minix

我想在Minix的PM服务器中实现一个syscall,它可以访问用户空间中的一些数据,并且可以修改它.

我使用Minix的消息传递机制将数据传递给系统调用.在message传递的结构中,我从我想要传递的用户空间中指定一个指向变量地址的指针.

例如,在用户程序中,

message m;
m.m1_p1 = &var; //data to be passed
//pass it to the syscall
Run Code Online (Sandbox Code Playgroud)

在内核中,在syscall函数中,我这样做

char *ptr = m_in.m1_p1;
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试读取或写入数据时,我收到内核惊慌失措的错误,需要重新启动.

我意识到这可能是因为在用户空间中,正在使用特定于用户的虚拟地址,这在系统调用中是无法识别的.

在进一步搜索时,我发现Linux具有功能copy_from_user()copy_to_user()实现了这一点.

有没有相当于这是Minix?如果没有,有没有其他方法来实现这一目标?


@ osgx的评论建议的帮助下,我尝试过使用sys_datacopy().虽然这允许我在系统调用中读取和写入数据,但我所做的更改不会反映回调用系统调用的用户程序.

我的最新尝试如下:

在用户程序中,

message m;
m.m1_p1 = &var; //data to be passed
printf("%c\n",*(m.m1_p1)); //gives the value in var
//pass it to the syscall
printf("%c\n",var); //gives the old value of var
Run Code Online (Sandbox Code Playgroud)

在系统调用中,

char *ptr = (char*)malloc(sizeof(char));
sys_datacopy(who_e,(vir_bytes)(m_in.m1_p1),SELF,(vir_bytes)(ptr),sizeof(char*)); //or some other version of sys_vircopy()?
printf("Read value of ptr : %c\n",*ptr); //gives correct value
*ptr = //new value
printf("New value of ptr : %c\n",*ptr); //gives modified value
Run Code Online (Sandbox Code Playgroud)

在这里,我现在可以访问varsyscall内部的值ptr,并在syscall中修改它.但是,从系统调用返回后,我发现`var'的基础值没有改变.

根据我的理解,应该发生的是sys_datacopy()应该复制一个等效的虚拟,m_in.m1_p1它位于系统调用的地址空间中ptr,指向相同的物理地址.所以,*ptr应该完全达到var,从而修改它.

或者,当我使用时,是否复制了与地址对应的数据sys_datacopy()?如果是这种情况,我能想到的一个解决方案是定义一个允许双指针并传递char**给系统调用的消息结构.然后,取消引用一次将确保将地址复制到ptr.但是再一次,解除引用ptr将尝试取消引用属于用户进程的地址空间的虚拟地址,这将无效.

为什么这种方法不起作用?实现这一目标的正确方法是什么?

我使用的是Minix 3.2.1.

谢谢.