我正在尝试进行自定义系统调用。
我的系统调用需要2个参数struct buffer **mybuffer
& int size
。
它强加了**mybuffer
发生的任何变化应反映在用户空间中,但它似乎无效。
所以我在其他地方看到我可以使用copy_to_user(void *dest, void *src, int size)
将数据从内核空间复制到用户空间。
在用户空间中我有一个名为buffer的结构,这个结构在系统调用中也是一样的。
typedef struct buffer {
int n;
}buffer;
int main(void)
{
buffer **buf = malloc(sizeof(buffer *));
int i = 0
for(;i<8;i++)
buf[i] = malloc(sizeof(buffer));
long int sys = systemcall(801,buf,8)
//print out buf
return 0;
}
在系统调用中我有
asmlinkage long sys_something(buffer **buf,int size)
{
//allocate buffer same as it appears in int main
//fill buf with some data
for(i = 0; i<size,i++)
copy_to_user(buf[i],buf[i],sizeof(buffer));
我很确定我做错了什么。实际上如何将数据从内核空间复制到用户空间?
P.S。我正在使用linux内核3.16.0
答案 0 :(得分:10)
函数copy_to_user
用于将数据从内核地址空间复制到用户程序的地址空间。例如,将已分配了kmalloc
的缓冲区复制到用户提供的缓冲区。
编辑:您的示例有点复杂,因为您传递了一系列指向系统调用的指针。要访问这些指针
您必须先使用buf
将数组copy_from_user
复制到内核空间。
因此,您的内核代码应如下所示:
asmlinkage long sys_something(buffer **buf, int size)
{
/* Allocate buffers_in_kernel on stack just for demonstration.
* These buffers would normally allocated by kmalloc.
*/
buffer buffers_in_kernel[size];
buffer *user_pointers[size];
int i;
unsigned long res;
/* Fill buffers_in_kernel with some data */
for (i = 0; i < size; i++)
buffers_in_kernel[i].n = i; /* just some example data */
/* Get user pointers for access in kernel space.
* This is a shallow copy, so that, the entries in user_pointers
* still point to the user space.
*/
res = copy_from_user(user_pointers, buf, sizeof(buffer *) * size);
/* TODO: check result here */
/* Now copy data to user space. */
for (i = 0; i < size; i++) {
res = copy_to_user(user_pointers[i], &buffers_in_kernel[i], sizeof(buffer));
/* TODO: check result here */
}
}
最后但并非最不重要的是,您的main
功能存在错误。在第一个malloc
调用时,它只为1个指针而不是8分配足够的空间。它应该是:
int main(void)
{
const int size = 8;
buffer **buf = malloc(sizeof(buffer *) * size);
for(int i=0; i<size; i++) buf[i] = malloc(sizeof(buffer));
long int sys = systemcall(801,buf,size)
//print out buf
return 0;
}