Подтвердить что ты не робот

Файловый ввод-вывод в модуле ядра Linux

Я пишу модуль ядра Linux, который должен открывать и читать файлы. Какой лучший способ это сделать?

4b9b3361

Ответ 1

Могу ли я спросить, почему вы пытаетесь открыть файл?

Мне нравится следить за развитием Linux (из любопытства, я не разработчик ядра, я занимаюсь Java), и я уже обсуждал этот вопрос. Я смог найти сообщение LKML об этом, в основном упоминая, что это обычно плохая идея. Я почти уверен, что LWN покрыл его в прошлом году, но мне трудно найти статью.

Если это частный модуль (например, для некоторых настраиваемых аппаратных средств, и модуль не будет распространен), вы можете это сделать, но у меня создается впечатление, что если вы собираетесь отправить свой код на магистраль, он не может быть принят.

Эван Теран упомянул о sysfs, который кажется мне хорошей идеей. Если вам действительно нужно делать более сложные пользовательские материалы, вы всегда можете создавать новые ioctrls.

EDIT:

ОК, я нашел статью, которую я искал, из Linux Journal. Это объясняет, почему делать такие вещи, как правило, плохая идея, а затем продолжает рассказывать вам, как это сделать в любом случае.

Ответ 2

Предполагая, что вы можете получить указатели на relavent указатели на функциональные вызовы 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_*", которые я показал. Я уверен, что есть лучший способ, но я считаю, что это сработает.

Ответ 3

Вообще говоря, если вам нужно читать/записывать файлы из модуля ядра, вы делаете что-то неправильно архитектурно.

Существуют механизмы (например, netlink или просто зарегистрировать устройство символов), чтобы позволить модулю ядра разговаривать с вспомогательным процессом в пользовательском пространстве. Этот вспомогательный процесс userpace может делать все, что он хочет.

Вы также можете реализовать системный вызов (или такой как), чтобы взять файловый дескриптор, открытый в пользовательском пространстве, и прочитать/записать его из ядра.

Это, вероятно, будет более аккуратным, чем попытка открыть файлы в пространстве ядра.

Есть и другие вещи, которые уже открывают файлы из пространства ядра, вы можете посмотреть на них (на мой взгляд, работает драйвер цикла?).

Ответ 6

Все разработчики ядра говорят, что файловый ввод-вывод из пространства ядра плох (особенно если вы ссылаетесь на эти файлы по своим путям), но основное ядро делает это при загрузке прошивки. Если вам просто нужно прочитать файлы, используйте

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 что-то вроде READING_FIRMWARE (без кавычек).

buf не имеет нулевого конца, вместо этого ссылается на его размер по size. Если вам нужно, чтобы он был завершен с нулем, создайте size + 1 строки size + 1 байт в длину и скопируйте его или kernel_read_file() функцию 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 с помощью этой функции, выполнив его.