Отладка драйверов удара молнии

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

Отладка VT-d I/O Виртуализация MMU

Более новые Способные к удару молнии Macs предоставляют поддержку для I/O виртуализация MMU (VT-d). Эта технология позволяет виртуальным машинам иметь прямой доступ к аппаратным средствам. В результате этой поддержки, когда Ваше устройство выполняет операции DMA, адресуется I/O, это использует, может отличаться от физических адресов, как замечено ядром OS X.

Полная спецификация может быть найдена здесь: Intel® Virtualization Technology для Направленной Спецификации I/O.

Системы Ivy Bridge рабочий OS X v10.8.2 и позже включают модуль Intel VT-d как DMA remapper. Эта функциональность поддерживается текущим APIs почти таким же способом как контроллер DART на компьютерах PowerMac G5. (Чтобы изучить, как это работает на высоком уровне, считайте Поддержку DMA на 64-разрядных Архитектурах системы).

Когда VT-d включен, некоторые изменения, которые Вы рассмотрите как, результаты этого:

Если Вы просите неотображенные физические адреса — путем вызова IOMemoryDescriptor объект getPhysicalSegment метод с опцией kIOMapperNone или IODMACommand объект initWithSpecification метод с mappingOptions набор к чему-то другому, чем kMapped— и попытайтесь использовать их для DMA, Ваш драйвер повредится.

Включение паника VT-d

По умолчанию отказы VT-d регистрируются к /var/log/system.log. Отказ VT-d похож на следующее:

vtd[0] fault: device 13:0:0 reason 0x6 R:0x3dff000

В примере выше, 13:0:0 шина, устройство и функция устройства, генерировавшего отказ. Можно определить, произвело ли устройство отказ путем взгляда на pci-debug поле в выводе ioreg или в приложении IORegistryExplorer и сравнении значений.

Для списка кодов причин посмотрите Intel® Virtualization Technology для Направленной Спецификации I/O.

R указывает, что операция чтения инициировала отказ. (W указывает запись.) Окончательное значение является адресом, который устройство пыталось считать или записать (выраженный как адрес I/O-space).

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

pci=0x100

Отключение VT-d

При отладке драйверов устройств PCIe часто полезно временно отключить VT-d так, чтобы адреса I/O совпали с соответствующими физическими адресами. Для отключения VT-d добавьте, что следующие к ядру загружают args:

dart=0x0

Если проблема, которую Вы отлаживаете, уходит в этом режиме, она обычно указывает одну из следующих ошибок:

  • Некоторая часть Вашего кода неправильно передает физический адрес в RAM к Вашему устройству в целях DMA вместо адреса I/O.

  • Вашему коду не удалось вызвать prepare или вызванный prepare неправильно на IOMemoryDescriptor объект перед использованием его для выполнения DMA.

Отладка пауза PCIe

По умолчанию ядро OS X распространяет распределения адресов PCI. В результате события паузы PCIe нечасто имеют место, который делает эти события оспариванием для отладки. Можно сделать отладку проще путем отключения этого поведения распространения выделения. С распространением отключенного, почти каждое событие замены в горячем режиме инициировало событие паузы.

Для отключения распространения выделения добавьте следующий к ядру boot-args строка:

pci=0x200

Предотвращение утечек памяти

Драйверы должны гарантировать выпуск любого и всех ресурсов, полученных за жизненный цикл драйвера. В частности диапазоны I/O с отображенной памятью, память и объекты должны все быть освобождены и перепроверены для любых утечек. Использование инструментов такой как ioclasscount может помочь идентифицировать некоторые из этих типов утечек. Стандартная форма утечек представлена ссылками (т.е. сохраните количества). Часто, трудно определить источник этих ссылок. Один способ определить источник этих ссылок состоит в том, чтобы переопределить taggedRetain() метод и получает след вызывающей стороны, к которой можно тогда отправить printf(), kprintf(), или IOTimeStampConstant().

Перечисление 4-1  , ищущее утечки памяти

   void
   AppleSamplePCI::taggedRetain ( const void * tag ) const
   {
             void *    bt[16] = { 0 };
 
             OSBacktrace ( &bt[0], sizeof ( bt ) / sizeof ( bt[0] ) );
             super::taggedRetain ( tag );
   }

Используя стандарт symbolication инструменты позволяет Вам определять, какие функции или методы заставили ссылку (ки) быть взятой. Кроме того, можно переопределить taggedRelease() и соответствуйте сохранение и выпуски для нахождения вызовов к taggedRetain(), которые не имеют никакого соответствующего вызова к taggedRelease().