read and write
The read and write methods perform a similar task, that is, copying data from and to application code. Therefore, their prototypes are pretty similar and it’s worth introducing them at the same time:
ssize_t read(struct file *filp, char *buff,
size_t count, loff_t *offp);
ssize_t write(struct file *filp, const char *buff,
size_t count, loff_t *offp);
For both methods, filp is the file pointer and
count is the size of the requested data
transfer. The buff argument points to the user
buffer holding the data to be written or the empty buffer where the
newly read data should be placed. Finally, offp is
a pointer to a “long offset type” object that indicates the file
position the user is accessing. The return value is a “signed size
type;” its use is discussed later.
As far as data transfer is concerned, the main issue associated with the two device methods is the need to transfer data between the kernel address space and the user address space. The operation cannot be carried out through pointers in the usual way, or through memcpy. User-space addresses cannot be used directly in kernel space, for a number of reasons.
One big difference between kernel-space addresses and user-space addresses is that memory in user-space can be swapped out. When the kernel accesses a user-space pointer, the associated page may not be present in memory, and a page fault is generated. The functions we introduce in this section and in Section 5.1.4 in Chapter 5 use some hidden ...