在前面講過,驅動層是應用層是分離,驅動層的代碼不能使用再應用層,應用層也不能直接操作驅動代碼,那麼應用層和驅動層之間是如何來實作資料間的交換的能,方法就是通過相應的接口函數。
(1)copy_from_user
<code>unsigned </code><code>long</code> <code>copy_from_user(</code><code>void</code> <code>*to, </code><code>const</code> <code>void</code> <code>__user *from, unsigned </code><code>long</code> <code>n)</code>
<code>{</code>
<code> </code><code>might_sleep(); </code>
<code> </code><code>if</code> <code>(access_ok(VERIFY_READ, from, n))</code>
<code> </code><code>n = __copy_from_user(to, from, n);</code>
<code> </code><code>else</code>
<code> </code><code>memset</code><code>(to, 0, n);</code>
<code> </code><code>return</code> <code>n;</code>
<code>}</code>
這個函數是從使用者空間拷貝資料到核心空間,失敗傳回沒有被拷貝的位元組數,成功傳回0,注意使用者空間的資料不能直接通過memcpy複制到核心空間,原因是核心空間和使用者空間的位址不在同一個映射區域裡面。核心空間和使用者空間的記憶體是不能直接通路的。
(2)copy_to_user
<code>unsigned </code><code>long</code> <code>copy_to_user(</code><code>void</code> <code>__user *to, </code><code>const</code> <code>void</code> <code>*from, unsigned </code><code>long</code> <code>n)</code>
<code> </code><code>might_sleep();</code>
<code> </code><code>BUG_ON((</code><code>long</code><code>) n < 0);</code>
<code> </code><code>if</code> <code>(access_ok(VERIFY_WRITE, to, n))</code>
<code> </code><code>n = __copy_to_user(to, from, n);</code>
<code> </code><code>return</code> <code>n;</code>
傳回值和copy_from_user一樣,成功傳回0,失敗傳回沒有拷貝成功的位元組數。
參數to有個__user限定,這個在~/include/linux/compiler.h中有如下定義:
# define __user __attribute__((noderef, address_space(1)))
表示這是一個使用者空間的位址,即其指向的為使用者空間的記憶體。
__attribute__是gnu c編譯器的一個功能,它用來讓開發者使用此功能給所聲明的函數或者變量附加一個屬性,以友善編譯器進行錯誤檢查,其實就是一個核心檢查器。
以上兩個函數參考
<a href="http://blog.sina.com.cn/s/blog_55465b470100kdn9.html" target="_blank">http://blog.sina.com.cn/s/blog_55465b470100kdn9.html</a>
本文轉自 菜鳥養成記 51CTO部落格,原文連結:http://blog.51cto.com/11674570/1872418