835 /**
836 * copy_to_user: - Copy a block of data into user space.
837 * @to: Destination address, in user space.
838 * @from: Source address, in kernel space.
839 * @n: Number of bytes to copy.
840 *
841 * Context: User context only. This function may sleep.
842 *
843 * Copy data from kernel space to user space.
844 *
845 * Returns number of bytes that could not be copied.
846 * On success, this will be zero.
847 */
848 unsignedlong
849 copy_to_user(void __user *to,constvoid*from,unsignedlong n)
850 {
851 if(access_ok(VERIFY_WRITE, to, n))
852 n = __copy_to_user(to, from, n);
853 return n;
854 }
85/**
86 * access_ok: - Checks if a user space pointer is valid
87 * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that
88 * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
89 * to write to a block, it is always safe to read from it.
90 * @addr: User space pointer to start of block to check
91 * @size: Size of block to check
92 *
93 * Context: User context only. This function may sleep.
94 *
95 * Checks if a pointer to a block of memory in user space is valid.
96 *
97 * Returns true (nonzero) if the memory block may be valid, false (zero)
98 * if it is definitely invalid.
99 *
100 * Note that, depending on architecture, this function probably just
101 * checks that the pointer is in the user space range - after calling
102 * this function, memory access functions may still return -EFAULT.
103 */
104#ifdef CONFIG_MMU
105#define access_ok(type,addr,size)(likely(__range_ok(addr,size)== 0))
106#else
107static inlineint access_ok(int type,constvoid*addr,unsignedlong size)
108{
109 externunsignedlong memory_start, memory_end;
110 unsignedlong val =(unsignedlong)addr;
111
112 return((val >= memory_start)&&((val + size)< memory_end));
113}
114#endif/* CONFIG_MMU */
其功能是检查用户空间是否合法,它的第一个参数:type,有两种类型:VERIFY_READ
和VERIFY_WRITE,前者为可读,后者可写,注意:如果标志为可写(VERIFY_WRITE)时,必然可读!因为可写是可读的超集(%
VERIFY_WRITE is a superset of %VERIFY_READ)。 检查过程如下:addr为起始地址,size为所要复制的大小,那么从addr到addr+size则是所要检查的空间,如果它的范围在memory_start和memory_end之间的话,则返回真。至于memory_start详细信息,我没有读。 到此为止,如果检查合法,那么OK,我们来实现真正的复制功能:__copy_to_user(),其源码定义如下: