Создание и отладка ядер

Эта глава не о создании расширений ядра (KEXTs). Существует много хороших учебных руководств KEXT на сайте документации разработчика Apple (http://developer .apple.com/documentation). Эта глава о добавлении новых модулей в ядре (дополнительные части ядра), создание ядер и отладка сборки расширения ядра и расширение ядра.

Обсуждение разделено на три раздела. Первые, Добавляющие Новые Файлы или Модули, описывает, как добавить новую функциональность в само ядро. Когда использование KEXT не возможно (например, при добавлении определенной низкоуровневой поддержки оборудования системной платы), необходимо только добавить файлы в ядро.

Второй раздел, Создавая Ваше Первое Ядро, описывает, как создать ядро, включая то, как создать ядро с поддержкой для отладочных средств, как добавить новые опции, и как получить источники, которые имеют подобный год изготовления вина тем в определенной версии OS X или Дарвина.

Третий раздел, Когда Вещи Идут не так, как надо: Отладка Ядра, говорит, как отладить ядро или использование модуля ядра ddb и gdb. Это - обязательное для чтения для любого делающего разработку ядра.

Добавление новых файлов или модулей

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

Изменение конфигурационных файлов

Подробные данные добавления нового файла или модуля в ядро отличаются согласно тому, какая часть ядра содержит файл. Если Вы добавляете новый файл или модуль в часть Маха ядра, необходимо перечислить его в различных файлах в xnu/osfmk/conf. Для части BSD ядра необходимо перечислить его в различных файлах в xnu/bsd/conf. В любом случае процедура является в основном тем же, только в различном каталоге.

Этот раздел разделен на два подраздела. Первое описывает добавление самого модуля, и второе описывает включение модуля.

Добавление файлов или модулей

В надлежащем conf каталог, необходимо добавить файлы или модули в различные файлы. Файлы MASTER, MASTER.ppc, и MASTER.i386 содержите список параметров конфигурации, которые должны быть встроены в ядро для всей архитектуры, PowerPC и i386, соответственно.

Они дополняются files, files.ppc, и files.i386, которые содержат ассоциации между опциями компиляции и файлами, связанными с ними для их соответствующей архитектуры.

Формат для этих двух файлов является относительно прямым. Если Вы добавляете новый модуль, необходимо сначала выбрать имя для того модуля. Например, если вызывают Ваш модуль mach_foo, необходимо тогда добавить новую строку опции около вершины files это - пробел (пространство или вкладка) разграниченный и похоже на это:

OPTIONS/mach_foo    optional mach_foo

Первая часть определяет имя модуля, поскольку это будет использоваться в #if операторы в коде. (См. Изменение Файлов исходного кода для получения дополнительной информации.) Вторая часть всегда является дополнительным словом. Третья часть говорит имя опции, как используется включить или выключить его в a MASTER файл. Любая строка с mach_foo в последнем поле будет включен, только если существует надлежащая строка в a MASTER файл.

Затем позже в файле, Вы добавляете

osfmk/foo/foo_main.c            optional mach_foo
osfmk/foo/foo_bar.c             optional mach_foo

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

osfmk/crud/mandatory_file.c     standard

Если Вы не добавляете модулей, то Вы сделаны. Иначе, также необходимо включить опцию в одном из MASTER файлы.

Включение опций модуля

Включить опцию модуля (как описано в files файлы), необходимо добавить запись для той опции в один из MASTER файлы. Если Ваш код не является псевдоустройством BSD, необходимо добавить что-то как следующее:

options MACH_FOO

Иначе, необходимо добавить что-то вроде этого:

pseudo-device   mach_foo

В случае псевдоустройства (например, /dev/random), можно также добавить число. Когда Ваши проверки кода, чтобы видеть, должно ли это быть включено, это может также проверить, что число и выделяет ресурсы больше чем для одного псевдоустройства. Значение многократных псевдоустройств является зависящим от устройств. Пример этого ppp, который выделяет ресурсы для двух одновременных соединений PPP. Таким образом, в MASTER.ppc файл, это имеет строку:

pseudo-device   ppp 2

Изменение файлов исходного кода

В ядре OS X автоматически компилируются все файлы исходного кода. Это - ответственность самого файла C, чтобы определить, должно ли его содержание быть включено в сборку или нет.

В примере выше, Вы создали вызванный модуль mach_foo. Предположите, что Вы хотите, чтобы этот файл скомпилировал только на основанных на PowerPC компьютерах. В этом случае необходимо было включать опцию только в MASTER.ppc а не в MASTER.i386. Однако по умолчанию, просто указание файла foo_main.c в files причины это, чтобы быть скомпилированным, независимо от указанных опций компиляции.

Чтобы заставить код скомпилировать только, когда опция mach_foo включена в конфигурацию, необходимо начать каждый исходный файл C со строк

#include <mach_foo.h>
#if (MACH_FOO > 0)

и закончите его

#endif /* MACH_FOO */

Если mach_foo псевдоустройство, и необходимо проверить число mach_foo псевдоустройства включали, можно сделать дальнейшие тесты значения MACH_FOO.

Обратите внимание на то, что файл <mach_foo.h> не что-то, что Вы создаете. Это создается самими make-файлами. Необходимо работать make exporthdrs прежде make all генерировать эти файлы.

Создание первого ядра

Прежде чем можно будет создать ядро, необходимо сначала получить исходный код. Исходный код для ядра OS X может быть найден в Дарвине xnu проект на http://www .opensource.apple.com. Для обнаружения текущей версии ядра используйте команду uname -a. Если Вы сталкиваетесь с проблемой, ищете архивы дарвинского ядра и списков рассылки дарвинской разработки для получения информации. Если это не помогает, попросите помощи в любом списке. Архивы списка и информация о подписке могут быть найдены в http://www .lists.apple.com.

Затем, необходимо будет скомпилировать несколько инструментов поддержки. Доберитесь bootstrap_cmds, Libstreams, kext_tools, IOKitUser, и cctools пакеты от http://www .opensource.apple.com. Извлеките файлы из них .tar пакеты, затем сделайте следующее:

sudo mkdir -p /usr/local/bin
sudo mkdir -p /usr/local/lib
cd bootstrap_cmds-version/relpath.tproj
make
sudo make install
cd ../../Libstreams-version
make
sudo make install
cd ../cctools-version
sudo cp /usr/include/ar.h \
        /System/Library/Frameworks/Kernel.framework/Headers

В cctools пакет, измените Makefile, и изменение COMMON_SUBDIRS строка (включая строку продолжения после него) для чтения:

COMMON_SUBDIRS = libstuff libmacho misc

Наконец, дайте следующие команды:

make RC_OS=macos
sudo cp misc/seg_hack.NEW /usr/local/bin/seg_hack
cd ld
make RC_OS=macos kld_build
sudo cp static_kld/libkld.a /usr/local/lib
sudo ranlib /usr/local/lib/libkld.a

Теперь Вы сделаны с cctools проектом. Один последний шаг остается: компиляция kextsymboltool. Чтобы сделать это, извлеките kext_tools tarball, затем сделайте следующее:

sudo mkdir -p /System/Library/Frameworks/IOKit.framework/Versions/A/PrivateHeaders/kext
cd /System/Library/Frameworks/IOKit.framework/
sudo ln -s Versions/A/PrivateHeaders PrivateHeaders
sudo cp PATH_TO_IOKITUSER/IOKitUser-version/kext.subproj/*.h PrivateHeaders/kext
cd PATH_TO_KEXT_TOOLS/kext_tools-version
gcc kextsymboltool.c -o kextsymboltool
sudo cp kextsymboltool /usr/local/bin

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

Следующий шаг должен скомпилировать само ядро. Во-первых, измените каталоги в xnu каталог. Затем, необходимо установить несколько переменных окружения соответственно. Для Вашего удобства источники ядра содержат сценарии оболочки, чтобы сделать это для Вас. Если Вы используете sh, удар, zsh, или некоторую другую Совместимую с границей оболочку, даете следующую команду:

source SETUP/setup.sh

При использовании csh, tcsh, или подобной оболочки, используйте следующую команду:

source SETUP/setup.csh

Затем необходимо быть в состоянии ввести

make exporthdrs
make all

и вложите рабочее ядро BUILD/obj/RELEASE_PPC/mach_kernel (принятие Вас создает a RELEASE ядро для PowerPC, конечно).

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

Создание альтернативной конфигурации ядра

При создании ядра можно хотеть создать конфигурацию кроме RELEASE конфигурация (конфигурация поставки значения по умолчанию). Дополнительные конфигурации RELEASE_TRACE, DEBUG, DEBUG_TRACE, и PROFILE. Эти конфигурации добавляют различные дополнительные опции (кроме PROFILE, который резервируется для будущего расширения, и в настоящее время отображается на RELEASE).

Самые полезные и интересные конфигурации RELEASE и DEBUG. Конфигурация выпуска должна совпасть с акциями выпущенное Apple ядро, таким образом, это интересно, только если Вы создаете источник, отличающийся от того, что использовалось для создания ядра, которое Вы уже выполняете. Компиляция ядра, не указывая конфигурацию приводит к RELEASE создаваемая конфигурация.

DEBUG конфигурация включает ddb, последовательный отладчик в ядре. ddb отладчик полезен для отладки паники, происходящей рано в начальной загрузке или в определенных частях драйвера Ethernet. Это также полезно для отладки низкоуровневых подпрограмм обработчика прерываний, которые не могут быть отлажены при помощи более традиционного gdb.

Для компиляции альтернативной конфигурации ядра необходимо выполнить ту же основную процедуру, как обрисовано в общих чертах ранее, изменив финал make оператор немного. Например, для создания DEBUG конфигурация, вместо ввода

make all

Вы вводите

make KERNEL_CONFIGS=DEBUG all

и ожидайте.

Для включения дополнительных опций компиляции необходимо изменить один из MASTER файлы. Для получения информации об изменении этих файлов посмотрите раздел Enabling Module Options.

Когда вещи идут не так, как надо: отладка ядра

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

Существует много способов разыскать проблемы в коде ядра. Во многих случаях можно найти проблему посредством тщательного использования printf или IOLog операторы. Некоторые люди клянутся этим методом, и действительно, учитывая достаточное количество времени и усилие, любая ошибка может быть найдена и исправлена, не используя отладчик.

Конечно, ключевым словам в том операторе “дают достаточное количество времени и усилие”. Для остальной части нас существуют отладчики: gdb и ddb.

Установка флагов отладки в открытом встроенном микропрограммном обеспечении

За исключением паники ядра или вызовов к PE_enter_debugger, не возможно сделать, удаленная отладка ядра, не устанавливая флаги отладки в Открывает Firmware. Эти флаги относятся к обоим gdb и ddb отладка и достаточно важна для гарантирования их собственного раздела.

Для установки этих флагов можно или использовать nvram программа (из командной строки OS X) или доступ Ваш компьютер Открывает Firmware. Можно получить доступ, Открывают Firmware это удержанием Опции O F Команды во время начальной загрузки. Для большинства компьютеров значение по умолчанию для, Открывают Firmware, чтобы представить приглашение командной строки на Вашем мониторе и принять ввод с Вашей клавиатуры. Для некоторых более старых компьютеров необходимо использовать последовательную линию в 38 400, 8N1. (Технически, такие компьютеры не поддерживаются OS X, но некоторые применимы при Дарвине, и таким образом они упоминаются здесь для полноты.)

От Открыть подсказки Firmware можно установить флаги с setenv команда. Из командной строки OS X Вы использовали бы nvram команда. Обратите внимание на то, что при изменении этих флагов необходимо всегда смотреть на старое значение для надлежащего, Открывают переменные Firmware и добавляют debug флаги.

Например, если Вы хотите установить флаги отладки в 0x4, Вы используете одну из следующих команд. Для компьютеров с последними версиями Открывают Firmware, Вы ввели бы

printenv boot-args
setenv boot-args original_contents debug=0x4

от открытого встроенного микропрограммного обеспечения или

nvram boot-args
nvram boot-args="original_contents debug=0x4"

из командной строки (как корень).

Для более старых версий микропрограммного обеспечения интересная переменная boot-command. Таким образом Вы могли бы сделать что-то как

printenv boot-command
setenv boot-command 0 bootr debug=0x4

от открытого встроенного микропрограммного обеспечения или

nvram boot-command
nvram boot-command="0 bootr debug=0x4"

из командной строки (как корень).

Конечно, более важный вопрос - то, какое значение выбрать для отладки отмечает. Таблица 20-1 перечисляет флаги отладки, поддерживающиеся в OS X.

Табличные 20-1  флаги Отладки

Символьное имя

Флаг

Значение

DB_HALT

0x01

Останов во время начальной загрузки и ожидает присоединения отладчика (gdb).

DB_PRT

0x02

Отправьте отладку ядра printf вывод к консоли.

DB_NMI

0x04

Заскочите в отладчик на NMI (Питание команды, Escape Сдвига Управления Опции Команды, или прервите переключатель).

DB_KPRT

0x08

Отправьте отладку ядра kprintf вывод к последовательному порту.

DB_KDB

0x10

Сделать ddb (kdb) отладчик по умолчанию (требует пользовательского ядра).

DB_SLOG

0x20

Выведите определенную диагностическую информацию к системному журналу.

DB_ARP

0x40

Позвольте отладчик ARP, и маршрут (позволяет отлаживать через маршрутизаторы и устраняет необходимость постоянной записи ARP, но потенциальная дыра в системе безопасности) — не доступный во всех ядрах.

DB_KDP_BP_DIS

0x80

Поддерживайте старые версии gdb в более новых системах.

DB_LOG_PI_SCRN

0x100

Отключите графическое паническое диалоговое окно.

Опция DB_KDP_BP_DIS если Ваши целевые и хост-системы выполняют те же или аналогичные версии OS X с соответствием инструментов разработчика, не доступно во всех системах и не должен быть важным. Последняя опция только доступна в Mac OS 10.2 и позже.

Предотвращение сторожевых проблем таймера

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

Первый из них, сторожевого таймера управления питанием, разработан для восстановления системы к известному безопасному состоянию в случае неожиданной потери связи между аппаратными средствами управления питанием и CPU. Этот таймер только присутствует в G4 и более ранних рабочих столах и ноутбуках и в ранних рабочих столах G5. Более в частности это присутствует только в машинах, содержащих PMU (Блок управления питанием) микросхема.

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

Проблема происходит, когда сбой в коммуникации вызывается путем ввода отладчика, в то время как микросхема PMU находится в одном из этих «небезопасных» состояний. Если микросхему оставят в одном из этих «небезопасных» состояний слишком долго, то это завершит работу компьютера для предотвращения перегрева или других проблем.

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

Для отключения этого сторожевого таймера добавьте параметр pmuflags=1 к загрузочным аргументам ядра. Посмотрите, что Флаги Отладки Установки в Открывают Firmware для получения информации о том, как добавить загрузочный аргумент.

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

Выбор отладчика

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

Для проблем, включающих расширения сети или низкоуровневую операционную систему bringups, ddb единственный способ сделать отладку. Для других ошибок, gdb обычно проще использовать. Для полноты эта глава описывает, как использовать обоих ddb и gdb сделать основную отладку. С тех пор gdb самостоятельно хорошо документируется и обычно используется для прикладного программирования, эта глава принимает, по крайней мере, передающее знание основ использования gdb и внимание на области, где удаленный (ядро) gdb отличается.

Используя gdb для отладки ядра

gdb, короткий для Отладчика GNU, часть программного обеспечения, обычно используемого для отладки программного обеспечения в системах Linux и UNIX. Этот раздел предполагает, что Вы использовали gdb прежде, и не пытается объяснить основное использование.

В стандартных сборках OS X (и в Ваших сборках, если Вы не компилируете с ddb поддержка), gdb поддержка встроена в систему, но выключена кроме случая паники ядра.

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

Можно заставить тестовый компьютер (целевой объект отладки) заскакивать в отладчик следующими способами:

  • отладка на панике

  • отладка на NMI

  • отладка на начальной загрузке

  • программно заскочите в отладчик по умолчанию

    Функция PE_enter_debugger может быть вызван отовсюду в ядре, несмотря на то, что если gdb Ваш отладчик по умолчанию, катастрофический отказ закончится, если сетевое оборудование не будет инициализировано или если gdb не может использоваться в том определенном контексте. Этот вызов описан в заголовке pexpert/pexpert.h.

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

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

Как только Вы создали ядро с помощью узла отладки, необходимо тогда скопировать его в целевой компьютер и перезагрузить целевой компьютер. В этой точке при выполнении отладки только для паники необходимо инициировать панику. Иначе, необходимо сказать целевому компьютеру заскакивать в отладчик путем выпуска NMI (или путем простой начальной загрузки, в случае debug=0x1).

Затем, если Ваше ядро не поддерживает ARP при отладке (и если Вы не включили его с надлежащим флагом отладки), необходимо добавить постоянную запись ARP для цели. Это будет неспособно ответить на запросы ARP при ожидании отладчика. Это гарантирует, что внезапно не исчезнет Ваше соединение. Следующий пример предполагает, что Ваша цель target.foo.com с IP-адресом 10.0.0.69:

$ ping -c 1 target_host_name
ping results: ....
$ arp -an
target.foo.com (10.0.0.69): 00:a0:13:12:65:31
$ sudo arp -s target.foo.com 00:a0:13:12:65:31
$ arp -an
target.foo.com (10.0.0.69) at00:a0:13:12:65:31 permanent

Теперь, можно начать отлаживать путем выполнения следующего:

gdb /path/to/mach_kernel
source /path/to/xnu/osfmk/.gdbinit
p proc0
source /path/to/xnu/osfmk/.gdbinit
target remote-kdp
attach 10.0.0.69

Обратите внимание на то, что ядро Маха передало как параметр gdb должен быть загруженный символом файл ядра, расположенный в BUILD/obj/DEBUG_PPC/mach_kernel.sys (для сборок ядра отладки, RELEASE_PPC для сборок неотладки), не загрузочное ядро, которое Вы скопировали на целевой объект отладки. Иначе большая часть gdb макросы перестанут работать. Корректное ядро должно быть несколько раз более большим, чем нормальное ядро.

Необходимо сделать p proc0 команда и получает .gdbinit файл (из надлежащих источников ядра) дважды для работы вокруг ошибки в gdb. Конечно, если Вам не нужны ни одни из макросов в .gdbinit, можно пропустить те две инструкции. Макросы имеют главным образом интерес для людей, отлаживающих аспекты Маха, хотя они также обеспечивают способы получить информацию о в настоящее время загруженном KEXTs.

При отладке модуля ядра необходимо выполнить некоторую дополнительную работу для получения отладочной информации о модуле. Во-первых, необходимо знать адрес загрузки для модуля. Можно получить эту информацию путем выполнения kextstat (kmodstat в системах рабочий OS X v10.1 или ранее) как корень на цели.

Если Вы уже находитесь в отладчике, то принятие цели не паниковало, необходимо быть в состоянии использовать continue функция в gdb для восстановления цели получите эту информацию, затем инициируйте другой NMI для ронения в отладчик.

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

Как только у Вас есть адрес загрузки рассматриваемого модуля, необходимо создать файл символов для модуля. Вы делаете это по-разному на различных версиях OS X.

Для версий 10.1 и ранее, Вы используете kmodsyms программа для создания файла символов для модуля. Если вызывают Ваш KEXT mykext и это загружается в адресе 0xf7a4000, например, Вы изменяете каталоги на mykext.kext/Contents/MacOS и тип:

kmodsyms -k path/to/mach_kernel -o mykext.sym mykext@0xf7a4000

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

Для версий после 10.1, у Вас есть две опции. Если Ваш KEXT не разрушает компьютер, когда это загружается, можно спросить kextload генерировать символы во время загрузки путем передачи его следующие опции:

kextload -s symboldir mykext.kext

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

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

kextload -n -s symboldir mykext.kext

Если тогда предложит Вам адрес загрузки расширения ядра и адреса всех его зависимостей. Как упомянуто ранее, можно найти адреса с kextstat (или kmodstat) или путем ввода showallkmods внутри gdb.

У Вас должны теперь быть файл или файлы, содержащие символьную информацию это gdb может использовать для определения преобразований адресов в имена в KEXT. Добавить символы от этого KEXT, в gdb на Вашем узле отладки введите команду

add-symbol-file mykext.sym

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

Особенный gdb Проблемы Решения I/O

Как описано в Адресных пространствах, некоторые аппаратные средства Macintosh имеют третий способ адресации под названием обращение I/O, отличающееся и от физических и от виртуальных способов адресации. Большинство разработчиков не должно будет знать об этих режимах во всех подробностях.

То, где некоторые разработчики могут столкнуться с проблемами, отлаживает драйверы устройств PCI и пытается к памяти/регистрам устройства доступа.

Для разрешения дампа памяти I/O-mapped сделайте следующее:

set kdp_read_io=1

Для дампа в физическом режиме сделайте следующее:

set kdp_trans_off=1

Например:

(gdb) x/x 0xf8022034
0xf8022034: Cannot access memory at address 0xf8022034
(gdb) set kdp_trans_off=1
(gdb) x/x 0xf8022034
0xf8022034: Cannot access memory at address 0xf8022034
(gdb) set kdp_read_io=1
(gdb) x/x 0xf8022034
0xf8022034: 0x00000020
(gdb)

Если Вы испытываете проблемы, получающие доступ к адресам I/O, не исправленным этой процедурой, свяжитесь с Технической поддержкой Разработчика Apple для дополнительной помощи.

Используя ddb для отладки ядра

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

  • драйверы для встроенного оборудования Ethernet

  • обработчики прерываний (аппаратное разнообразие, не потоки обработчика)

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

Когда gdb не практично (или если Вам любопытно), существует второй механизм отладки, который может быть скомпилирован в OS X. Этот механизм вызывают ddb, и подобно kdb отладчик в большей части BSD системы UNIX. Это не совсем столь же просто в использовании как gdb, в основном из-за аппаратных средств должен был использовать его.

В отличие от этого gdb (который использует Ethernet для связи с тупиком ядра), ddb встроен в само ядро и взаимодействует непосредственно с пользователем по последовательной линии. Также в отличие от этого gdb, использование ddb требует создания пользовательского ядра с помощью DEBUG конфигурация. Для получения дополнительной информации о создании этого ядра посмотрите Создание Вашего Первого Ядра.

Если Ваш целевой компьютер имеет два последовательных порта, ddb использует модемный порт (порт SCC 0). Однако, если Ваша цель имеет только один последовательный порт, тот порт, вероятно, присоединен к порту 1 из ячейки SCC, что означает, что необходимо изменить порт по умолчанию, если Вы хотите использовать ddb. Для использования этого порта (порт SCC 1) измените строку:

const int console_unit=0;

в osfmk/ppc/serial_console.c читать:

const int console_unit=1;

и перекомпилируйте ядро.

Как только у Вас есть ядро с ddb поддержка, это относительно просто в использовании. Во-первых, необходимо установить программу эмулятора терминала на узле отладки. Если Ваш узел отладки выполняет Mac OS 9, Вы могли бы использовать ZTerm, например. Для компьютеров OS X, или для компьютерного выполнения Linux или UNIX, minicom обеспечивает хорошую среду. Установка этих программ выходит за рамки этого документа.

Как только Вы загружаете ядро с ddb поддержка, паника позволит Вам заскакивать в отладчик, как будет вызов к PE_enter_debugger. Если DB_KDB флаг не установлен, необходимо будет нажать клавишу D на клавиатуре для использования ddb. Поочередно, если оба DB_KDB и DB_NMI установлены, необходимо быть в состоянии заскочить ddb путем генерации немаскируемого прерывания (NMI). Посмотрите, что Флаги Отладки Установки в Открывают Firmware для получения дополнительной информации о флагах отладки.

Для генерации немаскируемого прерывания удержите команду, опцию, управление и клавиши Shift и поразите Escape (OS X v10.4 и более новый), удержите командную клавишу при нажатии клавиши питания на клавиатуре (на аппаратных средствах с ключом питания) или нажмите кнопку прерывания на целевом компьютере. В этой точке должна зависнуть система, и необходимо видеть ddb вывод на последовательном терминале. Если Вы не делаете, проверьте свою конфигурацию и проверьте указание корректного последовательного порта на обоих компьютерах.

Команды и синтаксис ddb

ddb отладчик намного больше gdb- как, чем предыдущие версии, но это все еще имеет синтаксис, который является очень его собственным (совместно использованный только с другим ddb и kdb отладчики). Поскольку ddb существенно отличается от того, что большинство разработчиков привыкло использовать, этот раздел обрисовывает в общих чертах основные команды и синтаксис.

Команды в ddb обычно находятся в этой форме:

command[/switch] address[,count]

Переключатели могут быть одним из показанных в Таблице 20-2.

  Опции Table 20-2 Switch в ddb

Переключатель

Описание

/A

Распечатайте расположение с номером строки, если это возможно,

/I

Дисплей как инструкция с возможным альтернативным машинно-зависимым форматом

/a

Распечатайте выводимое на экран расположение

/b

Дисплей или процесс байтами

/c

Низкие 8 битов дисплея как символ (непечатаемые символы как восьмеричные) или инструкции количества при выполнении (зависит от инструкции),

/d

Дисплей как подписанное десятичное число

/h

Дисплей или процесс полусловом (16 битов)

/i

Дисплей как инструкция

/l

Дисплей или процесс длинным словом (32 бита)

/m

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

/o

Дисплей в восьмеричном без знака

/p

Распечатайте кумулятивное количество инструкции и вызовите древовидную глубину в каждом вызове или операторе возврата

/r

Дисплей в текущем основании, подписанном

/s

Выведите на экран завершенную нулем строку в адресе (непечатаемый как восьмеричную).

/u

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

/x

Дисплей в шестнадцатеричном числе без знака

/z

Дисплей в шестнадцатеричном числе со знаком

ddb отладчик имеет богатый набор команд, росший в его время жизни. Его набор команд подобен тому из ddb и kdb в других системах BSD и их страницах руководства обеспечивают довольно хорошую ссылку для различных команд. Набор команд для ddb включает следующие команды:

break[/u] addr

Установите точку останова в адресе, указанном addr. Когда точка останова будет достигнута, выполнение остановится. /u переключитесь означает устанавливать точку останова в пространстве пользователя.

c или continue[/c]

Продолжайте выполнение после достижения точки останова. /c переключитесь означает считать инструкции при выполнении.

call

Вызовите функцию.

cond

Точки останова условия набора. Эта команда не поддерживается на PowerPC.

cpu cpunum

Причины ddb переключаться для работы различного CPU.

d или delete [addr|#]

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

dk

Эквивалентный выполнению kextstat в то время как работает целевой компьютер. Это перечисляет загруженный KEXTs, их адреса загрузки и различную соответствующую информацию.

dl vaddr

Выводит диапазон памяти, запускающейся с данного адреса. Параметр vaddr виртуальный адрес ядра. Если vaddr не указан, последний адрес, к которому получают доступ, используется. См. также dr, dv.

dm

К дисплеям, отображающим информацию для последнего адреса, получают доступ.

dmacro name

Удалите вызванный макрос name. Посмотрите macro.

dp

Выводит на экран таблицу в настоящее время активной страницы.

dr addr

Выводит диапазон памяти, запускающейся с данного адреса. Параметр address физический адрес. Если addr не указан, последний адрес, к которому получают доступ, используется. См. также dl, dv.

ds

Дампы сохраняют области всех задач Маха.

dv [addr [vsid]]

Выводит диапазон памяти, запускающейся с данного адреса. Параметр addr виртуальный адрес в адресном пространстве, обозначенном vsid. Если addr не указан, последний адрес, к которому получают доступ, используется. Точно так же, если vsid не указан, последнее vsid используется. См. также dl, dr.

dwatch addr

Удалите контрольную точку. Посмотрите watch.

dx

Дисплеи регистры CPU.

examine

Посмотрите print.

gdb

Переключатели к gdb режим, позволяя gdb присоединить к компьютеру.

lt

На PowerPC только: Выводит таблицу трассировки исключения PowerPC.

macro name command [ ; command .. ]

Создайте вызванный макрос name это выполняет перечисленные команды. Можно показать макрос с командой show macro name или удалите его с dmacro name.

match[/p]

Остановитесь в соответствующей инструкции возврата. Если /p переключатель не указан, сводная информация распечатана только при заключительном возврате.

print[/AIabcdhilmorsuxz] addr1 [addr2 ...]

Распечатайте значения в адресах, данных в формате, указанном переключателем. Если никакой переключатель не дан, последний используемый переключатель принят. Синонимичный с examine и x. Обратите внимание на то, что некоторые перечисленные переключатели могут работать на examine а не для print.

reboot

Перезагружает компьютер. Сразу. Не делая никакой файловой системы размонтировался или другая очистка. Не делайте этого кроме после паники.

s или step

Единственный шаг через инструкции.

search[/bhl] addr value [mask[,count]]

Поисковая память для value запуск в addr. Если значение не найдено, эта команда может нанести ущерб. Эта команда может принять другие значения форматирования в дополнение к перечисленным.

set $name [=] expr

Устанавливает значение переменной или регистра, названного name к значению, обозначенному expr.

show

Данные системы отображения. Для списка информации, которая может быть показана, введите show команда отдельно. Некоторые дополнительные опции доступны для определенных опций, особенно show all. Для тех подопций ввести show all отдельно.

trace[/u]

Распечатывает след штабеля. Если /u флаг указан, отслеживание стека расширяется на пространство пользователя, если поддерживается архитектурно-зависимым кодом.

until[/p]

Остановитесь в следующем вызове или возврате.

w или write[/bhl] addr expr1 [expr2 ... ]

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

watch addr[,size]

Устанавливает контрольную точку на определенном адресе. Когда значение, сохраненное в том адресе, изменяется, выполнение останавливается. Контрольные точки не поддерживаются на PowerPC.

Предупреждение адресов Наблюдения в соединенной проводом памяти ядра может вызвать неисправимые ошибки на i386.

x

Короткий для examine. Посмотрите print.

xb

Исследуйте назад. Выполнитесь последние исследуют команду, но используют адрес до последнего используемого (переход назад инкрементами последней выведенной на экран ширины).

xf

Исследуйте вперед. Выполните последнее examine команда, но использование адрес после последнего используемого (переход инкрементами последней выведенной на экран ширины).

ddb отладчик должен казаться относительно знакомым пользователям gdb, и его синтаксис был изменен радикально от его предшественника, kdb, быть больше gdb- как. Однако это все еще достаточно отличается, что необходимо не торопиться для ознакомления себя с его использованием прежде, чем попытаться отладить что-то с ним. Намного проще использовать ddb в системе, память которой не была набросана на ошибочным запросом DMA, например.