Linux 用戶空間與內核空間數據交換方式

http://blog.sina.com.cn/s/blog_71fdf1f00102v5o8.html

引言

一般地,在使用虛擬內存技術的多任務系統上,內核和應用有不同的地址空間,因此,在內核和應用之間以及在應用與應用之間進行數據交換需要專門的機制來實現,衆所周知,進程間通信(IPC)機制就是爲實現應用與應用之間的數據交換而專門實現的,大部分讀者可能對進程間通信比較瞭解,但對應用與內核之間的數據交換機制可能瞭解甚少

本文將詳細介紹 Linux 系統下內核與應用進行數據交換的各種方式,包括內核啓動參數、模塊參數與 sysfs、sysctl、系統調用、netlink、procfs、seq_file、debugfs 和 relayfs。

系統調用

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()相同,也不進行地址檢查。

(通常情況下,應用程序通過內核接口訪問驅動程序,因此,驅動程序需要和應用程序交換數據。Linux將存儲器分爲“內核空間”和“用戶空間”。操作系統和驅動程序在內核空間運行,應用程序在用戶空間運行,兩者不能簡單地使用指針傳遞數據。因爲Linux系統使用了虛擬內存機制,用戶空間的內存可能被換出,當內核空間使用用戶空間指針時,對應的數據可能不在內存中。Linux內核提供了多個函數和宏用於內核空間和用戶空間傳遞數據。)

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