>
>
>
Разработка драйверов для 64-битных верс…

Евгений Рыжков
Статей: 125

Разработка драйверов для 64-битных версий Windows

В статье рассматриваются вопросы, связанные с выпуском драйверов для 64-битных версий Windows. Приводятся типовые проблемы и пути их решения, а также рассматриваются инструменты, упрощающие процесс разработки драйверов.

Введение

Выход в 2005 году первой версии операционной системы Windows для 64-битных процессоров AMD64 поставил перед разработчиками драйверов новую задачу - выпуск драйверов и для 32-битных, и для 64-битных систем. В то время многие производители оказались не готовы к поддержке драйверов для двух систем, поэтому многие устройства так и не получили обновленных драйверов. Тогда это было оправдано, поскольку 64-битные системы были в новинку и не так уж много пользователей их оценило. Однако с выходом Windows Vista x64 ситуация резко изменилась. Теперь и домашние пользователи хотят иметь 64-битную операционную систему, и разработчикам уже необходимо в обязательном порядке задуматься о выпуске 64-битных версий драйверов.

Прежде всего, возникает вопрос: Нужно ли разрабатывать 64-битные драйверы для 64-битных версий Windows? Ответ однозначен: "Да, нужно!". Дело в том, что использовать 32-битные драйверы на 64-битной системе в режиме ядра невозможно.

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

Основные положения

При разработке драйверов для Win64 обычно желательно использовать тот же самый исходный код, что и для Win32. Различия в коде стоит выносить в отдельные секции под условной компиляцией.

Перечислим несколько наиболее важных положений, касающихся 64-битных драйверов:

  • Поддержка режима DMA (Direct Memory Access). Включение в драйвер поддержки 64-битной адресации позволяет значительно повысить производительность.
  • Поддержка 32-битного ввода-вывода. Если драйвер использует процедуры DMA корректно в Windows 2000, то драйвер будет нормально работать и в 64-битных системах.
  • Драйвер должен поддерживать как 32-битные так и 64-битные версии команд IOCTL.

Необходимо заметить, что Microsoft максимально возможно обеспечивает разработчиков руководствами по переносу кода в новых версиях Windows DDK.

Потенциальные проблемы в коде

Список потенциальных проблем при переносе кода приведен в [1, 2]. Однако, там лишь названы эти проблемы, мы же подробно рассмотрим варианты их решения.

Итак, MSDN рекомендует нам использовать:

  • Новые типы данных, безопасные с точки зрения Win64. Это, прежде всего, типы фиксированной длины, а также типы, предназначенные специально для хранения указателей.
  • Корректные строки формата в printf-подобных функциях. Поскольку размеры указателей на 32-битных и 64-битных системах разные, то использовать одну и ту же строку формата не получится. Идеальным решением здесь является отказ от использования таких функций взамен использования их более безопасных аналогов.
  • При необходимости обрезать указатель, использовать функции PtrToLong и PtrToUlong. Однако, лучше переписать код так, чтобы подобная операция вовсе не потребовалась. Дело в том, что указатель после такой операции станет уже некорректным.
  • Использовать макросы FIELD_OFFSET и TYPE_ALIGNMENT вместо явного вычисления позиции переменной в структуре или ручного учета выравнивания. Это связано опять же с различными типами выравнивания и размерами указателей.

Особое внимание следует обращать на:

  • Операции с участием знаковых и беззнаковых переменных. Вопросы приведения типов переменных часто вызывают непонимание, поэтому лучше стараться их избегать.
  • Вызовы функций, где один из параметров является указателем. Причем потенциальная ошибка может быть скрыта как внутри функции, так и вне ее, при использовании результата ее работы.
  • Использование магических констант, которые могут изменяться в зависимости от разрядности системы. Обратите внимание, что число -1 на 64-битной системе уже не равно 0xffffffff, как это было на 32-битной. Чему оно равно? Разумеется, 0xffffffffffffffff, в то время как 0xffffffff - это всего лишь 0x00000000ffffffff.
  • Структуры, содержащие указатели. Так как изменения адресного пространства, произошедшие на 64-битных системах, могут напрямую сказаться на работе драйверов.
  • Приведение указателей к каким-либо типам данных (int, long).

Инструменты

Для проверки работоспособности драйверов рекомендуется использовать соответствующие инструменты. Помимо включения максимального уровня диагностики в компиляторе (/W4 или даже /Wall) обязательно необходимо использовать другие возможности.

Прежде всего, посмотрите на бесплатный инструмент от Microsoft - анализатор PREfast, если Вы еще с ним не знакомы. Это статический анализатор кода, который обнаруживает некоторые классы ошибок, которые часто встречаются как в драйверах, так и в обычных C и C++ программах.

Статический анализатор кода общего назначения Gimpel Software PC-lint обнаруживает, помимо некоторых из перечисленных ошибок, еще и огромное количество ошибок, встречающихся в обычных программах.

Другой статический анализатор кода Viva64 предназначен для поиска ошибок в C++ программах, проявляющихся при переносе кода с 32-битных на 64-битные системы.

Заключение

Как видите, ничего страшного в разработке 64-битных драйверов нет и инструменты, облегчающие этот процесс, доступны. А значит откладывать это больше не стоит.

Библиографический список