835
848 unsigned long
849 copy_to_user(void __user *to, const void *from, unsigned long n)
850 {
851 if (access_ok(VERIFY_WRITE, to, n))
852 n = __copy_to_user(to, from, n);
853 return n;
854 }
其功能是将核心空間的内容複制到使用者空間,所複制的内容是從from來,到to去,複制n個位。
其中又牽扯到兩個函數:access_ok()和__copy_to_user(),好我們繼續往下深入,先來看看第一個函數access_ok()的源碼
85
104#ifdef CONFIG_MMU
105#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0))
106#else
107static inline int access_ok(int type, const void *addr, unsigned long size)
108{
109 extern unsigned long memory_start, memory_end;
110 unsigned long val = (unsigned long)addr;
111
112 return ((val >= memory_start) && ((val + size) < memory_end));
113}
114#endif
其功能是檢查使用者空間是否合法,它的第一個參數:type,有兩種類型:VERIFY_READ 和VERIFY_WRITE,前者為可讀,後者可寫,注意:如果标志為可寫(VERIFY_WRITE)時,必然可讀!因為可寫是可讀的超集(% VERIFY_WRITE is a superset of %VERIFY_READ)。
檢查過程如下:addr為起始位址,size為所要複制的大小,那麼從addr到addr+size則是所要檢查的空間,如果它的範圍在memory_start和memory_end之間的話,則傳回真。到此為止,如果檢查合法,那麼OK,我們來實作真正的複制功能:__copy_to_user(),其源碼定義如下:
80static inline __kernel_size_t __copy_to_user(void __user *to, const void *from,
81 __kernel_size_t n)
82{
83 return __copy_user((void __force *)to, from, n);
84}
__copy_user(),這個函數才真正在做底層的複制工作。
__copy_to_user()就是對__copy_user()的封裝.其實, 在函數:copy_from_user()中,也調用了這個函數。也就是說這個函數實作了核心空間與使用者空間的互相複制。