Ядро Linux периодически ломается, иногда это происходит на стадии загрузки. Одним из методов исследования проблемы является удаленная отладка с использованием последовательного порта.
Опции конфигурации ядра должны быть такими:
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
Кроме того, драйвер последовательного порта должен быть включен в состояние
Y.
Далее нам понадобятся отладочные символы и исходные коды ядра, которые находятся в пакетах
-debuginfo и
-debugsource. Скорее всего, архитектуры удаленной и локальной системы не будут совпадать, так как особенно часто ядро Linux не работает на архитектуре armv7l, поэтому просто распакуем данные следующим образом:
> rpm2cpio kernel-default-base-debuginfo-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id
> rpm2cpio kernel-default-debuginfo-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id
> rpm2cpio kernel-default-debugsource-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id
В текущей директории будет создана поддиректория
/usr содержащая отладочные символы и исходные коды в стандартной иерархии. Кроме того, нам понадобятся сами бинарные файлы ядра:
> rpm2cpio kernel-default-base-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id
> rpm2cpio kernel-default-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id
Далее, следует подключить последовательный порт, и открыть удаленную консоль следующим, например, образом:
> screen /dev/ttyUSB0 115200
и начать загрузку целевого устройства. Для активации механизма
kgdb потребуется добавить параметры командной строки ядра в загрузчике:
U-Boot# setenv append "kgdboc=ttyO0,115200 kgdbwait"
U-Boot# boot
Если все пойдет правильно, то загрузка ядра остановится после примерно следующих строк:
[ 3.753423] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 154, base_baud = 3000000) is a OMAP UART0
[ 4.497783] console [ttyO0] enabled
[ 4.502387] STMicroelectronics ASC driver initialized
[ 4.507960] KGDB: Registered I/O driver kgdboc
[ 4.512673] KGDB: Waiting for connection from remote gdb...
Entering kdb (current=0xdb0b3480, pid 1) on processor 0 due to Keyboard Entry
[0]kdb>
kdb ождает ввода команд, среди прочего доступна команда
help, выводящая список базовых команд. На этом консоль можно закрыть:
Ctrl-A :quit и открыть отладчик
gdb.
Для начала установим пути к отладочным символам и исходным кодам и загрузим объектный файл ядра целевой системы (внимание, сначала этот файл нужно будет распаковать командой
gz).
(gdb) set debug-file-directory /tmp/dbg/usr/lib/debug
(gdb) directory /tmp/dbg/usr/src/debug/kernel-default-4.2.rc4/linux-4.2-rc4/linux-obj
(gdb) file /tmp/dbg/boot/vmlinux-4.2.0-rc4-1.gaf243bc-default
Reading symbols from /tmp/dbg/boot/vmlinux-4.2.0-rc4-1.gaf243bc-default...Reading symbols from /tmp/dbg/usr/lib/debug/boot/vmlinux-4.2.0-rc4-1.gaf243bc-default.debug...done.
done.
После этого нужно подключиться к целевой системе:
(gdb) target remote /dev/ttyUSB0
Remote debugging using /dev/ttyUSB0
0xc031dc08 in arch_kgdb_breakpoint () at ../arch/arm/include/asm/outercache.h:142
Далее можно использовать отладчик как обычно. Через команду
monitor доступны все команды из консоли kdb, среди них есть достаточно полезные, например
dmesg или
lsmod:
(gdb) monitor lsmod
Module Size modstruct Used by
musb_am335x 1431 0xbf000278 1 (Loading) 0xbf000000 [ ]
Обратите внимание, что команда
lsmod любезно нам показывает адрес
0xbf000000, куда в памяти загружен модуль
musb_am335x. Этот адрес нужен чтобы отлаживать код из модуля:
(gdb) add-symbol-file /tmp/dbg/lib/modules/4.2.0-rc4-1.gaf243bc-default/kernel/drivers/usb/musb/musb_am335x.ko 0xbf000000