Функция scull_read_p_mem используется для создания записи процедуры здесь с использованием create_proc_read_entry функции.5-минутный поиск в Google дал этой странице , которая объясняет параметры в указателе функции, переданной функции create_proc_read_entry
.С фиксированным форматированием это:
Аргументы:
* buf: Ядро выделяет страницу памяти любому процессу, который пытается прочитать запись процесса.Указатель страницы указывает на тот буфер памяти, в который записываются данные.
** start: этот указатель используется, когда чтение файла proc должно начинаться не с начала файла, а с определенного смещения.Для небольших операций чтения обычно устанавливается значение NULL.
off: смещение от начала файла, в котором указатель файла в данный момент указывает на
count: число байтов данных, которые нужно прочитать
data:данные, переданные из вызова функции create_read_proc_entry.
eof: установлено в 1, чтобы указать конец файла
Но через некоторое время я также нашел несколько документов в kenel fs / proc/generic.c.Это немного долго, но я думаю, что это единственный источник для суммирования параметра start
:
/*
* How to be a proc read function
* ------------------------------
* Prototype:
* int f(char *buffer, char **start, off_t offset,
* int count, int *peof, void *dat)
*
* Assume that the buffer is "count" bytes in size.
*
* If you know you have supplied all the data you
* have, set *peof.
*
* You have three ways to return data:
* 0) Leave *start = NULL. (This is the default.)
* Put the data of the requested offset at that
* offset within the buffer. Return the number (n)
* of bytes there are from the beginning of the
* buffer up to the last byte of data. If the
* number of supplied bytes (= n - offset) is
* greater than zero and you didn't signal eof
* and the reader is prepared to take more data
* you will be called again with the requested
* offset advanced by the number of bytes
* absorbed. This interface is useful for files
* no larger than the buffer.
* 1) Set *start = an unsigned long value less than
* the buffer address but greater than zero.
* Put the data of the requested offset at the
* beginning of the buffer. Return the number of
* bytes of data placed there. If this number is
* greater than zero and you didn't signal eof
* and the reader is prepared to take more data
* you will be called again with the requested
* offset advanced by *start. This interface is
* useful when you have a large file consisting
* of a series of blocks which you want to count
* and return as wholes.
* (Hack by Paul.Russell@rustcorp.com.au)
* 2) Set *start = an address within the buffer.
* Put the data of the requested offset at *start.
* Return the number of bytes of data placed there.
* If this number is greater than zero and you
* didn't signal eof and the reader is prepared to
* take more data you will be called again with the
* requested offset advanced by the number of bytes
* absorbed.
*/
Мы можем увидеть start
, использованного позже внутри copy_to_user
-Этот параметр используется для оптимизации чтения записей proc
в файлах biiiig.Пользователь может передать очень небольшую переменную count
, но у вас есть файл biig для чтения.Таким образом, вы возвращаете размер этого файла из функции чтения proc с параметром *start
, который говорит, сколько байтов нужно прочитать.Таким образом, ядро может даже передавать count=0
, но функция proc_read может возвращать как 5000
с действительным адресом *start
, позже она будет использоваться в вызове copy_to_user
для ускорения чтения.
Итак:
что означают параметры в static int scull_read_p_mem (char * buf, char ** start, off_t offset, int count, int * eof, void * data)?
buf
- целевой буфер для копирования результата в start
- магический указатель, описанный в комментарии выше, используется для ускорения чтения процесса. offset
- смещение в файле для чтения с count
- количество байтов для чтения eof
- указатель на int, который должен быть установлен на ненулевое значение, в случаевесь файл читается data
- пользовательский контекст, переданный в качестве последнего параметра в функции create_proc_entry
.
У меня есть ряд вопросовотносительно самой реализации (которую можно найти ниже):
scullp_proc_offset
манипулирует выключениями len
et внутри buf
буфера.Если offset != 0
, тогда scull_read_p_mem
не нужно читать с первого байта, а должен содержать некоторый байт offset
.Поскольку он написан лениво, то вызовы snprintf
выполняются в любом случае, вам нужно «сдвинуть» буфер.
what does this function do?
- На самом деле я вижу забавный способ подсчитать, сколько байтов было / нужно скопировать пользователю.
what is the purpose of this?
- Понятия не имею.Выглядит глючно, так как *offset
станет отрицательным.Комментарий над функцией /* FIXME this should use seq_file */
говорит, что что-то осталось исправить.Я думаю, что иды возвращают точно информацию об одном scull_p_devices[i]
в одном вызове.
why do you need to change "start"?
- что приходит к этому.Если *offset
отличается от 0 и если у нас есть несколько байтов для чтения, мы должны вернуть указатель на buf + offset
, чтобы сообщить ядру, откуда читать.Обратите внимание, что *start = buf
уже инициализирован, поэтому ядро будет делать copy_to_user(... *start, len)
.