下面總結了7種方式,主要對之前不是很熟悉的方式作了編程實現,以便加深印象。html
1.使用API:這是最常使用的一種方式了linux
A.get_user(x,ptr):在內核中被調用,獲取用戶空間指定地址的數值並保存到內核變量x中。編程
B.put_user(x,ptr):在內核中被調用,將內核空間的變量x的數值保存到到用戶空間指定地址處。緩存
C.Copy_from_user()/copy_to_user():主要應用於設備驅動讀寫函數中,經過系統調用觸發。異步
2.使用proc文件系統:和sysfs文件系統相似,也能夠做爲內核空間和用戶空間交互的手段。socket
/proc 文件系統是一種虛擬文件系統,經過他能夠做爲一種linux內核空間和用戶空間的。與普通文件不一樣,這裏的虛擬文件的內容都是動態建立的。函數
使用/proc文件系統的方式很簡單。調用create_proc_entry,返回一個proc_dir_entry指針,而後去填充這個指針指向的結構就行了,我下面的這個測試用例只是填充了其中的read_proc屬性。測試
下面是一個簡單的測試用例,經過讀虛擬出的文件能夠獲得內核空間傳遞過來的「proc ! test by qiankun!」字符串。spa
3.使用sysfs文件系統+kobject:其實這個之前是編程實現過得,可是那天太緊張忘記了,T_T。每一個在內核中註冊的kobject都對應着sysfs系統中的一個目錄。能夠經過讀取根目錄下的sys目錄中的文件來得到相應的信息。除了sysfs文件系統和proc文件系統以外,一些其餘的虛擬文件系統也能一樣達到這個效果。指針
4.netlink:netlink socket提供了一組相似於BSD風格的API,用於用戶態和內核態的IPC。相比於其餘的用戶態和內核態IPC機制,netlink有幾個好處:1.使用自定義一種協議完成數據交換,不須要添加一個文件等。2.能夠支持多點傳送。3.支持內核先發起會話。4.異步通訊,支持緩存機制。
對於用戶空間,使用netlink比較簡單,由於和使用socket很是的相似,下面說一下內核空間對netlink的使用,主要說一下最重要的create函數,函數原型以下:
extern struct sock *netlink_kernel_create(struct net *net,
int unit,unsigned int groups,
void (*input)(struct sk_buff *skb),
struct mutex *cb_mutex,
struct module *module);
第一個參數通常傳入&init_net。
第二個參數指的是netlink的類型,系統定義了16個,咱們若是使用的話最好本身定義。這個需和用戶空間所使用的建立socket的第三個參數一致,才能夠完成通訊。
第四個參數指的是一個回調函數,當接受到一個消息的時候會調用這個函數。回調函數的參數爲struct sk_buff類型的結構體。經過分析其結構成員能夠獲得傳遞過來的數據
第六個參數通常傳入的是THIS_MODULE。指當前模塊。
下面是對netlink的一個簡單測試,將字符串「netlink test by qiankun」經過netlink輸出到內核,內核再把字符串返回。Netlink類型使用的是22.
5.文件:應該說這是一種比較笨拙的作法,不過確實能夠這樣用。當處於內核空間的時候,直接操做文件,將想要傳遞的信息寫入文件,而後用戶空間能夠讀取這個文件即可以獲得想要的數據了。下面是一個簡單的測試程序,在內核態中,程序會向「/home/melody/str_from_kernel」文件中寫入一條字符串,而後咱們在用戶態讀取這個文件,就能夠獲得內核態傳輸過來的數據了。
6.使用mmap系統調用:能夠將內核空間的地址映射到用戶空間。在之前作嵌入式的時候用到幾回。一方面能夠在driver中修改Struct file_operations結構中的mmap函數指針來從新實現一個文件對應的映射操做。另外一方面,也能夠直接打開/dev/mem文件,把物理內存中的某一頁映射到進程空間中的地址上。
其實,除了重寫Struct file_operations中mmap函數,咱們還能夠重寫其餘的方法如ioctl等,來達到驅動內核空間和用戶空間通訊的方式。
7.信號:從內核空間向進程發送信號。這個卻是常常遇到,用戶程序出現重大錯誤,內核發送信號殺死相應進程。
轉自:http://www.cnblogs.com/dchipnau/p/5043591.html