copy_to_user -- Copy a block of data into user space. copy_from_user -- Copy a block of data from user space.get_user -- Get a simple variable from user space.
put_user -- Write a simple value into user space.
文章出處:飛諾網(www.diybl.com):http://www.diybl.com/course/6_system/linux/Linuxjs/20101230/551611.html
copy_from_user
Name
copy_from_user -- Copy a block of data from user space.
Synopsis
unsigned long copy_from_user (void * to, const void __user * from, unsigned long n);
Arguments
to
Destination address, in kernel space.
from
Source address, in user space.
n
Number of bytes to copy.
Context
User context only. This function may sleep.
Description
Copy data from user space to kernel space.
Returns number of bytes that could not be copied. On success, this will be zero.
If some data could not be copied, this function will pad the copied data to the requested size using zero bytes.
copy_to_user
Name
copy_to_user -- Copy a block of data into user space.
Synopsis
unsigned long copy_to_user (void __user * to, const void * from, unsigned long n);
Arguments
to
Destination address, in user space.
from
Source address, in kernel space.
n
Number of bytes to copy.
Context
User context only. This function may sleep.
Description
Copy data from kernel space to user space.
Returns number of bytes that could not be copied. On success, this will be zero.
put_user
Name
put_user -- Write a simple value into user space.
Synopsis
put_user ( x, ptr);
Arguments
x
Value to copy to user space.
ptr
Destination address, in user space.
Context
User context only. This function may sleep.
Description
This macro copies a single simple value from kernel space to user space. It supports simple types like char and int, but not larger data types like structures or arrays.
ptr must have pointer-to-simple-variable type, and x must be assignable to the result of dereferencing ptr.
Returns zero on success, or -EFAULT on error.
put_user() 宏函數
功能:把核心變量值寫入使用者空間
原型: put_user (x, ptr)
說明: put_user 宏函數在 ptr 指向的使用者記憶體空間上寫入 x 變量大小的資料
變量:
•x 核心變量
•ptr 使用者記憶體塊的起始位址
get_user
Name
get_user -- Get a simple variable from user space.
Synopsis
get_user ( x, ptr);
Arguments
x
Variable to store result.
ptr
Source address, in user space.
Context
User context only. This function may sleep.
Description
This macro copies a single simple variable from user space to kernel space. It supports simple types like char and int, but not larger data types like structures or arrays.
ptr must have pointer-to-simple-variable type, and the result of dereferencing ptr must be assignable to x without a cast.
Returns zero on success, or -EFAULT on error. On error, the variable x is set to zero.
Linux中put_user和memcpy的差別
http://bbs.51soc.com/read.php?tid=361
我在從事linux kernel開發的時候,知道user app和kernel子產品之間傳輸資料不能使用memcpy,必須使用copy_to/from_user或是put/get_user。原因就是kernel和user app記憶體不能直接互訪。僅僅明白到這個層次。具體為什麼不能直接互訪,也說不出什麼來。
最近在ARM平台上開發,看了一下kernel中put_user的代碼和關于linux kernel的資料,自己對這個問題的了解有加深了一些。現在總結如下
首先 Linux的kernel和user app運作在不同的模式。在ARM上就是kernel運作在SVC模式(最進階),App運作在user模式。當user app執行一個system call調用kernel代碼,kernel會完成CPU的模式切換。SVC模式能通路的寄存器更多,如果在kernel中對user app傳入的位址直接通路,可能會有以下問題:傳入的位址是錯誤的,則kernel也可以通路,可能會破壞其他kernel内容,這會引起安全問題,memcpy不會進行位址檢查,使用專用的put_user就會執行位址檢查,判斷是否是<0xc0000000,是否在user app位址空間之内。同時在ARM平台上,最後調用的函數是__put_user_1/2/4/8。這個是一個彙編函數,使用的資料通路指令為ldrbt,這個ARM彙編指令使用user mode來通路記憶體,如果這個通路非法,這會觸發一個exception,在kernel中都加入了一個異常函數表,出現異常則調用__get_user_bad
個人感覺使用專用函數在kernel和user app之間傳遞資料就是為了安全,防止參數非法破壞kernel
文章出處:飛諾網(www.diybl.com):http://www.diybl.com/course/6_system/linux/Linuxjs/20101230/551611.html