Let's take a look at the definition of the data structure of each scull_dev:
Struct scull_qset {void ** data; struct scull_qset * next;};
struct scull_dev {struct scull_qset * data; / * Pointer to first quantum set * / int quantum; / * the current quantum size * / int qset; / * the current array size * / unsigned long size; / * amount of data stored here * / Unsigned int access_key; / * buy by sculluid and scullpriv * / struct semaphore sem; / * mutual Exclusion Semaphore * / Struct CDEV CDEV; / * CHAR Device structure * /};
Each scull device has a data pointer, each pointer pointing to the next Scull_Qset data structure. Each memory is a quantum quantum. This pointer is the length of its length, which can be a quantum set Qset. This two values can define the initial value in Scull.h, or the IOCTL function can customize their size in this example. A 1000 pointer (QSET) is defined in the DATA of each scull_qset, and each pointer points to a 4000-byte area (Quantum).
This memory uses the picture on the "Linux driver", which can compare the difference between the third edition and the second edition. The following is the source code for the third version of the program.
We have to read this memory, first pass it to the kernel space is a Loff_T * OFFP pointer to represent the location of the user's read or write operation. First, you can get a message through this OFFP, this Loff_t * OFFP pointer is on which Struct Scull_Qset, see the source code, in SSIZE_T Scull_read (Struct File * Filp, Char __USER * BUF, SIZE_T Count, Loff_t * f_pos):
........................................
/ * Find ListItem, qset index, and offset in the quantum * / item = (long) * f_pos / itemsize; rest = (long) * f_pos% itemsize; s_pos = rest / quantum; Q_POS = REST% quantum;
/ * FOLLOW The list up to the right position (defined elsewhere) * / dptr = scull_follow (dev, item);
Locate the scen_qset where the OFFP pointer is located via the scull_follow () function, and when reading the data, it is read for a certain memory quantum;
Item = (long) * f_pos / itemsize: Which scull_qset is on the list? REST = (long) * f_pos% Itemsize: What is the data offset in this scull_Qset?
S_POS = REST / Quantum: Which quantum is in this scull_qset?
Q_POS = REST% Quantum: How much is the offset in this quantum?
Pointer Loff_t * f_pos successfully positioned!
IF (COPY_TO_USER (BUF, DPTR-> DATA [S_POS] Q_POS, COUNT), the kernel data to the copy of the user space, and then update the offset pointer after success: * f_pos = count.
The next article introduces simple transplantation of Scull source, and provides all source code, Heph, today, here, rest, rest ...