0

Я программирую устройство pci с verilog, а также записываю его драйвер, Я, вероятно, вставил некоторую ошибку в аппаратный дизайн, и когда я загружаю драйвер с insmod, ядро ​​просто застревает и не отвечает. Теперь я пытаюсь выяснить, какова последняя строка кода драйвера, которая заставляет мой компьютер застревать. Я вставил printk во все соответствующие функции, такие как probe и init, но не распечатывал их.как отладить устройство pci и драйвер linux

Какой еще код работает, когда я использую insmod до того, как он подключится к моей функции init? (Я думаю, что ядро ​​застряло там)

+0

вы можете увидеть напечатанные сообщения в/вар/сообщения журнала /. –

+0

Как это отличается от просмотра dmesg при этом insmod? – yonigo

+0

Я не думаю, что есть какая-то разница между ними. Я думал, что ты не сделал do dmesg. –

ответ

0

Я бы поставил логический анализатор на линии автобуса (на FPGA вы могли бы использовать чипслет или аналогичный). Затем вы сможете указать, какой доступ вызывает (и исправить аппаратное обеспечение). В любом случае это будет полезно для отладки или анализа будущих проблем.

Другим способом было бы использовать утилиту сброса аварийной ситуации ядра, которая в прошлом спасла мне некоторые головные боли. Но в зависимости от вашего дистрибутива Linux требуется установка (доступная по умолчанию в RH). См. http://people.redhat.com/anderson/crash_whitepaper/

0

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

Вы должны быть в состоянии видеть printk s, поскольку они напечатаны, они не буферизованы и не должны затеряться. Это применимо только в ситуациях, когда вы можете напрямую видеть вывод ядра, например, на текстовой консоли или через последовательную линию. Если на этом пути есть какое-то другое приложение, например, отображение журналов ядра в терминале в X11 или поверх ssh, у него может не быть возможности читать и отображать журналы до того, как компьютер зависает.

Если по каким-либо другим причинам printk s все еще не работает для вас, вы можете вместо этого вернуть функцию init. Просто проверьте и переместите возврат позже в init, пока не найдете точку, где он сработает.

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

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

0

Тот факт, что ядро ​​застревает, как только вы устанавливаете свой модуль драйвера, заставляет задуматься, если какой-либо другой драйвер (встроенный в ядро?) Уже управляет устройством. Я сделал эту ошибку, и именно поэтому я спрашиваю. Я хотел бы найти строку «драйвер ядра в использовании» на выходе «lspci» перед установкой модуля. В любом случае ваши printk должны быть видны в dmesg-выходе.

0

в дополнении к предложению Клаудио, еще пара отлаживать идеи: 1. попытки kgdb (https://www.kernel.org/doc/htmldocs/kgdb/EnableKGDB.html) 2. Использование JTAG интерфейс для подключения к отладочным инструментам (это я думаю, варьируются от устройств, поставщики, так что вы должны будете фигуры какие инструменты отладки вам нужны для конкретного оборудования)

1

printk s часто не являются полезными для отладки такой проблемы. Они достаточно буферизованы, что вы не увидите их вовремя, если система зависает вскоре после вызова printk.

Гораздо более результативно выборочно прокомментировать разделы вашего драйвера и по мере устранения определить, какая строка является (первой) проблемой.

Начните с комментирования раздела init всего модуля, оставив только return 0;. Постройте его и загрузите. Он висит? Перезагрузите систему, повторите следующие несколько строк (class_create()?) И повторите.

1

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

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

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

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

Какие методы могут быть рекомендованы с точки отладки программного обеспечения зрения:

  1. Попробуйте пересмотреть вам код драйвера посвятив особое внимание обработчика прерываний и места, где вы отключить/включить прерывания для синхронизации.
  2. Комментирование всей логики драйвера с постепенным раскомментированием может помочь в решении проблемы локализации проблемы.
  3. Вы можете попробовать удаленное отладку ядра вашего драйвера. Я советую использовать виртуальную машину для этих целей, но я не знаю, разрешают ли они передавать устройство PCI на виртуальной машине.
  4. Вы можете попробовать трюк с отслеживанием в памяти. Идея состоит в том, чтобы предварительно распределить блок памяти с хорошо известными виртуальными и физическими адресами и обнулить его. Затем измените свой драйвер, чтобы записать данные трассировки в этом фрагменте, используя его виртуальный адрес. (Например, присвойте уникальное целочисленное значение каждому событию, которое вы хотите трассировать, и напишите '1' в соответствующий индекс массива байтов в ячейке предварительно выделенной памяти). Затем, когда ваша система зависает, вы можете просто принудительно создать генерацию дампа памяти, а затем проанализировать макет памяти, упакованный в дамп, используя физический адрес блока памяти со следами. Я использовал эту технику с VmWare Workstation VM в Windows. Когда система повесилась, я просто приостанавливаю экземпляр виртуальной машины и смотрю на соответствующий файл .vmem, который содержит необработанную память в физической памяти экземпляра виртуальной машины. Не уверен, что этот трюк будет работать легко или даже вообще будет работать на Linux, но я бы попробовал.
  5. Наконец, вы можете попробовать отслеживать сообщения на шине PCI, но я не эксперт в этом поле и не уверен, что это может помочь в вашем случае или нет.

В целом отладка ядра - довольно сложная задача, в которой используется множество трюков, и все они работают только для определенного набора случаев. :(

Смежные вопросы