Отладка ядра Android

Я экспериментировал с получением kgdb для работы Nexus One.

Я вытащил ядро ​​из https://android.googlesource.com и включил все, что связано с kgdb, включая тестирование kgdbts, используя menuconfig, Успешно построил ядро ​​и высветил его на устройстве (которое разблокировано и запущено CyanogenMod 7)

Я также выполнил инструкции, найденные в http://bootloader.wikidot.com/android:kgdb, чтобы включить соединение usb как последовательное соединение, как требуется kgdb (и проверена связь от ttyACM0 до ttyGS0 успешно).

Существуют следующие папки, указывающие, что kgdboc и kgdbts были встроены в ядро:

/sys/modules/kgdboc/parameters
/sys/modules/kgdbts/parameters

Ниже представлен результат dmesg, показывающий, что тестирование kgdbts выполняется, показывает, что (я думаю) является успешным завершением тестов:

# dmesg | grep kgdb
<6>[   12.974060] kgdb: Registered I/O driver kgdbts.
<6>[   12.981781] kgdbts:RUN plant and detach test
<6>[   12.995178] kgdbts:RUN sw breakpoint test
<6>[   13.002441] kgdbts:RUN bad memory access test
<6>[   13.010864] kgdbts:RUN singlestep test 1000 iterations
<6>[   13.019042] kgdbts:RUN singlestep [0/1000]
<6>[   13.077850] kgdbts:RUN singlestep [100/1000]
<6>[   13.132720] kgdbts:RUN singlestep [200/1000]
<6>[   13.187500] kgdbts:RUN singlestep [300/1000]
<6>[   13.242370] kgdbts:RUN singlestep [400/1000]
<6>[   13.297149] kgdbts:RUN singlestep [500/1000]
<6>[   13.351928] kgdbts:RUN singlestep [600/1000]
<6>[   13.406829] kgdbts:RUN singlestep [700/1000]
<6>[   13.461578] kgdbts:RUN singlestep [800/1000]
<6>[   13.516540] kgdbts:RUN singlestep [900/1000]
<6>[   13.570922] kgdbts:RUN do_fork for 100 breakpoints
<6>[   21.117645] kgdb: Unregistered I/O driver kgdbts, debugger disabled.

Я считаю, что проблема, с которой я сталкиваюсь, - заставить ядро ​​запускать kgdb.

# echo -n g > /proc/sysrq-trigger

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

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

(gdb) target remote /dev/ttyACM0

И подключитесь к сеансу отладки с ядром.

Я также протестировал /proc/sysrq-trigger с помощью b и c только для подтверждения того, что я могу передать некоторые команды sysrq.

Итак, мой вопрос, следуя моей длительной попытке предоставить как можно больше информации, является причиной того, что g не запускает отладчик?

Это моя первая попытка отладки ядра в любой системе, и у меня не было возможности рассказать о моем поиске в google, поэтому я обращаюсь к вам. Спасибо!

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

Ответ 1

Вопросы ядра ядра Android редко встречаются на [SO], поскольку никто другой не ответил. Я представил свои выводы по этому вопросу. К сожалению, у меня нет связи, чтобы проверить это, поэтому этот ответ не предназначен как пошаговое разрешение вашей проблемы, а должен указывать вам в правильном направлении, где искать.

Единственный полезный ресурс, который я нашел в этой проблеме, - это LKML-патч от Dongdong Deng, так что вряд ли это проблема конфигурации, поскольку они обычно обильны и хорошо -publicized.

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

В противном случае попробуйте сообщить об этом команде cyanogen и посмотрите, является ли это известной проблемой или имеет простой способ обхода.

В качестве последнего средства вы можете попробовать патч, если версии совместимы. Единственная альтернатива - свернуть рукава и начать взламывать ядро ​​CM, чтобы включить патч.

Удачи.

Ответ 2

У меня нет опыта работы с аппаратным обеспечением Android, но я выполнил скомпилированное ядро ​​kgdb, запущенное как клиент VirtualBox, и с хоста подключился к гостю через виртуальный последовательный порт и с помощью gdb (со стандартной командой "target remote" ) Я могу пройти через всю загрузку виртуального гостевого ядра - с помощью kgdbwait. Без этого я могу написать модуль ядра, который ничего не делает, кроме как реализовать встроенную сборку, которая называется "int 13", которая равна 0xcc. После загрузки точка останова будет отображаться на стороне хоста последовательного соединения, а затем я могу установить точку останова и продолжить изъятие ядра. Это работает, потому что kgdb обрабатывает исключение "int 13". Если u явно создает другое исключение типа "* p = 0", а p указывает на NULL, u все равно получит точку останова, но я сомневаюсь, что u может продолжить выполнение.

Ответ 3

Нашел этот пост из связанного сообщения и хотел сказать, что я только что опубликовал некоторую работу, которую я сделал, чтобы заставить это работать на Nexus 6, если кому-то интересно:

http://www.contextis.com/resources/blog/kgdb-android-debugging-kernel-boss/

Интересно, что проблема OP с sysrq была одной из тех, с которыми я столкнулся. Причина такого поведения заключается в том, что KGDB не инициализировался правильно, поэтому он не смог установить обработчик для триггера "g" (kgdb). Вот почему все остальные команды sysrq все еще работают.

Более длинное объяснение (спасибо @Robert):

Чтобы получить эту работу, мне пришлось сделать отладочный кабель UART на основе этого блога Accuvant. Это довольно простая схема, которая состоит из основного прорыва FTDI 3.3v (доступного от SparkFun на момент написания), а также 4 резистора (2 x 1K Ом, 1 x 1.2K Ом и 1 x 100 Ом) и 4-элементное гнездо для наушников Tip-Ring-Sleeve (TRRS). Резисторы по существу обеспечивают делитель напряжения, чтобы уменьшить 3,3 В до чего-то более безопасного для вашего телефона. Вставив аудиоразъем с другим концом, подключенным к вашей монтажной плате, аудиоподсистема распознает, что напряжение (~ 2,8 В) на одном из контактов, и он знает, чтобы обеспечить интерфейс UART через этот кабель. Разрыв FTDI подключается к компьютеру через USB, и отсюда вы можете получить доступ к консольным сообщениям через эмулятор терминала, например, миникомпьютер. Однако теперь у вас есть последовательный интерфейс через тот же механизм и что мы можем использовать для подключения KGDB.

Итак, в этот момент требуются относительно небольшие изменения для последовательного драйвера Nexus 6 (msm_serial_hs_lite.c) для поддержки KGDB (в частности, возможность выполнять операции ввода-вывода с использованием атомного символа). Я просто портировал эти изменения из основного кода ядра Linux, так как глава под названием Stephen Boyd проделал большую работу с полным серийным драйвером MSM (Qualcomm) msm_serial.c. Его изменения могут быть найдены здесь или просто искать "msm_serial: добавить поддержку poll_" в Google. Порт не был сложным, и мой код может быть найден на github.

Кроме того, вы должны иметь возможность создавать собственное ядро ​​для вашего N6, которое google предоставляет много информации о. Затем вам необходимо создать загрузочный образ, содержащий модификации KGDB в репозитории github. Я взял исходное ядро ​​из https://developers.google.com/android/nexus/images, извлек его (используя abootimg -x), а затем использовал следующую команду, чтобы переупаковать его с помощью моего пользовательского kernel (zImage-dtb) и дополнительные параметры командной строки для обеспечения загрузки KGDB и указания на мой последовательный порт следующим образом:

abootimg -u boot.img -k zImage-dtb -c 'cmdline=console=ttyHSL0,115200,n8 kgdboc=ttyHSL0,115200 kgdbretry=4'

С созданным boot.img я мог бы загрузиться в него с помощью команды fastboot boot boot.img, открыть оболочку adb, а затем запустить контрольную точку в ядре Android с помощью команды:

echo -n g > /proc/sysrq-trigger

Следует отметить, что для полноты вам нужны привилегии суперпользователя для доступа /proc/sysrq -trigger, поэтому вам нужно иметь root.

При остановленном телефоне и подключенном кабель отладки запустите версию GDB для ARM на вашем ПК с несжатым ядром в качестве аргумента (например, arm-eabi-gdb./vmlinux). Примечание. Я запускаю Ubuntu 14.04 и использую arm-eabi-gdb из каталога prebuilts в моем исходном репозитории AOSP. Наконец, введите следующие команды:

set remoteflow off
set remotebaud 115200
target remote /dev/ttyUSB0

Все должно быть хорошо, это должно немедленно прорваться в точку останова kgdb (чтобы ваша запись выполнялась в /proc/sysrq -trigger), и вы можете начать отладку.