Создание и отладка ядер
Эта глава не о создании расширений ядра (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.
Символьное имя |
Флаг |
Значение |
---|---|---|
|
0x01 |
Останов во время начальной загрузки и ожидает присоединения отладчика ( |
|
0x02 |
Отправьте отладку ядра |
|
0x04 |
Заскочите в отладчик на NMI (Питание команды, Escape Сдвига Управления Опции Команды, или прервите переключатель). |
|
0x08 |
Отправьте отладку ядра |
|
0x10 |
Сделать |
|
0x20 |
Выведите определенную диагностическую информацию к системному журналу. |
|
0x40 |
Позвольте отладчик ARP, и маршрут (позволяет отлаживать через маршрутизаторы и устраняет необходимость постоянной записи ARP, но потенциальная дыра в системе безопасности) — не доступный во всех ядрах. |
|
0x80 |
Поддерживайте старые версии |
|
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.
Переключатель |
Описание |
---|---|
|
Распечатайте расположение с номером строки, если это возможно, |
|
Дисплей как инструкция с возможным альтернативным машинно-зависимым форматом |
|
Распечатайте выводимое на экран расположение |
|
Дисплей или процесс байтами |
|
Низкие 8 битов дисплея как символ (непечатаемые символы как восьмеричные) или инструкции количества при выполнении (зависит от инструкции), |
|
Дисплей как подписанное десятичное число |
|
Дисплей или процесс полусловом (16 битов) |
|
Дисплей как инструкция |
|
Дисплей или процесс длинным словом (32 бита) |
|
Дисплей как шестнадцатеричное число без знака с символьным дампом для каждой строки |
|
Дисплей в восьмеричном без знака |
|
Распечатайте кумулятивное количество инструкции и вызовите древовидную глубину в каждом вызове или операторе возврата |
|
Дисплей в текущем основании, подписанном |
|
Выведите на экран завершенную нулем строку в адресе (непечатаемый как восьмеричную). |
|
Дисплей в десятичном без знака или набор устанавливает контрольные точки в адресе пространства пользователя (в зависимости от команды). |
|
Дисплей в шестнадцатеричном числе без знака |
|
Дисплей в шестнадцатеричном числе со знаком |
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.
x
Короткий для
examine
. Посмотритеprint
.xb
Исследуйте назад. Выполнитесь последние исследуют команду, но используют адрес до последнего используемого (переход назад инкрементами последней выведенной на экран ширины).
xf
Исследуйте вперед. Выполните последнее
examine
команда, но использование адрес после последнего используемого (переход инкрементами последней выведенной на экран ширины).
ddb
отладчик должен казаться относительно знакомым пользователям gdb
, и его синтаксис был изменен радикально от его предшественника, kdb
, быть больше gdb
- как. Однако это все еще достаточно отличается, что необходимо не торопиться для ознакомления себя с его использованием прежде, чем попытаться отладить что-то с ним. Намного проще использовать ddb
в системе, память которой не была набросана на ошибочным запросом DMA, например.