Работа со встроенным программным обеспечением

Предыдущая  Содержание  Следующая V*D*V

Как автор драйвера, вы можете столкнуться с устройством, которое должно иметь встроенное программное обеспечение (прошивку), загружаемую в него перед тем, как оно будет функционировать должным образом. Конкуренции во многих частях рынка оборудования настолько сильна, что даже стоимость небольшой EEPROM для программы управления устройством будет больше, чем производитель готов потратить. Таким образом, встроенное программное обеспечение поставляется на компакт-дисках вместе с оборудованием и операционная система ответственна за передачу программы в само устройство.

 

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

 

static char my_firmware[ ] = { 0x34, 0x78, 0xa4, ... };

 

Однако, такой подход почти наверняка является ошибкой. Кодирование прошивки в драйвере раздувает код драйвера, делает обновление прошивки трудным и весьма вероятно заработать проблемы лицензирования. Весьма маловероятно, что поставщик выпустил образ прошивки под GPL, так что смешивание его с лицензированным под GPL кодом обычно является ошибкой.

 

По этой причине устройства, содержащие внедрённую прошивку, вряд ли будут приняты в главную ветку ядра или включаться дистрибьюторами Linux.

Интерфейс ядра для встроенного программного обеспечения

Правильным решением является получение прошивки из пользовательского пространства, когда это действительно необходимо. Однако, пожалуйста, сопротивляйтесь искушению попробовать открыть файл, содержащий прошивку, непосредственно из пространства ядра; это подверженная ошибкам операция и она помещает политику (в форма имени файла) в ядро. Вместо этого корректный подход заключается в использовании интерфейса прошивки, который был создан только для этой цели:

 

#include <linux/firmware.h>

int request_firmware(const struct firmware **fw, char *name, struct device *device);

 

Вызов request_firmware просит пользовательское пространство найти и предоставить образ прошивки в ядро; мы рассмотрим подробности, как это работает, за минуту. name (имя) должно идентифицировать желаемую прошивку; при нормальном использовании это имя файла прошивки, предоставленной производителем. Что-то вроде my_firmware.bin является типичным. Если прошивка успешно загружена, возвращаемое значение равно 0 (в противном случае, возвращается обычный код ошибки), и аргумент fw указывает на одну из таких структур:

 

struct firmware {

    size_t size;

    u8 *data;

};

 

Эта структура содержит актуальную прошивку, которая теперь может быть загружена в устройство. Будьте осторожны, эта прошивка является непроверенными данными из пространства пользователя; вы должны применять любые и все тесты которые можно придумать, чтобы убедить себя, что она является правильным образом прошивки перед отправкой его в оборудование. Прошивка устройства обычно содержит идентификационные строки, контрольные суммы и так далее; проверяйте их все перед тем, как доверять данным.

 

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

 

void release_firmware(struct firmware *fw);

 

Так как request_firmware запрашивает для помощи пространство пользователя, это гарантирует сон перед возвратом. Если ваш драйвер не имеет возможности заснуть, когда он должен запросить прошивку, может быть использован асинхронный вариант:

 

int request_firmware_nowait(struct module *module,

            char *name, struct device *device, void *context,

            void (*cont)(const struct firmware *fw, void *context));

 

Дополнительными аргументами здесь являются module (который почти всегда будет THIS_MODULE), context (свой указатель данных, который не используется подсистемой прошивки) и cont. Если все пойдёт хорошо, request_firmware_nowait начинает процесс загрузки прошивки и возвращает 0. В какой-то момент в будущем, будет вызвана cont с результатом загрузки. Если по каким-то причинам загрузка прошивки не удаётся, fw является NULL.

Как это работает

Подсистема прошивки работает с механизмами sysfs и горячего подключения. Когда сделан вызов request_firmware, с использованием имени вашего устройства в /sys/class/firmware создаётся новый каталог. Этот каталог содержит три атрибута:

 

loading

Этот атрибут должен быть установлен в единицу процессом пользовательского пространства, который загружает прошивку. Когда процесс загрузки завершится, он должен быть установлен в 0. Запись значения -1 для загрузки прерывает процесс загрузки прошивки.

 

data

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

 

device

Этот атрибут является символической ссылкой на соответствующую запись в /sys/devices.

 

После того, как были созданы записи в sysfs, ядро генерирует для вашего устройства событие горячего подключения. Окружение, передаваемое в обработчик горячего подключения, включает в себя переменную FIRMWARE, которая установлена в имя, указанное в request_firmware. Обработчик должен найти файл прошивки и скопировать его в ядро с помощью предоставленных атрибутов. Если файл не может быть найден, обработчик должен установить атрибут loading в -1.

 

Если запрос на прошивку не обслуживается в течение 10 секунд, ядро прерывает его и возвращает статус неисполнения драйверу. Этот период ожидания может быть изменён с помощью атрибута /sys/class/firmware/timeout в sysfs.

 

Использование интерфейса request_firmware позволяет вам распространять прошивки с вашим драйвером. При правильной интеграции в механизм горячего подключения, подсистема загрузки прошивки позволяет устройствам работает сразу "из коробки". Это явно лучший способ решения проблемы.

 

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

Предыдущая  Содержание  Следующая