2015-12-08 88 views
3

我正在嘗試進行自定義系統調用。將數據從內核空間複製到用戶空間

我的系統調用需要2個參數struct buffer **mybuffer & int size

它強加的任何變化發生在**mybuffer應該反映在用戶空間,但它似乎不起作用。

所以我在其他地方看到我可以使用copy_to_user(void *dest, void *src, int size)將數據從內核空間複製到用戶空間。

在用戶空間我有一個叫做緩衝區的結構體,這個結構體在系統調用中也是一樣的。

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

有'dest'和'src'等於'BUF [I]'肯定是不對的。你想拷貝什麼** kernel **的數據?指向這些數據的指針應該用作'copy_to_user'的第二個參數。還要注意,因爲第一個syscall的參數實際上是一個*指針數組*,所以您需要使用'copy_from_user'來讀取這些指向內核(臨時)內存的指針,然後在'copy_to_user'調用中使用該內核內存中的指針。 – Tsyvarev

回答

7

函數copy_to_user用於將數據從內核地址空間複製到用戶程序的地址空間。例如,要將已分配了kmalloc的緩衝區複製到用戶提供的緩衝區中。

編輯:你的例子有點複雜,因爲你傳遞一個指向數組的指針。要訪問這些指針 ,您必須首先使用copy_from_user將數組buf複製到內核空間。

因此,你的內核代碼應該是這樣的:

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; 
} 
+0

Btw copy_to_user(void * dst,const void * src,const int size); 無論如何謝謝:)你真的做得很好 –

+0

另外我需要指出,我測試了我的系統調用,而不執行'copy_from_user()'宏並將數據複製到用戶空間。 –

相關問題