Implementation file in / proc Lane

All using / proc module should include <linux / proc_fs.h> to define the correct function.

 

To create a read-only / proc file, your driver must implement a function to generate data when the file is read. When a process reads a file (using the read system call), the request by this function module you arrive. We take a look at this function and discuss the registration interface later in this chapter.

 

When you read a process / proc file, the kernel allocates a page of memory (that is, PAGE_SIZE bytes), the drive can write data back to the user space buffer to pass that your function is called read_proc Methods:

 

int (*read_proc)(char *page, char **start, off_t offset, int count, int *eof, void *data);

 

page pointer you write buffer your data; start this function is used for data related to write in the page where (more on this below);. offset and count have the same meaning for the read method eof argument points to a integer, must be set by the driver to indicate that no more data return, data is specific data pointer drive, you can be used for internal purposes.

 

This function returns the number of bytes actually be placed in the page buffer data, as made by the same method to read another file. Other output values ​​are * eof and * start. Eof is a simple flag, but a start value some use complex; its purpose is to help achieve a large (more than one) / proc file.

 

Some non-traditional start parameter usage. Its purpose is to indicate where (which page) to find data returned to the user. When calling your proc_read method, * start will be NULL. If you keep it to NULL, the kernel assumes that the data has put page offset is 0; in other words, it assumes a simple-minded proc_read version, which placed the entire contents of the virtual file to the page, do not pay attention to offset parameter If, instead, you * start to set a non-NULL value. the kernel believe the data pointed to by the * start considering the offset, and ready to return directly to the user. in general, the method returns a simple proc_read small amount of data just ignore start. more sophisticated methods set

* Start page and only starts to be placed offset from where the requested data.

 

Still some distance to another major problem / proc files, it also intends to answer start. Sometimes ASCII representation of kernel data structures change continuously read call, so the reading process may be found from a call to the next data inconsistency If * start is set to a small integer value, it is incremented by the caller filp- <f_pos amount of data does not depend on your return, so that the internal number into a f_pos record your read_proc process. If, for example, if you the read_proc function returns information from a large array of structures and the first call returns a structure 5, * start can be set to 5. as a call provides the same offset number; know sixth driving structure returned from the array it was admitted its author a "hack", can / generic.c seen in fs / proc.

 

Note that there is a better way to achieve large / proc file; it is called seq_file, we will soon discuss it first, however, it is the time for example the following is a simple (somewhat ugly) read_proc realized for. scull device:

 

 

67

 

 

 

int scull_read_procmem(char *buf, char **start, off_t offset, int count, int *eof, void *data)

{

int i, j, len = 0;

int limit = count - 80; /* Don't print more than this */

 

for (i = 0; i < scull_nr_devs && len <= limit; i++) { struct scull_dev *d = &scull_devices[i];

struct scull_qset *qs = d->data; if (down_interruptible(&d->sem))

return -ERESTARTSYS;

len += sprintf(buf+len,"\nDevice %i: qset %i, q %i, sz %li\n", i, d->qset, d->quantum, d->size); for (; qs && len <= limit; qs = qs->next) { /* scan the list */

len += sprintf(buf + len, " item at %p, qset at %p\n", qs, qs->data); if (qs->data && !qs->next) /* dump only the last item */

for (j = 0; j < d->qset; j++) {

if (qs->data[j])

len += sprintf(buf + len, " % 4i: %8p\n", j, qs->data[j]);

}

}

up(&scull_devices[i].sem);

 

}

*eof = 1; return len;

 

}

 

This is a fairly typical read_proc implementation. It assumes that there will be no need to produce more than one data and therefore ignores the start and offset values. It is, however, careful not to cover its cache, just in case.

Guess you like

Origin www.cnblogs.com/fanweisheng/p/11106368.html