it-swarm.com.ru

Зачем нужен метод исследования в драйверах устройств Linux в дополнение к init?

В ядре linux, что делает метод probe(), предоставляемый драйвером? Насколько она отличается от функции драйвера init, т. Е. Почему нельзя выполнять действия функции probe() в функции драйвера init?

44
Bandicoot

Различные типы устройств могут иметь функции probe (). Например, оба устройства PCI и USB имеют функции probe ().

Если вы говорите об устройствах PCI, я бы порекомендовал вам прочитать главу 12 Linux Device Drivers , которая описывает эту часть инициализации драйверов. USB рассматривается в главе 13.

Краткий ответ, при условии PCI: функция инициализации драйвера вызывает pci_register_driver(), которая дает ядру список устройств, которые он может обслуживать, вместе с указателем на функцию probe(). Затем ядро ​​вызывает функцию драйвера probe() один раз для каждого устройства.

Эта функция проверки запускает инициализацию для каждого устройства: инициализирует оборудование, выделяет ресурсы и регистрирует устройство в ядре как блочное или сетевое устройство или что бы то ни было.

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

68
Eric Seppanen

@Bandicoot: будет вызываться probe (), чтобы убедиться, что устройство существует и его функциональность нормальная. Если устройство не поддерживает горячее подключение, функциональность probe () можно поместить в метод init (). уменьшить объем памяти во время выполнения драйвера. P.S ссылка

Probe () происходит во время загрузки устройства или когда устройство подключено. Для устройства «платформа» функция датчика вызывается, когда устройство платформы зарегистрировано, и его имя соответствует имени, указанному в драйвере устройства. P.S ссылка

Функция i2c_detect проверяет адаптер I2C, ища разные адреса, указанные в структуре addr_data. Если устройство найдено, вызывается функция chip_detect. P.S ссылка .

Одна ссылка, которая наверняка прояснит ваши сомнения. P.S ссылка

В ядре 2.4.29 я могу показать вам, как происходит зондирование? Пожалуйста, смотрите ниже (Имя файла: drivers/acorn/char/pcf8583.c)

static struct i2c_driver pcf8583_driver = {
name:       "PCF8583",
id:     I2C_DRIVERID_PCF8583,
flags:      I2C_DF_NOTIFY,
attach_adapter: pcf8583_probe, /* This will be called from i2c-core.c P.S see below function i2c_add_driver()*/
detach_client:  pcf8583_detach,
command:    pcf8583_command

};

Имя файла: drivers/i2c/i2c-core.c

int i2c_add_driver(struct i2c_driver *driver)
{
    ........................
    ........................

    /* now look for instances of driver on our adapters
     */
    if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) {
        for (i=0;i<I2C_ADAP_MAX;i++)
            if (adapters[i]!=NULL)
                /* Ignore errors */
                driver->attach_adapter(adapters[i]); /*This is a location from where probe is called. Pointer **driver** is of type **pcf8583_driver** which you have passed into this function*/
    }
    ADAP_UNLOCK();
    return 0;
}

Несколько важных ссылок:

1) http://www.slideshare.net/varunmahajan06/i2c-subsystem-in-linux2624

2) http://www.programering.com/a/MjNwcTMwATM.html

3) http://www.linuxjournal.com/article/6717

4) http://www.developermemo.com/2943157/

5) http://free-electrons.com/doc/kernel-architecture.pdf

6) http://www.techques.com/question/1-3014627/Probe-problem-when-writing-a-I2C-device-driver

В PCI для kernel-2.4.29 он вызывается при идентификации поставщика и идентификатора устройства. Драйвер шины PCI сделает это за вас. Пожалуйста, смотрите ниже код:

Имя файла: drivers/pci/pci.c

static int pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
{
   const struct pci_device_id *id;
   int ret = 0;
   if (drv->id_table) {
    id = pci_match_device(drv->id_table, dev); /* check for device presence*/
    if (!id) {
     ret = 0;
     goto out;
    }
   } else
  id = NULL;
  dev_probe_lock();
  if (drv->probe(dev, id) >= 0) { /* This is a location from where probe is called*/
   dev->driver = drv;
   ret = 1;
   }
   dev_probe_unlock();
  out:
  return ret;
}
9
Manish

Init (void) // запускается один раз, когда вызывается драйвер/модуль, и устанавливает параметры для компьютера с драйвером ядра.

Probe (* pdev) // используется драйвером ядра для обнаружения и установки реальных устройств

8
fbp

Функция драйверов xxx_init_module() вызывает pci_register_driver(struct pci_driver *drv), передавая ссылку на структуру типа pci_driver. struct pci_driver - это важная структура, которую должны иметь все драйверы PCI, которая инициализируется такими переменными, как имя драйвера, список таблиц устройств PCI, которые может поддерживать драйвер, процедуры обратного вызова для базовой подсистемы PCI.

Структура драйверов pci_driver имеет важные поля-члены, перечисленные ниже:

  1. name - Имя драйвера, который является уникальным среди всех драйверов PCI в ядре. Он появится под /sys/bus/pci/drivers.

  2. pci_device_id - Таблица идентификационных данных устройства содержит тип микросхем, поддерживаемых этим драйвером.

  3. probe - адрес функции xxx_probe().

  4. remove/suspend/resume/shutdown - адрес функции, вызываемой базовой системой PCI, когда устройство PCI удаляется/приостанавливается/возобновляется/выключается соответственно. Обычно используется верхними уровнями для управления питанием.

Для получения дополнительной информации о том, как зондирование драйвера выполняется из ядра PCI, обратитесь к Linux Device Driver Init

1
Sunil Bojanapally

Зондирование выполняется, когда метод probe () вызывается указателем функции внутри структуры, которая используется для привязки устройства со стандартными или пользовательскими данными платформы, относящимися к устройству. Драйверы используют много информации об устройстве, так что зондирование предоставляет такую ​​информацию. к драйверам, когда запись в поле id_table name совпадает с именем устройства, будет проверено.

0
Yûvʀʌj Sɩŋʛʜ

Ядро Linux использует аппаратное устройство соответствующий программный драйвер устройства process. init вызывается очень рано и регистрирует в ядре функцию probe и имя аппаратного устройства, например «taiko_sound_card». Это говорит ядру, что «я являюсь драйвером sw для этого устройства с таким именем». Когда ядро ​​проходит через устройства hw (дерево устройств или перечисление шины) и находит совпадение, оно вызывает вашу зарегистрированную функцию probe. Теперь ваш драйвер устройства sw владеет устройством hw.

Если не найдено подходящего устройства, ваш зонд может никогда не позвонить. Вот почему обычно init крошечный и probe выполняет всю инициализацию.

0
Liyong Zhou

Несколько устройств и горячее подключение

  1. Вы работаете на большом сервере со многими ускорителями GPU, подключенными к PICe. В какой-то момент вы решили купить больше графических процессоров для свободных слотов.

    Если бы мы использовали init, то нам пришлось бы rmmod и insmod модуль. Но это потребует остановки всех подключенных графических процессоров, что приведет к простою. 

    С probe мы просто подключаем новые графические процессоры для повторного сканирования.

  2. В противном случае горячее подключение PCIe было бы невозможно: https://electronics.stackexchange.com/questions/208767/does-pcie-hotplug-actually-work-in-practice

Пример устройства PCI QEMU edu

QEMU имеет образовательное PCI-устройство под названием edu, которое позволяет нам легко проверять, когда вызывается probe.

Во-первых, нам нужен минимальный драйвер PCI для ядра Linux, который я здесь написал

Мы можем начать с устройства с:

-device edu

но что еще интереснее, мы можем подключить и удалить устройство из монитора QEMU, Ctrl + Alt + 2 в графическом интерфейсе SDL или -monitor telnet::45454,server,nowait в CLI, с помощью команд:

device_add edu
device_del edu

Если устройство подключено при загрузке:

  • probe вызывается, как только мы insmod модуль

  • dmesg содержит строку типа: pci 0000:00:04: [1234:11e8] ..., которая показывает, что наше устройство было проверено на BDF 0000:00:04.

    Мы знаем, что это наше устройство, потому что поставщик 0x1234 и идентификатор устройства 11e8 в источнике QEMU.

    Таким образом, мы приходим к выводу, что устройства PCI проверяются при загрузке и где-то хранятся в списке.

Если мы подключим устройство после загрузки с монитора:

  • ничего не происходит, пока мы не сделаем:

    echo 1 > /sys/bus/pci/rescan
    

    Смотрите также: Как можно заставить ядро ​​linux перечислять шину PCI-e?

  • после повторного сканирования:

    • если мы уже отправили, probe вызывается немедленно.

      Таким образом, в этом случае probe произошел отдельно от insmod, показывая, как они отличаются. 

    • если у нас нет: probe вызывается сразу после insmod