#c #linux #linux-kernel #filesystems #ioctl
Вопрос:
Я хочу добавить настраиваемую операцию файловой системы для ramfs ядра ioctl
(т. Е. unlocked_ioctl
in struct file_operations
). Что я сделал, так это скопировал код ramfs, переименовал .name
в «myramfs», добавил функцию монтирования в .mount
of struct file_system_type
. Таким образом, я мог бы смонтировать «myramfs» в каталоге. Затем я создал функцию ioctl unlocked_ioctl
, и в основном эта функция теперь предназначена только для тестирования и выполнения простого переключения…case и printk. Я определил две команды ioctl с помощью _IO
. Я уверен, что функциональные возможности «myramfs» без ioctl работают должным образом.
Вот несколько фрагментов кода:
myramfs.c (код модуля ramfs)
#include "myioctl.h"
// Only for testing purpose
static long myramfs_unlocked_ioctl(struct file *f,
unsigned int cmd,
unsigned long arg)
{
switch (cmd) {
case IOCTL_NUM1:
printk(KERN_INFO "Call by IOCTL_NUM1n");
break;
case IOCTL_NUM2:
printk(KERN_INFO "Call by IOCTL_NUM2n");
break;
default:
printk(KERN_INFO "Call by Defaultn");
break;
}
return 0;
}
const struct file_operations ramfs_file_operations = {
...
.unlocked_ioctl = myramfs_unlocked_ioctl,
};
myioctl.h (самостоятельный файл заголовка ioctl)
#include <linux/ioctl.h>
#define IOC_CODE '1'
#define IOC_NO(x) (IOC_CODE (x))
#define MY_IOC(n) _IO(IOC_CODE, IOC_NO(n))
#define IOCTL_NUM1 MY_IOC(1)
#define IOCTL_NUM2 MY_IOC(2)
Я написал программу для тестирования драйвера C в пространстве пользователя, чтобы вызвать ioctl «myramfs».:
test.c (программа драйвера пользовательского пространства для вызова ioctl и надежды получить информацию о печати в dmesg)
#include <sys/ioctl.h>
#include "myioctl.h"
...
int dirfd;
//mp is the pathname of myramfs mountpoint
dirfd = open(mp, O_RDONLY | __O_DIRECTORY);
if (dirfd < 0) {
exit(1);
}
int ret;
ret = ioctl(dirfd, VERIFS_CHECKPOINT, (void *)arg); // Got ENOTTY in this statement
Когда я позвонил ioctl
в пространство пользователя, я получил errno = 25 (ENOTTY), что означает неподходящий ioctl для устройства. Я подозреваю, что это связано с тем, что я использовал точку монтирования fd в качестве первого аргумента пользовательского пространства ioctl
вместо устройства fd. Но ramfs не нуждается в поддержке устройством, поэтому я не могу использовать device fd в качестве аргумента ioctl. Я не уверен, в чем проблема и правильно ли я реализовал ioctl для ramfs. Не могли бы вы, пожалуйста, помочь с этой ошибкой NOTTY в программе пользовательского драйвера? Спасибо вам за вашу помощь!
Комментарии:
1. Вы добавляете метод
unlocked_ioctl
в структуруramfs_file_operations
, который, согласно его названию, предназначен только для обычных файлов . Но вы, пользовательская космическая программа, пытаетесь работать с каталогом .2. На вашем устройстве есть основной и второстепенный номера. Вам нужно создать узел устройства и открыть его, чтобы иметь файловый дескриптор, который сопоставляется с вашим устройством.
3. @Tsyvarev Большое тебе спасибо. Я попытался создать файл в точке монтирования myramfs, затем получить этот файл
fd
open
и ввести его вioctl
качестве аргумента. Теперь это работает, и я могу получить ожидаемый вывод ядра. Интересно, нужно ли мне создавать файл, прежде чем делатьioctl
это в пользовательском пространстве. Могу ли я запроситьioctl
чистую файловую систему без какого-либо обычного файла в ней?4. @старк, Спасибо. Похоже, что ramfs не требует устройства при монтаже, и я не знаю, как сопоставить устройство для ramfs. Есть идеи?
5. Вы также можете добавить ioctl для каталогов. Вместо назначения
amp;simple_dir_operations
создать свои собственные файловые операции для каталога и добавитьunlocked_ioctl
в него.