Arhn - архитектура программирования

Что нужно сделать в ядре Linux, чтобы инициализировать коммутатор L2 Broadcom через PCI-E?

У меня есть специальная плата с SoC Armada 370, в которой коммутатор Broadcom L2 теперь добавляется через PCI-E к SoC.
Плата работает на Linux. Я хочу просто инициализировать регистры коммутатора L2.
Мне просто нужен минимальный доступ, чтобы я мог получить доступ к регистрам коммутатора L2 (используя программу, которая использует /dev/mem — у меня есть приложение).
Am новое, и я хотел бы знать, что нужно сделать в драйверах PCI-E, в menuconfig и т. д.
Я был бы рад, если бы кто-нибудь мог указать на ресурс, который объясняет все это с нуля, потому что я хочу узнать больше. Смогу ли я получить доступ к регистрам, если просто правильно сделаю отображение памяти? Нужно ли мне делать что-то еще?


Ответы:


1

Это должно помочь вам в пути. Он устанавливает BAR0 для доступа. Все, что вам нужно сделать, это выяснить, как вы хотите, чтобы программное обеспечение обращалось к драйверу и реализовать эти обработчики: чтение/запись/открытие/закрытие/ioctl и т. д.

#include <linux/cdev.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/tty.h>
#include <linux/version.h>

void error_msg (const char *msg, ...);  /* provide by calling possibly kprintf() */

static dev_t        dev_num;        /* major/minor device numbers */
static struct cdev  c_dev, pci_dev;     /* character device structure */
static const char   DEVICE_NAME[] = "mydevice"; /* name for /dev/... */

static unsigned long        bar0_len;
static unsigned char __iomem    *bar0_mem;

static struct file_operations mydevice_fops = {
    .owner      = THIS_MODULE,
//  .open       = (function to handle open),
//  .read       = (function to handle read),
//  .write      = (function to handle write),
//  .close      = (function to handle close),
//  .unlocked_ioctl = (function to handle ioctl),
};

static int mydevice_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
    int     ret;
    char        name[20];
    dev_t       unit_num;
    struct device   *dev_p;

    ret = pci_enable_device (dev);
    if (ret)
    {
        error_msg ("error %d enabling device");
        return ret;
    }
    bar0_len = pci_resource_len (dev, 0);
    bar0_mem = pci_iomap (dev, 0, bar0_len);
    if (!bar0_len  ||  !bar0_mem)       /* device not there */
    {
        error_msg ("device bar0 missing");
        return -1;
    }
    snprintf (name, sizeof name, "%s%d", DEVICE_NAME, 1);  /* create device name */
    unit_num = MKDEV(MAJOR(dev_num), 1);
    dev_p = device_create (NULL, NULL, unit_num, NULL, name);
    if (IS_ERR(dev_p))
    {
        error_msg ("error creating pci device %s", name);
        return -1;
    }
    cdev_init (&pci_dev, &mydevice_fops);
    mydevice_fops.owner = THIS_MODULE;
    ret = cdev_add (&pci_dev, unit_num, 1);
    if (ret < 0)
    {
        error_msg ("error adding pci device");
        device_destroy (NULL, unit_num);
        return ret;
    }

    pci_set_master (dev);
    return 0;
}

static void mydevice_pci_remove (struct pci_dev *dev)
{
    cdev_del (&c_dev);
    device_destroy (NULL, dev_num);
    pci_iounmap (dev, bar0_mem);
    pci_disable_device (dev);
}


static struct pci_device_id mydevice_ids[] = {
{
    0xabcd,     /* vendor/manufacturer ID */
    0x1234,     /* device/vendor device ID */
    PCI_ANY_ID, /* subvendor:  don't care */
    PCI_ANY_ID, /* subdevice:  don't care */
    0,      /* class:  don't care */
    0,      /* class_mask:  don't care */
    0,      /* ulong_t driver_data:  private driver data */
    },

    {}      /* end of pci device IDs */
};

static struct pci_driver mydriver_ops = {
    .name       = DEVICE_NAME,
    .id_table   = mydevice_ids,
    .probe      = mydevice_pci_probe,
    .remove     = mydevice_pci_remove,
    /*
     * For pci bus error recovery, see
     * https://www.kernel.org/doc/Documentation/PCI/pcieaer-howto.txt
     */
};

static struct file_operations mydriver_fops = {
    .owner = THIS_MODULE,
};


static int __init mydriver_init (void)
{
    struct device  *mydriver_device;

    int ret = alloc_chrdev_region (&dev_num, 0, 1, DEVICE_NAME);
    if (ret)
    {
        error_msg ("unable to allocate major/minor device number");
        return ret;
    }

    mydriver_device = device_create (NULL, NULL, dev_num, NULL, DEVICE_NAME);
    if (IS_ERR(mydriver_device))
    {
        error_msg ("error creating device");
        unregister_chrdev_region (dev_num, 1);
        return -ENODEV;
    }

    cdev_init (&c_dev, &mydevice_fops);
    c_dev.owner = THIS_MODULE;
    ret = cdev_add (&c_dev, dev_num, 1);
    if (ret < 0)
    {
        error_msg ("error adding device");
        device_destroy (NULL, dev_num);
        unregister_chrdev_region (dev_num, 1);
        return ret;
    }

    ret = pci_register_driver (&mydriver_ops);  // this is key to PCI devices
    if (ret < 0)
    {
        error_msg ("error %d from pci_register_driver", ret);
        cdev_del (&c_dev);
        device_destroy (NULL, dev_num);
        unregister_chrdev_region (dev_num, 1);
        return ret;
    }
    return 0;
}

static void __exit mydriver_exit (void)
{
    device_destroy (NULL, dev_num);
    unregister_chrdev (MAJOR(dev_num), DEVICE_NAME);
    unregister_chrdev_region (dev_num, 1);
}

module_init(mydriver_init);
module_exit(mydriver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your name <[email protected]>");
29.04.2014
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..