Как установить режим для символьного устройства в модуле ядра Linux? - PullRequest
1 голос
/ 15 апреля 2020

Я создаю модуль устройства персонажа, который играет в игру Ti c -ta c -toe. Я пытаюсь запрограммировать его, чтобы он устанавливал режим /dev/ticactoe на 666, вместо того, чтобы пользователь использовал команду chmod.

My main.c содержит следующее с реализациями tictactoe s init и exit (отредактировано для краткости):

static dev_t device_number;
static struct cdev our_cdev;
static struct class* my_class = NULL;

static struct file_operations fops = {
.owner = THIS_MODULE,
.read = tictactoe_read,
.write = tictactoe_write,
.open = tictactoe_open,
.release = tictactoe_release,
};

У меня есть tictactoe.h, содержащий следующее:

#define MODULE_NAME "tictactoe"

int tictactoe_open(struct inode *pinode, struct file *pfile);
ssize_t tictactoe_read(struct file *pfile, char __user *buffer, size_t length, loff_t *offset);
ssize_t tictactoe_write(struct file *pfile, const char __user *buffer, size_t length, loff_t *offset);
int tictactoe_release(struct inode *pinode, struct file *pfile);

Я читал о umode_t , но я не уверен, как я мог бы использовать это для этого модуля. Кто-нибудь может привести меня в правильном направлении или объяснить, как реализовать переменную umode_t? Любая помощь приветствуется.

1 Ответ

1 голос
/ 15 апреля 2020

Исходный код ядра для /dev/{null,zero,...} является хорошим местом для поиска такого рода вещей, когда вы сомневаетесь, посмотрите, как это реализовано в drivers/char/mem.c.

После того, как вы создали класс my_class для своего устройства, вы должны установить в поле ->devnode функцию для установки желаемого режима. Вы можете найти режимы в заголовке <linux/stat.h>, установка на 666 означает rw-rw-rw-, то есть S_IRUGO|S_IWUGO. Хорошая идея сделать эту константу где-нибудь в коде.

Вот решение:

#define DEV_CLASS_MODE ((umode_t)(S_IRUGO|S_IWUGO))

static char *my_class_devnode(struct device *dev, umode_t *mode)
{
    if (mode != NULL)
        *mode = DEV_CLASS_MODE;
    return NULL;
}

Тогда в вашем модуле init функция:

my_class = class_create(THIS_MODULE, "tictactoe");
if (IS_ERR(my_class)) {
    // Abort...
}

my_class->devnode = my_class_devnode;

О, и, кстати, вам не нужно #define MODULE_NAME, оно уже определено автоматически и KBUILD_MODNAME.

...