Файловый ввод-вывод в модуле ядра Linux
-
07-07-2019 - |
Вопрос
Я пишу модуль ядра Linux, который должен открывать и читать файлы.Какой лучший способ добиться этого?
Решение
Могу я спросить, почему вы пытаетесь открыть файл?
Мне нравится следить за разработкой Linux (из любопытства я не разработчик ядра, я занимаюсь Java), и я уже видел обсуждение этого вопроса раньше.мне удалось найти LKML-сообщение по этому поводу вообще упоминать об этом обычно плохая идея.Я почти уверен, что LWN освещал эту тему в прошлом году, но мне трудно найти эту статью.
Если это частный модуль (например, для какого-то специального оборудования, и модуль не будет распространяться), вы можете это сделать, но у меня сложилось впечатление, что если вы собираетесь отправить свой код в основную ветку, это может быть не так. быть принятым.
Эван Теран упомянул sysfs, что мне кажется хорошей идеей.Если вам действительно нужно сделать что-то более сложное, вы всегда можете создать новые ioctrls.
РЕДАКТИРОВАТЬ:
Хорошо, я нашел статью, которую искал, она из Linux-журнал.Он объясняет, почему делать подобные вещи обычно является плохой идеей, а затем рассказывает, как именно это сделать.
Другие советы
предполагая, что вы можете получить указатели на указатели соответствующих функций на системные вызовы open
/ read
/ close
, вы можете сделать что-то вроде этого
mm_segment_t fs = get_fs();
set_fs(KERNEL_DS);
fd = (*syscall_open)(file, flags, mode);
if(fd != -1) {
(*syscall_read)(fd, buf, size);
(*syscall_close)(fd);
}
set_fs(fs);
вам нужно будет создать " syscall _ *
" Функциональные указатели я показал, хотя. Я уверен, что есть лучший способ, но я верю, что это сработает.
Вообще говоря, если вам нужно читать / записывать файлы из модуля ядра, вы архитектурно что-то делаете неправильно.
Существуют механизмы (например, netlink - или просто регистрация символьного устройства), позволяющие модулю ядра взаимодействовать с вспомогательным процессом в пользовательском пространстве. Этот вспомогательный процесс в пространстве пользователя может делать все, что захочет.
Вы также можете реализовать системный вызов (или что-то подобное), чтобы взять файловый дескриптор, открытый в пользовательском пространстве, и прочитать / записать его из ядра. Р>
Это, вероятно, было бы лучше, чем пытаться открывать файлы в пространстве ядра. Р>
Есть некоторые другие вещи, которые уже открывают файлы из пространства ядра, вы можете посмотреть на них (на ум приходит драйвер цикла?).
Вы также можете найти некоторую информацию о sys_call_open в этом модуле ядра Linux. Руководство по программированию .
/ proc также хороша для частного использования и проста.
http://www.linuxtopia.org/online_books/Linux_Kernel_M3.Gogram_Module. > р>
Все разработчики ядра говорят, что файловый ввод-вывод из пространства ядра — это плохо (особенно, если вы ссылаетесь на эти файлы по их путям), но основное ядро делает это при загрузке прошивки.Если вам просто нужно прочитать файлы, используйте команду
kernel_read_file_from_path(const char *path, void **buf, loff_t *size, loff_t max_size, enum kernel_read_file_id id)
функция, которую использует код загрузчика прошивки, объявленная в include/linux/fs.h
.Эта функция возвращает отрицательное значение в случае ошибки.
Я не совсем уверен в сути id
переменная в конце, если вы посмотрите на код, он на самом деле не используется, поэтому просто поместите что-то вроде READING_FIRMWARE
там (без кавычек).
buf
не завершается нулем, вместо этого обратитесь к его размеру в size
.Если вам нужно, чтобы оно заканчивалось нулем, создайте строку size + 1
байт и скопируйте его или перепишите kernel_read_file()
функция (используется kernel_read_file_from_path()
, определенный в fs/exec.c
) и добавьте один к i_size
где выделяется память.(Если вы хотите это сделать, вы можете переопределить kernel_read_file()
функцию в вашем модуле с другим именем функции, чтобы избежать изменения всего ядра.)
Если вам нужно писать в файлы, есть kernel_write()
функция (аналог kernel_read()
, который используется kernel_read_file()
и, следовательно, также kernel_read_file_from_path()
), но нет kernel_write_file()
или kernel_write_file_from_path()
функция.Вы можете посмотреть код в fs/exec.c
файл в дереве исходного кода ядра Linux, где kernel_read_file()
и kernel_read_file_from_path()
определены, чтобы написать свой собственный kernel_write_file()
и kernel_write_file_from_path()
функции, которые вы можете включить в свой модуль.
И, как всегда, вы можете сохранить содержимое файла в указателе char вместо указателя void с помощью этой функции, приведя ее.