12.【linux驅動】內核空間用戶空間數據傳遞

linux分爲用戶空間和內核空間,兩者的虛擬地址空間分佈不一樣。內核佔用高地址,應用程序佔有低地址空間,每個進程的內核虛擬地址都是一樣的,區別在於進程的用戶控件映射不同,所以內核也可以直接使用用戶空間的指針讀寫數據,但是用戶空間的內存可能被換出去,所以還是需要藉助內核函數去讀寫。
主要有這幾個函數:access_ok(),copy_to_user(),copy_from_user,put_user,get_user

1.access_ok()

函數原型:
int access_ok(int type,unsigned long addr,unsigned long size)
函數access_ok()用於檢查指定地址是否可以訪問。參數type爲訪問方式,可以爲VERIFY_READ(可讀),VERIFY_WRITE(可寫)。addr爲要操作的地址,size爲要操作的空間大小(以字節計算)。函數返回1,表示可以訪問,0表示不可以訪問。

2.copy_to_user()和copy_from_user()

函數原型:
unsigned long copy_to_user(void *to,const void *from,unsigned long len)
unsigned long copy_from_user(void *to,const void *from,unsigned long len)
這兩個函數用於內核空間與用戶空間的數據交換。copy_to_user()用於把數據從內核空間拷貝至用戶空間,copy_from_user()用於把數據從用戶空間拷貝至內核空間。第一個參數to爲目標地址,第二個參數from爲源地址,第三個參數len爲要拷貝的數據個數,以字節計算。這兩個函數在內部調用access_ok()進行地址檢查。返回值爲未能拷貝的字節數。

3.get_user()和put_user()

函數原型:
int get_user(x,p)
int put_user(x,p)
這是兩個宏,用於一個基本數據(1,2,4字節)的拷貝。get_user()用於把數據從用戶空間拷貝至內核空間,put_user()用於把數據從內核空間拷貝至用戶空間。x爲內核空間的數據,p爲用戶空間的指針。這兩個宏會調用access_ok()進行地址檢查。拷貝成功,返回0,否則返回-EFAULT。

4.還有兩個函數__copy_to_user()和__copy_from_user()

這兩個函數功能與copy_to_user()和copy_from_user()相同,只是不進行地址檢查。還有兩個宏__get_user()和__put_user(),功能與get_user()和put_user()相同,也不進行地址檢查。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章