Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с созданием символьного драйвера.
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
novartis
Добрый день, разбираюсь с драйвером под линукс для pcie устройства.

module_init, module_exit, probe - это реализовал и это работает.
Теперь хочу из программы пользователя писать в бары платы.
Стал описывать символьный драйвер, все вроде так же как у людей сделал, а в папке /dev/ мой девайс не добавляется.
Вот выдержки из кода:

функция инициализации, создания символьного драйвера:
Код
#define AG_DEF_DRIVER_NAME "ag_pcie_driver"
#define AG_DEF_BAR_NUM 6

struct ag_bookkeep {
    struct pci_dev *pci_dev;
    
    void * __iomem bar[AG_DEF_BAR_NUM];
    size_t bar_length[AG_DEF_BAR_NUM];
    
    dev_t cdevno;
    struct cdev cdev;
};

static int __init init_chrdev (struct ag_bookkeep *bk_ptr)
{
    int dev_minor = 0;
    int dev_major = 0;
    dev_t devno;

    int result = alloc_chrdev_region(&bk_ptr->cdevno, dev_minor, 1, AG_DEF_DRIVER_NAME);

    dev_major = MAJOR(bk_ptr->cdevno);
    if (result < 0)
    {
        printk(KERN_INFO "[ag_pcie_driver]:[init_chrdev]: cannot get major ID %d", dev_major);
    }
    else
        printk(KERN_INFO "[ag_pcie_driver]:[init_chrdev]: major ID %d", dev_major);

    devno = MKDEV(dev_major, dev_minor);

    cdev_init(&bk_ptr->cdev, &ag_user_fops);
    bk_ptr->cdev.owner = THIS_MODULE;
    bk_ptr->cdev.ops = &ag_user_fops;
    result = cdev_add(&bk_ptr->cdev, devno, 1);

    if (result)
    {
        printk(KERN_INFO "[ag_pcie_driver]:[init_chrdev]: cdev_add() fail");
        return -1;
    }
    printk(KERN_INFO "[ag_pcie_driver]:[init_chrdev]: cdev_add() success");
    return 0;
}


Эта функция вызывается в probe:

Код
static int ag_pciedr_probe( struct pci_dev *dev, const struct pci_device_id *id )
{
    int res;
    
    struct ag_bookkeep *bk_ptr = NULL;
    bk_ptr = kzalloc(sizeof(struct ag_bookkeep), GFP_KERNEL);
    if(!bk_ptr)
    {
        printk( KERN_INFO "[ag_pcie_driver]:[ag_pciedr_probe]: kzalloc() failed\n");
        return 0;
    }
        
    bk_ptr->pci_dev = dev;
    pci_set_drvdata(dev, bk_ptr);    //зачем это????
    
    // инициализация символьного драйвера
    
    res = init_chrdev(bk_ptr);
    if (res)
    {
        kfree(bk_ptr);
        printk( KERN_INFO "[ag_pcie_driver]:[ag_pciedr_probe]: init_chrdev() failed\n");
        return 0;
    }
    else
        printk( KERN_INFO "[ag_pcie_driver]:[ag_pciedr_probe]: init_chrdev() success\n");
.........


При загрузке модуля dmesg выдает, что
[ag_pcie_driver]:[init_chrdev]: major ID 245
[ag_pcie_driver]:[init_chrdev]: cdev_add() success
[ag_pcie_driver]:[ag_pciedr_probe]: init_chrdev() success

То есть мажор найден, cdev_add сработал.
Но когда смотрю в папку /dev/ там не вижу свой девайс.
В /proc/devices тоже его нет, а в /proc/modules мой модуль есть.

Что я сделал не так?

Прикрепил полные исходники
Нажмите для просмотра прикрепленного файла
Tarbal
Ваш драйвер сам там не появится. Он появится в /sys. Если pci, то в /sys/bus/pci; pci_express, то /sys/bus/pci_express/.
Для pci_express смотрите в /sys/bus/pci_express/drivers.

Если он есть там, то есть два способа добавить пайп к вашему драйверу в /dev:
1. Легкий и устаревший -- команда mknod
2. Правильный и непростой для начинаящего -- написать rule для udev.

Ключевые слова я вам дал, а детали легко найдете в гугле.


des333
Лучше начать с использования miscdevice -- это упрощенный вариант char device

Вот тут неплохой пример.

Самое важное на второй (туда идёт ссылка) и на третьей страницах -- раздел Hello, World! Using /dev/hello_world
doom13
Приветствую.
Не знаю, полезно будет или нет, есть такая штука LinK+ IDE, мне, как новичку в данном вопросе, очень даже понравилась. В начале пытался компилить из консоли, а исходники редактировать в текстовом редакторе, но как-то оно неудобно очень получается. Тут и шаблон драйвера сразу создаётся, куда только добавляем всё необходимое, и компилятор автоматом подтягивается.

Сам пока пользуюсь этим методом:
Цитата(Tarbal @ Nov 18 2015, 16:56) *
1. Легкий и устаревший -- команда mknod

, начинал эксперименты с изучения данной статьи , где он и описан.
Tarbal
Цитата(doom13 @ Nov 18 2015, 22:17) *
Приветствую.
Не знаю, полезно будет или нет, есть такая штука LinK+ IDE, мне, как новичку в данном вопросе, очень даже понравилась. В начале пытался компилить из консоли, а исходники редактировать в текстовом редакторе, но как-то оно неудобно очень получается. Тут и шаблон драйвера сразу создаётся, куда только добавляем всё необходимое, и компилятор автоматом подтягивается.

Сам пока пользуюсь этим методом:

, начинал эксперименты с изучения данной статьи , где он и описан.


Так в 2006 других способов и не было насколько мне известно. Ну mknod до сих пор имеется в наличии, только методы более удобными стали.
novartis
Я для своего драйвера брал за основу драйвер от альтеры (не помню откуда скачал, архив называется G2x4_avmm_dma_Linux). Порылся в нем и нашел там скрипт altera_dma_load, там как раз используется mknod:
Код
#!/bin/sh
module="altera_dma"
device="altera_dma"
mode="666"

# load the module
/sbin/insmod ./$module.ko $* || exit 1

# remove stale nodes
rm -f /dev/$device

# create new device node
major=`grep -w $module /proc/devices | cut -f1 -d" "`
mknod /dev/$device c $major 0

# change permissions to allow all users to read/write
chmod $mode /dev/$device

# make user program
rm -f ./user/user
gcc ./user/user.c -o ./user/user


Я его сначала и не приметил. Применил этот скрипт и в /dev/ отобразился мой девайс. Только как-то это все равно глючно получилось. Иногда в /proc/devices повисали 1 или 2 или больше моих девайсов, долго понять не мог, как их оттуда убить. Потом научился их оттуда удалять несколькими insmod/rmmod. Воощем, как-то криво у меня получилось с alloc_chrdev_region, cdev_init и тп.

Быстренько переделал под miscdevices.
Реально быстро и просто все получилось. В примере, что des333 дал, написано:
Create the "hello" device in the /sys/class/misc directory.
Udev will automatically create the /dev/hello device using
the default rules.
Действительно, девайс автоматом добавился в /dev/. Никаких мажоров вычислять не надо. И удаляется девайс тоже нормально.
Вообщем пока решил остановиться на miscdevices.

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.