Что делает в ядре Linux метод probe()
, предоставляемый драйвером? Насколько она отличается от функции init
водителя, т.е. почему действия функций probe()
нельзя выполнять в функции init
водителя?
Почему метод probe необходим в драйверах устройств Linux в дополнение к init?
Ответы (7)
Различные типы устройств могут иметь функции probe(). Например, устройства PCI и USB имеют функции probe().
Если вы говорите об устройствах PCI, я бы порекомендовал вам прочитать главу 12 драйверов устройств Linux, которая охватывает эту часть инициализации драйвера. USB рассматривается в главе 13.
Более короткий ответ, предполагая PCI: функция инициализации драйвера вызывает pci_register_driver()
, которая дает ядру список устройств, которые оно может обслуживать, вместе с указателем на функцию probe()
. Затем ядро вызывает функцию probe()
драйвера один раз для каждого устройства.
Эта зондирующая функция запускает инициализацию каждого устройства: инициализирует аппаратное обеспечение, выделяет ресурсы и регистрирует устройство в ядре как блочное или сетевое устройство или что-то еще.
Это облегчает работу драйверов устройств, поскольку им не нужно искать устройства или беспокоиться о том, чтобы найти устройство, которое было подключено в горячем режиме. Ядро обрабатывает эту часть и уведомляет нужный драйвер, когда у него есть устройство для обработки.
@Bandicoot: будет вызываться probe(), чтобы убедиться, что устройство существует и его функциональность в порядке. Если устройство не поддерживает горячее подключение, функциональность probe() можно поместить в метод init(). .Это уменьшит объем памяти, занимаемой драйвером во время работы. P.S ссылка
Зонд () происходит во время загрузки устройства или при подключении устройства. Для «платформенного» устройства функция зонда вызывается, когда устройство платформы зарегистрировано, и его имя устройства совпадает с именем, указанным в драйвере устройства. 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 для ядра-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;
}
.init
, который отбрасывается после загрузки.
- person domen; 22.11.2016
Init(void) // запускается один раз при вызове драйвера/модуля и устанавливает все для машины драйвера ядра.
Probe(*pdev) // используется машиной драйвера ядра по мере необходимости для обнаружения и установки реальных устройств
Функция драйвера xxx_init_module()
вызывает pci_register_driver(struct pci_driver *drv)
, передавая ссылку на структуру типа pci_driver
. struct pci_driver
— это важная структура, которую должны иметь все драйверы PCI, которая инициализируется переменными, такими как имя драйвера, список таблиц PCI-устройств, которые драйвер может поддерживать, процедуры обратного вызова для базовой подсистемы PCI.
Структура драйверов pci_driver содержит важные поля-члены, перечисленные ниже:
name
— Имя драйвера, уникальное среди всех драйверов PCI в ядре. Он появится под/sys/bus/pci/drivers
.pci_device_id
– Таблица идентификационных данных устройства состоит из типов чипов, поддерживаемых данным драйвером.probe
– адрес функцииxxx_probe()
.remove/suspend/resume/shutdown
– адрес функции, которую вызывает система ядра PCI при удалении/приостановке/возобновлении/отключении устройства PCI соответственно. Обычно используется верхними уровнями для управления питанием.
Для получения дополнительной информации о том, как проверка драйвера выполняется из ядра PCI, см. Инициализация драйвера устройства Linux.
Несколько устройств и горячее подключение
Вы используете большой сервер со многими графическими ускорителями, подключенными к PICe. В какой-то момент вы решаете купить больше графических процессоров для бесплатных слотов.
Если бы мы использовали
init
, то нам пришлось быrmmod
иinsmod
модуль. Но для этого потребуется остановить все подключенные графические процессоры, что приведет к простою.С
probe
мы просто подключаем новые графические процессоры и делаем повторное сканирование.В противном случае горячее подключение PCIe было бы невозможно: https://electronics.stackexchange.com/questions/208767/does-pcie-hotplug-actually-work-in-practice
Пример устройства QEMU edu PCI
В 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] ...
, которая показывает, что наше устройство было проверено на BDF0000:00:04
.Мы знаем, что это наше устройство, потому что производитель 0x1234 и идентификатор устройства 11e8 в источнике QEMU.
Таким образом, мы заключаем, что устройства PCI проверяются при загрузке и сохраняются где-то в списке.
Если мы прикрепим устройство после загрузки с монитора:
ничего не произойдет, пока мы не сделаем:
echo 1 > /sys/bus/pci/rescan
См. также: Как может linux принудительно перечислять шину PCI-e?
после повторного сканирования:
если мы уже внедрили мод, немедленно вызывается
probe
.Итак, в данном случае
probe
произошло отдельно отinsmod
, показывая, чем они отличаются.если нет:
probe
вызывается сразу послеinsmod
Ядро Linux использует аппаратное устройство, соответствующее процессу драйвера программного устройства. init
вызывается очень рано и регистрирует в ядре функцию probe
и имя аппаратного устройства, например "taiko_sound_card". Это должно сообщить ядру, что «я являюсь драйвером sw для этого устройства с таким именем». Когда ядро просматривает аппаратные устройства (дерево устройств или перечисление шины) и находит совпадение, оно вызывает вашу зарегистрированную функцию probe
. Теперь ваш программный драйвер устройства владеет аппаратным устройством.
Если подходящее устройство не будет найдено, ваш зонд может никогда не получить вызов. Вот почему обычно init
крошечный, а probe
выполняет всю работу по инициализации.
Зондирование выполняется, когда метод probe() вызывается указателем функции внутри структуры, которая используется для привязки устройства к стандартным или пользовательским данным платформы относительно устройства. В драйверах используется много информации об устройстве, так что проверка предоставляет такую информацию драйверам, когда запись в поле имени id_table соответствует имени устройства.