1. 程式人生 > >4. read()、write() 相關函數解析

4. read()、write() 相關函數解析

也有 工作 不為 作用 自己 這也 struct ioc 應用

我們在前面講到了file_operations,其是一個函數指針的集合,用於存放我們定義的用於操作設備的函數的指針,如果我們不定義,它默認保留為NULL。其中有最重要的幾個函數,分別是open()、read()、write()、ioctl(),下面分別對其進行解析

一、 打開和關閉設備函數a -- 打開設備

int (open) (struct inode , struct file );
在操作設備前必須先調用open函數打開文件,可以幹一些需要的初始化操作。當然,如果不實現這個函數的話,驅動會默認設備的打開永遠成功。打開成功時open返回0。b -- 關閉設備
int (
release) (struct inode , struct file

);
當設備文件被關閉時內核會調用這個操作,當然這也可以不實現,函數默認為NULL。關閉設備永遠成功。這兩個函數已經講過,這裏不再贅述,主要看下面幾個函數

二、read()、write() 函數

現在把 read()、write() 兩個函數放一起講,因為兩個函數非密不可分的,先看一下兩個函數的定義
a -- read() 函數
技術分享圖片

b -- write() 函數
技術分享圖片

兩個函數的作用分別是 從設備中獲取數據及發送數據給設備,應用程序中與之對應的也有 write() 函數及 read() 函數:
技術分享圖片

我們知道,應用程序工作在用戶空間,而驅動工作在內核空間,二者不能直接通信的,那我們用何種方法進行通信呢?下面介紹一下內核中的memcpy---copy_from_user和copy_to_user,雖然說內核中不能使用C庫提供的函數,但是內核也有一個memcpy的函數,用法跟C庫中的一樣。
技術分享圖片


可以看到兩個函數均是調用了_memcpy() 函數:
技術分享圖片

既然拷貝的功能__memcpy函數就可以實現,為什麽還要封裝成copy_to_user和copy_from_user。
因為_memcpy有缺陷,比如當我們在引用層調用函數是傳入的不是字符串,而是一個不能訪問否則修改的地址。那樣就會造成系統崩潰。
出於上面的原因,內核和用戶態之間交互的數據時必須要先對數據進行檢測,如果數據是安全的,才可以進行數據交互。
上面的函數就是memcpy的改進版,在memcpy功能的基礎上加上的檢查傳入參數的功能,防止有些人有意或者無意的傳入無效的參數。

現在我們可以審視一下這兩個函數了:
技術分享圖片

用法:和memcpy的參數一樣,但它根據傳參方向的不同分開了兩個函數。
"to"是相對於內核態來說的。所以,to函數的意思是從from指針指向的數據將n個字節的數據傳到to指針指向的數據。
"from"也是相對於內核來說的。所以,from函數的意思是從from指針指向的數據將n個字節的數據傳到to指針指向的數據。
返回值:函數的返回值是指定要讀取的n個字節中還剩下多少字節還沒有被拷貝。
註意:一般的,如果返回值不為0時,調用copy_to_user的函數會返回錯誤號-EFAULT表示操作出錯。當然也可以自己決定。到這裏open、close、read、write四個函數已經學完,
下面我們來看一下四個函數使用時,到底經歷了一個怎樣的過程:註:箭頭方向是從調用的一方指向受作用的一方
************************代理****************************

4. read()、write() 相關函數解析