Драйвер шины что делает

До сих пор мы видели немало низкоуровневой инфраструктуры и относительно мало примеров. Мы постараемся компенсировать это в оставшейся части этой главы, как только мы перейдём на более высокие уровни модели устройства Linux. С этой целью мы вводим новую виртуальную шину, которую мы называем lddbus (* Логичным именем для этой шины, конечно, было бы «sbus», но это название уже было взято настоящей, физической шиной.) , и изменяем драйвер scullp для «подключения» к этой шине. Ещё раз, большая часть прочитанного здесь никогда не потребуется многим авторам драйверов. Подробности этого уровня, как правило, обрабатываются на уровне шины, и небольшому числу авторов потребуется добавить новый тип шины. Однако, эта информация является полезной для тех, кому интересно, что происходит внутри PCI, USB и других уровнях или кому требуется сделать изменения на этом уровне.

Шина является каналом между процессором и одним или несколькими устройствами. Для целей модели устройства, все устройства подключаются через шину, даже если она является внутренней, виртуальной, «инструментальной» шиной. Шины могут подключаться друг в друга — контроллер USB, к примеру, обычно представляет собой PCI устройство. Модель устройства отражает фактические связи между шинами и устройствами, которыми они управляют.

В модели устройства Linux шина представлена структурой bus_type , определённой в
. Эта структура выглядит следующим образом:

int (*match)(struct device *dev, struct device_driver *drv);

struct device *(*add)(struct device * parent, char * bus_id);

int (*hotplug) (struct device *dev, char **envp,

int num_envp, char *buffer, int buffer_size);

Поля name является именем этой шины, что-нибудь такое, как pci. Вы можете видеть из структуры, что каждая шина имеет собственную подсистему; однако, эти подсистемы не живут на верхнем уровне в sysfs. Вместо этого, они находятся под шинной подсистемой. Шина содержит два kset-а, представляющих известные драйверы для этой шины и все устройства, подключенные к шине. Затем существует набор методов, которые мы получим в ближайшее время.

Регистрация шины

Как мы уже отмечали, исходник примера включает реализацию виртуальной шины под названием lddbus . Эта шина создаёт свою структуру bus_type следующим образом:

struct bus_type ldd_bus_type = bus_id, driver->name, strlen(driver->name));

Когда речь идёт о реальном оборудовании, функция match обычно делает какое-то сравнение между идентификационным номером оборудования, предоставляемым самим устройством, и идентификаторами, поддерживаемыми драйвером.

Читайте также: Резина рейтинг летних шин r16

Метод горячего подключения в lddbus выглядит следующим образом:

static int ldd_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)

if (snprintf(buffer, buffer_size, «LDDBUS_VERSION=%s»,

Здесь мы добавляем в него номер текущей версии исходного кода lddbus , на случай, если кто-нибудь полюбопытствует.

Перебор устройств и драйверов

Если вы пишете код шинного уровня, вам может потребоваться выполнять некоторые операции со всеми устройствами или драйверами, которые были зарегистрированы на вашей шине. Может быть заманчиво копаться непосредственно в структурах в структуре bus_type , но лучше использовать предоставленные вспомогательные функции.

Для работы с каждым устройством, известном шине, используйте:

int bus_for_each_dev(struct bus_type *bus, struct device *start,

void *data, int (*fn)(struct device *, void *));

Эта функция перебирает все устройства на шине, передавая связанную структуру device в fn , вместе со значением, передаваемым как data . Если start является NULL, итерация начинается с первого устройства на шине; в противном случае итерация начинается с первого устройства после start . Если fn возвращает ненулевое значение, итерация останавливается и такое значение является возвращённым из bus_for_each_dev .

Существует аналогичная функция для перебора драйверов:

int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,

void *data, int (*fn)(struct device_driver *, void *));

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

Следует отметить, что обе эти функции в течение работы удерживают шинный семафор подсистемы чтения/записи. Так что попытка использовать их обе вместе приведёт к взаимоблокировке, каждая будет пытаться получить один и тот же семафор. Операции, которые изменяют шину (такие, как отмена регистрации устройств), также будут блокироваться. Таким образом, используйте функцию bus_for_each с некоторой осторожностью.

Атрибуты шины

Почти каждый слой в модели устройства Linux предоставляет интерфейс для добавления атрибутов и уровень шины не является исключением. Тип bus_attribute определён в
следующим образом:

ssize_t (*show)(struct bus_type *bus, char *buf);

ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);

Мы уже видели struct attribute в разделе «Атрибуты по умолчанию». Тип bus_attribute также включает в себя два метода для отображения и установки значения атрибута. Большинство уровней модели устройства над уровнем kobject-а работают таким образом. Для создания во время компиляции и инициализации структуры bus_attribute был предусмотрен удобный макрос:

BUS_ATTR(name, mode, show, store);

Этот макрос декларирует структуру, создавая её название, предваряя заданное name строкой bus_attr_ .

Любые атрибуты, принадлежащие шине, должны быть созданы явно с помощью bus_create_file :

int bus_create_file(struct bus_type *bus, struct bus_attribute *attr);

Атрибуты также могут быть удалены с помощью:

void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr);

Драйвер lddbus создаёт простой файл атрибута, опять же содержащий номер версии исходника. Метод show и структура bus_attribute создаются следующим образом:

static ssize_t show_bus_version(struct bus_type *bus, char *buf)

return snprintf(buf, PAGE_SIZE, «%s\n», Version);

static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);

Создание атрибутного файла производится на время загрузки модуля:

if (bus_create_file(&ldd_bus_type, &bus_attr_version))

printk(KERN_NOTICE «Unable to create version attribute\n»);

Этот вызов создаёт атрибутный файл ( /sys/bus/ldd/version ), содержащее номер ревизии кода lddbus .

Видео:Как устранить проблему с sm контроллер шиныСкачать

Как устранить проблему с sm контроллер шины

Устройства

На самом низком уровне, каждое устройство в системе Linux представлено экземпляром struct device :

struct device_driver *driver;

void (*release)(struct device *dev);

Есть много других полей struct device , которые представляют интерес только для кода ядра устройства. Эти поля, однако, стоит знать:

Устройство-«родитель» для устройства — то устройство, к которому оно подключено. В большинстве случаев родительским устройством является какая-то шина или хост-контроллер. Если parent является NULL, устройство является устройством верхнего уровня, которое обычно не то, что вы хотите.

Kobject, который представляет это устройство и подсоединяет его в эту иерархию. Заметим, что как правило device->kobj->parent эквивалентен &device-parent->kobj .

Строка, которая однозначно идентифицирует это устройство на этой шине. PCI устройства, например, используют стандартный формат PCI идентификатора, содержащий домен, шину, устройство и функциональные номера.

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

struct device_driver *driver;

Драйвер, который управляет этим устройством; мы изучаем struct device_driver в следующем разделе.

Читайте также: Количество звеньев цепи для шины 50 см

Поле собственных данных, которые могут быть использованы драйвером устройства.

void (*release)(struct device *dev);

Метод вызывается, когда удаляется последняя ссылка на устройство; он вызывается из метода release встроенного kobject-а. Все структуры устройства, зарегистрированные в ядре, должны иметь метод release , или ядро распечатывает страшные жалобы.

Перед тем, как структура устройства может быть зарегистрирована, должны быть установлены, по крайней мере, поля parent , bus_id , bus и release .

Регистрация устройства

Существует обычный набор функций регистрации и её отмены:

int device_register(struct device *dev);

void device_unregister(struct device *dev);

Мы видели, как код lddbus регистрирует свой тип шины. Тем не менее, настоящая шина является устройством и должна быть зарегистрирована отдельно. Для простоты, модуль lddbus поддерживает только одну виртуальную шину, так что драйвер создаёт свои устройства во время компиляции:

static void ldd_bus_release(struct device *dev)

printk(KERN_DEBUG «lddbus release\n»);

Это шина верхнего уровня, поэтому поля parent и bus остались NULL. У нас есть простой метод release , не делающий ничего, и, как первая (и единственная) шина, она имеет имя ldd0 . Это устройство шины регистрируется так:

printk(KERN_NOTICE «Unable to register ldd0\n»);

Как только этот вызов будет завершён, в sysfs в каталоге /sys/devices можно увидеть новую шину. Любые устройства, добавленные к этой шине, показываются затем в /sys/devices/ldd0/ .

Атрибуты устройства

Записи устройств в sysfs могут иметь атрибуты. Соответствующей структурой является:

ssize_t (*show)(struct device *dev, char *buf);

ssize_t (*store)(struct device *dev, const char *buf, size_t count);

Эти структуры атрибутов могут быть созданы во время компиляции с помощью этого макроса:

DEVICE_ATTR(name, mode, show, store);

Результирующая структура называется, предваряя dev_attr_ заданное name . Фактическое управление файлами атрибутов осуществляется обычной парой функций:

int device_create_file(struct device *device, struct device_attribute *entry);

void device_remove_file(struct device *dev, struct device_attribute *attr);

Поле dev_attrs в struct bus_type указывает на список атрибутов по умолчанию, создаваемых для каждого добавляемого к шине устройства.

Внедрение структуры устройства

Структура device содержит информацию, которая необходима ядру модели устройства для моделирования системы. Однако, большинство подсистем отслеживают дополнительную информацию о тех устройств, которые они содержат. Как результат, редкие устройства представлены голыми структурами device ; вместо этого, эта структура, как и структуры kobject, как правило, встроены в представление устройства более высокого уровня. Если вы посмотрите на определения struct pci_dev или struct usb_device , вы найдете похороненную внутри struct device . Как правило, низкоуровневые драйверы даже не знают об этой struct device , но здесь могут быть исключения.

Драйвер lddbus создаёт свой собственный тип устройства ( struct ldd_device ) и ожидает, что отдельные драйверы устройств зарегистрировали свои устройства, используя этот тип. Он является простой структурой:

#define to_ldd_device(_dev) container_of(_dev, struct ldd_device, dev);

Читайте также: Peugeot 408 какие шины

static ssize_t sculld_show_dev(struct device *ddev, char *buf) struct sculld_dev *dev = ddev->driver_data; return print_dev_t(buf, dev->cdev.dev); static DEVICE_ATTR(dev, S_IRUGO, sculld_show_dev, NULL); Затем, во время инициализации, устройство регистрируется и создается атрибут dev посредством следующей функции: static void sculld_register_dev(struct sculld_dev *dev, int index) sprintf(dev->devname, «sculld%d», index); Обратите внимание, что мы используем поле driver_data для сохранения указателя на нашу собственную внутреннюю структуру устройства.

Видео:Код 28 — для устройства не установлены драйверы в Windows 10 и Windows 7 (решение)Скачать

Код 28 — для устройства не установлены драйверы в Windows 10 и Windows 7 (решение)

Драйверы устройств

Модель устройства отслеживает все драйверы, известные в системе. Основной причиной для этого отслеживания является необходимость разрешить драйверному ядру сопоставлять драйверы с новыми устройствами. Однако, хотя драйверы представляют собой известные объекты внутри системы, стал возможным ряд других вещей. Драйверы устройств могут, например, экспортировать переменные информации и конфигурации, которые не зависят от какого-либо особого устройства. Драйверы определяются следующей структурой: int (*probe)(struct device *dev); int (*remove)(struct device *dev); void (*shutdown) (struct device *dev); Снова, некоторые поля этой структуры были опущены (смотрите
для полной информации). Здесь, name является именем драйвера (оно появляется в sysfs), bus является типом шины, с которой работает этот драйвер, kobj является неизбежным kobject, devices является списком всех устройств в настоящее время связанных с этим драйвером, probe является функцией, вызываемой для запроса наличия определённого устройства (и может ли этот драйвер работать с ним), remove вызывается, когда устройство удаляется из системы, и shutdown вызывается во время выключения для перевода устройства в пассивное состояние. Форма функций для работы со структурами device_driver должны теперь выглядеть уже знакомо (так что мы рассматриваем их очень быстро). Функциями регистрации являются: int driver_register(struct device_driver *drv); void driver_unregister(struct device_driver *drv); Существует обычная структура атрибута: ssize_t (*show)(struct device_driver *drv, char *buf); ssize_t (*store)(struct device_driver *drv, const char *buf, size_t count); DRIVER_ATTR(name, mode, show, store); И атрибутные файлы создаются обычным образом: int driver_create_file(struct device_driver *drv, struct driver_attribute *attr); void driver_remove_file(struct device_driver *drv, struct driver_attribute *attr); Структура bus_type содержит поле ( drv_attrs ), которое указывает на набор атрибутов по умолчанию, создаваемых для всех драйверов, связанных с этой шиной.

Внедрение структуры драйвера

Как и в случае с большинством структур драйверного ядра, структура device_driver обычно внедрена в высокоуровневую, зависимую от шины структуру. Подсистема lddbus никогда не пойдёт против такой тенденции, поэтому она определяет свою собственную структуру ldd_driver : struct device_driver driver; struct driver_attribute version_attr; #define to_ldd_driver(drv) container_of(drv, struct ldd_driver, driver); Здесь мы требуем, чтобы каждый драйвер предоставлял свою текущую версию программного обеспечения, а lddbus экспортирует эту строку версии для каждого драйвера о котором она знает. Шинно-зависимой функцией регистрации драйвера является: int register_ldd_driver(struct ldd_driver *driver) Первая половина функции просто регистрирует в ядре низкоуровневую структуру device_driver ; остальная устанавливает атрибут version . Так как этот атрибут создаётся во время выполнения, мы не можем использовать макрос DRIVER_ATTR ; вместо этого структура driver_attribute должна быть заполнена вручную. Обратите внимание, что мы установили владельцем атрибута модуль драйвера, а не модуль lddbus ; причину этого можно увидеть в реализации функции show для этого атрибута: static ssize_t show_version(struct device_driver *driver, char *buf) struct ldd_driver *ldriver = to_ldd_driver(driver); sprintf(buf, «%s\n», ldriver->version); Можно подумать, что владельцем атрибута должен быть модуль lddbus , поскольку функция, которая реализует данный атрибут, определяется здесь. Однако, эта функция работает со структурой ldd_driver , созданной (и принадлежащей) самим драйвером. Если бы эта структура ушла в то время, как процесс в пользовательском пространстве попытался прочитать номер версии, всё могло бы поломаться. Назначение модуля драйвера в качестве владельца атрибута предохраняет модулю от выгрузки, пока пользовательское пространство удерживает файл атрибута открытым. Так как каждый модуль драйвера создаёт ссылку на модуль lddbus , мы можем быть уверены, что lddbus не будет выгружена в неподходящее время. Для полноты, sculld создаёт свою структуру ldd_driver следующим образом: static struct ldd_driver sculld_driver = Источник

  • Свежие записи
    • Нужно ли менять пружины при замене амортизаторов
    • Скрипят амортизаторы на машине что делать
    • Из чего состоит стойка амортизатора передняя
    • Чем стянуть пружину амортизатора без стяжек
    • Для чего нужны амортизаторы в автомобиле
    • Правообладателям
    • Политика конфиденциальности


    📽️ Видео

    Другие устройства в диспетчере устройств как убрать Windows 11.Неизвестное устройство.PCI-контроллерСкачать

    Другие устройства в диспетчере устройств как убрать Windows 11.Неизвестное устройство.PCI-контроллер

    🖥️ Периферийное устройство Bluetooth драйвер WindowsСкачать

    🖥️ Периферийное устройство Bluetooth драйвер Windows

    ❓ Неизвестное устройство в Windows. Как решить проблему?Скачать

    ❓ Неизвестное устройство в Windows. Как решить проблему?

    Sm контроллер шины что это, 1Скачать

    Sm контроллер шины что это, 1

    Система Windows не смогла найти драйверы. Что делать?Скачать

    Система Windows не смогла найти драйверы. Что делать?

    Для устройства не установлены драйверы КОД 28Скачать

    Для устройства не установлены драйверы КОД 28

    Что такое Драйвера - Объяснение | Как это работаетСкачать

    Что такое Драйвера - Объяснение | Как это работает

    Sm контроллер шины windows 7/32 bit chipset SM Bus controller and others driversСкачать

    Sm контроллер шины windows 7/32 bit chipset SM Bus controller and others drivers

    Восклицательный знак в диспетчере устройств Windows. Исправляем и правильно устанавливаем драйверСкачать

    Восклицательный знак в диспетчере устройств Windows. Исправляем и правильно устанавливаем драйвер

    Периферийное устройство bluetooth и желтый треугольник - что делать?Скачать

    Периферийное устройство bluetooth и желтый треугольник - что делать?

    Как сделать Kernel Driver - Загрузка & ВыгрузкаСкачать

    Как сделать Kernel Driver - Загрузка & Выгрузка

    Не работают USB порты - 3 способа Решения! Windows 7/8/10/11Скачать

    Не работают USB порты - 3 способа Решения! Windows 7/8/10/11

    Для Устройства не Установлены Драйверы (код 28) Windows 7 8 10 11 ✅ РЕШЕНИЕСкачать

    Для Устройства не Установлены Драйверы (код 28) Windows 7 8 10 11 ✅ РЕШЕНИЕ

    Для устройства не установлены драйверы Код 28Скачать

    Для устройства не установлены драйверы Код 28

    Установка ВСЕХ Драйверов на Windows 7/8/10 в Один Клик | UnderMindСкачать

    Установка ВСЕХ Драйверов на Windows 7/8/10 в Один Клик | UnderMind

    Как найти и установить нужный драйвер на компьютерСкачать

    Как найти и установить нужный драйвер на компьютер

    Установка и обновление драйверов в Windows 10/11 БесплатноСкачать

    Установка и обновление драйверов в Windows 10/11 Бесплатно

    Что такое драйвера на компьютереСкачать

    Что такое драйвера на компьютере
Поделиться или сохранить к себе:
Технарь знаток