內核空間與用戶空間的通訊方式

內核空間與用戶空間的通訊方式

  下面總結了7種方式,主要對之前不是很熟悉的方式作了編程實現,以便加深印象 linux

 

1.使用API這是最常使用的一種方式了 編程

A.get_user(xptr):在內核中被調用,獲取用戶空間指定地址的數值並保存到內核變量x中。 緩存

B.put_user(xptr):在內核中被調用,將內核空間的變量x的數值保存到到用戶空間指定地址處。 異步

C.Copy_from_user()/copy_to_user():主要應用於設備驅動讀寫函數中,經過系統調用觸發。 socket

 

2.使用proc文件系統:sysfs文件系統相似,也能夠做爲內核空間和用戶空間交互的手段。 函數

/proc 文件系統是一種虛擬文件系統,經過他能夠做爲一種linux內核空間和用戶空間的。與普通文件不一樣,這裏的虛擬文件的內容都是動態建立的。 測試

使用/proc文件系統的方式很簡單。調用create_proc_entry,返回一個proc_dir_entry指針,而後去填充這個指針指向的結構就行了,我下面的這個測試用例只是填充了其中的read_proc屬性。 ui

   下面是一個簡單的測試用例,經過讀虛擬出的文件能夠獲得內核空間傳遞過來的「proc ! test by qiankun!」字符串。 spa

 

 

3.使用sysfs文件系統+kobject其實這個之前是編程實現過得,可是那天太緊張忘記了,T_T。每一個在內核中註冊的kobject都對應着sysfs系統中的一個目錄。能夠經過讀取根目錄下的sys目錄中的文件來得到相應的信息。除了sysfs文件系統和proc文件系統以外,一些其餘的虛擬文件系統也能一樣達到這個效果。 3d

 

4.netlinknetlink 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_operationsmmap函數,咱們還能夠重寫其餘的方法如ioctl等,來達到驅動內核空間和用戶空間通訊的方式。

 

7.信號:從內核空間向進程發送信號。這個卻是常常遇到,用戶程序出現重大錯誤,內核發送信號殺死相應進程。

 


代碼以下:







附件列表

相關文章
相關標籤/搜索