2012-07-10 13 views
23

Soy nuevo en el desarrollo de kernel y me gustaría saber cómo ejecutar/depurar el kernel de linux usando QEMU y gdb. De hecho, estoy leyendo el libro de Robert Love, pero desafortunadamente no ayuda al lector sobre cómo instalar las herramientas adecuadas para ejecutar o depurar el kernel ... Entonces, lo que hice fue seguir este tutorial http://opensourceforu.efytimes.com/2011/02/kernel-development-debugging-using-eclipse/. Estoy usando eclipse como un IDE para desarrollar en el kernel, pero primero quería que funcione en QEMU/gdb. Así que lo que hice hasta ahora era:¿Cómo depurar el kernel de Linux con GDB y QEMU?

1) para compilar el kernel con:

make defconfig (then setting the CONFIG_DEBUG_INFO=y in the .config) 
make -j4 

2) Una vez que la compilación ha terminado corro Qemu usando:

qemu-system-x86_64 -s -S /dev/zero -kernel /arch/x86/boot/bzImage 

la que lanzar el núcleo en estado "detenido"

3) por lo tanto tengo que usar gDB, trato el siguiente comando:

gdb ./vmlinux 

que se ejecuta correctamente pero ... Ahora no sé qué hacer ... Sé que tengo que usar la depuración remota en el puerto 1234 (puerto predeterminado utilizado por Qemu), usando el vmlinux como el archivo de tabla de símbolos para la depuración.

Así que mi pregunta es: ¿qué debo hacer para ejecutar el kernel en Qemu, adjuntar mi depurador y así lograr que trabajen juntos para hacer mi vida más fácil con el desarrollo del kernel.

Respuesta

19

que iba a tratar:

(gdb) target remote localhost:1234 
(gdb) continue 

Usando la opción '-s' hace qemu escucha en el puerto TCP :: 1234, que se puede conectar a localhost: 1234 si se encuentra en la misma máquina. La opción '-S' de Qemu hace que Qemu detenga la ejecución hasta que usted dé el comando de continuar.

Lo mejor es, probablemente, echar un vistazo a un tutorial decente de GDB para llevarse bien con lo que está haciendo. This one se ve bastante bien.

+0

Gracias mucho funciona :). Acabo de terminar de leer el libro que trata sobre DDD, eclipse y gdb publicado por la prensa no almidonada, pero no hubo depuración remota en este libro. Mi kernel ahora se está iniciando, pero parece que lleva tiempo cargarlo (ya que Qemu parece usar solo 1 hilo en mi máquina) y ahora está bloqueado en:? kernel_thread_helper + 0x0/0x10. ¿Es la forma en que el kernel se usa para cargar? Quiero decir, ¿no deberíamos tener un símbolo del sistema una vez que está cargado? Gracias –

+0

me funciona. Sin embargo, no sé cómo forzar kernel stop en punto de interrupción después de llamar a la primera continuación. Por ejemplo, pongo un punto de interrupción en la función start_kernel pero nunca se detiene allí. Alguna idea ? – ARH

2

Cuando intenta iniciar vmlinux exe usando GDB, entonces lo primero en GDB es emitir cmds:

(GDB) Objetivo localhost a distancia: 1234

(BGF) ruptura start_kernel

(continuar)

Esto romperá el kernel en start_kernel.

+0

Uso eclipse para depurar kernel run en qemu, y setted stop en start_kernel. Pero aún se ejecuta después de eclipse start debug. He establecido que qemu se detuvo cuando comenzó y usar solo gdb está bien. – Ezio

3

La respuesta de BjoernID en realidad no funcionó para mí. Después de la primera continuación, ningún punto de ruptura se alcanza y por interrupción, me gustaría ver las líneas tales como:

0x0000000000000000 in ??() 
(gdb) break rapl_pmu_init 
Breakpoint 1 at 0xffffffff816631e7 
(gdb) c 
Continuing. 
^CRemote 'g' packet reply is too long: 08793000000000002988d582000000002019[..] 

supongo que esto tiene algo que ver con diferentes modos de CPU (modo real en el modo de larga BIOS cuando vs Linux tiene arrancado). De todos modos, la solución es ejecutar QEMU primera sin esperar (es decir, sin -S):

qemu-system-x86_64 -enable-kvm -kernel arch/x86/boot/bzImage -cpu SandyBridge -s 

En mi caso, tenía que romper algo durante el arranque, así que después de algunas décimas de segundo, me encontré con el comando gdb. Si tiene más tiempo (por ejemplo, necesita depurar un módulo que se carga manualmente), entonces el tiempo realmente no importa.

gdb le permite especificar comandos que se deben ejecutar cuando se inician. Esto hace que la automatización sea un poco más fácil. Para conectar con QEMU (que debe ser ahora ya iniciado), romper en una función y continuar la ejecución, utilice:

gdb -ex 'target remote localhost:1234' -ex 'break rapl_pmu_init' -ex c ./vmlinux 
13

Paso a paso probado procedimiento en Ubuntu 16.10 anfitrión

Para empezar desde cero rápidamente he hecho un mínimo ejemplo totalmente automatizado QEMU + Buildroot en: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/c7bbc6029af7f4fab0a23a380d1607df0b2a3701/gdb-step-debugging.md Major los pasos están cubiertos a continuación.

Primero obtenga un sistema de archivos raíz rootfs.cpio.gz. Si lo necesita, tenga en cuenta:

Luego, en el núcleo de Linux:

git checkout v4.15 
make mrproper 
make x86_64_defconfig 
cat <<EOF >.config-fragment 
CONFIG_DEBUG_INFO=y 
CONFIG_DEBUG_KERNEL=y 
CONFIG_GDB_SCRIPTS=y 
EOF 
./scripts/kconfig/merge_config.sh .config .config-fragment 
make -j"$(nproc)" 
qemu-system-x86_64 -kernel arch/x86/boot/bzImage \ 
        -initrd rootfs.cpio.gz -S -s \ 
        -append nokaslr 

En otra terminal, desde el interior del árbol de kernel de Linux, supongamos que desea iniciar la depuración desde start_kernel:

gdb \ 
    -ex "add-auto-load-safe-path $(pwd)" \ 
    -ex "file vmlinux" \ 
    -ex 'set arch i386:x86-64:intel' \ 
    -ex 'target remote localhost:1234' \ 
    -ex 'break start_kernel' \ 
    -ex 'continue' \ 
    -ex 'disconnect' \ 
    -ex 'set arch i386:x86-64' \ 
    -ex 'target remote localhost:1234' 

y listo !!

Para ver los módulos del núcleo: How to debug Linux kernel modules with QEMU?

Para Ubuntu 14.04, el BGF 7.7.1, se necesitaba hbreak, break puntos de interrupción de software fueron ignorados. Ya no es el caso en 16.10. Ver también: https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944

El desordenado disconnect y lo que viene después de que se han de evitar el error:

Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000 

las discusiones relacionadas:

limitaciones conocidas:

Ver también:

Cuestiones relacionadas