qemu + gdb debug notas de estudio del kernel de linux

Reimpreso

Declaración:

  El contenido de esta nota no es original, el 90% proviene de la integración de materiales en línea. Al mismo tiempo, debido a que acabo de estar en contacto con la depuración remota de qemu & gdbserver, este artículo no es un tutorial, es solo para referencia de familiares.

-------------------------------------------------- ---------------------------------------------- Línea divisoria-- -------------------------------------------------- -----------------------

Paso 1: instalación del entorno de compilación del núcleo

  

apt-cache search build-essential 
sudo apt-get install build-essential -y 

apt-cache search libncurses-dev 
sudo apt-get install libncurses-dev -y

Por supuesto, se pueden necesitar algunas otras herramientas. Si herramientas como gcc g ++ hacen, después de todo, build-essential es una caja de herramientas. Si hay limpieza, puede haber un pequeño conflicto. Para ncurses-dev, esto es imprescindible. Recuerdo yum directamente instalar ncurses-dev en fedora. La serie .deb parece estar prefijada.

 

paso 2: instalación de gdb

  Lo que hay que decir es que se debe incluir una herramienta gdb & gdbsever en build-essential, pero lamento que no se pueda usar y se producirá este error:

    

Código de copia

La respuesta remota del paquete 'g' es demasiado larga:000000000000000020000000000000004000000000000000001006000000000000f009000000000028aece81ffffffff981fc081ffffffff901fc081ffffffff0030c1010000000000000000000000000000000000000000f0b926020000000020f1d281ffffffffb01fc081ffffffff00e0e681ffffffff0010e781ffffffff02fbd281ffffffff9600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080lfa0000

Código de copia

  Entonces, necesitamos descargar una fuente de gdb relativamente nueva (usé 7.8), la URL es:  http://ftp.gnu.org/gnu/gdb/

  

http://ftp.gnu.org/gnu/gdb/

  Luego, modifique el código fuente de gdb de acuerdo con la información compartida por las personas frente a la red: modifique los contenidos de la función de proceso vacío vacío_g_packet (struct regcache * regcache) en el archivo gdb-7.8 / gdb / remote.c de la siguiente manera:

Código de copia

1 vacío estático 
 2 process_g_packet (struct regcache * regcache) 
 3 { 
 4 struct gdbarch * gdbarch = get_regcache_arch (regcache); 
 5 struct remote_state * rs = get_remote_state (); 
 6 struct remote_arch_state * rsa = get_remote_arch_state (); 
 7 int i, buf_len; 
 8 char * p; 
 9 caracteres * regs; 
10 
11 buf_len = strlen (rs-> buf); 
12 
13 / * Más controles de cordura, con conocimiento de la arquitectura. * / 
14 / * if (buf_len> 2 * rsa-> sizeof_g_packet) 
15 error (_ ("La respuesta remota del paquete 'g' es demasiado larga:% s"), rs-> buf); 
16 * / 
17 / * modificar por xx * /  
18 if (buf_len> 2 * rsa-> sizeof_g_packet) {
19 rsa-> sizeof_g_packet = buf_len;
20 para (i = 0; i <gdbarch_num_regs (gdbarch); i ++) { 
21 if (rsa-> regs [i] .pnum == -1)     
22 continuar; 
23 if (rsa-> regs [i] .offset> = rsa-> sizeof_g_packet) 
24 rsa-> regs [i] .in_g_packet = 0; 
25 más 
26 rsa-> regs [i] .in_g_packet = 1; 
27} 
28} 
29 // ....... 
30} 
31} 
32}

Código de copia

  Las líneas 14-15 anteriores son del archivo original y las líneas 18-27 se vuelven a agregar. <Para guardar el diseño, no pegué la parte posterior, así que preste atención a los errores de sintaxis que pueden resultar de "{}"> El principio no está claro para mí, pero resuelve el problema.

  Una vez completada la modificación, comience a compilar gdb. Ejecute el siguiente comando en gdb-7.8 /:

1 ./configure --prefix = .. / .. / tools / 
2 make 
3 make install

  Cabe señalar que no hay Makefile en el directorio gdb-7.8 /, debe usar ./configure para producir. Durante la configuración, si desea especificar la ruta (directorio) de la instalación de gdb, debe mantenerse al día con los parámetros relevantes de --prefix = $ PATH. En general, esta situación puede ser para el sistema que ya tiene un gdb pero no se puede usar. No eliminado, entonces el gdb recién compilado puede necesitar ser instalado en otro directorio. Por supuesto, el mío está instalado en el directorio ../../tools/.

 

Paso 3: compilar el kernel de Linux

  Vaya a www.kernel.org para descargar la versión que necesita y, una vez completado, compile el núcleo para generar archivos bzImage y vmlinux. Si recién está comenzando como yo, puede consultar los siguientes comandos y pasos:

  

cd linux-3.12.35 / 
cp /boot/config-3.13.0-43-generic .config 
make menuconfig 
<save> 
make bzImage

  Cabe señalar que la información de depuración específica depende de la configuración, selección y compilación después de hacer menuconfig. Después de la compilación, la máquina virtual qemu comprime y utiliza bzImage. Parte de la información se incluye en vmlinux. No hay compresión y gdb la utiliza.

  Cuando se completa la compilación, puede copiar el archivo vmlinux bzImage en un directorio limpio; estos son sus propios hábitos, no importa si no copia.

  Olvidé preparar las cosas más importantes anteriores: qemu

Paso 4: uso de qemu

  En pocas palabras: qemu es una máquina virtual que puede simular plataformas de hardware como x86 & arm, etc. <Parece que hay muchas plataformas de hardware que se pueden simular ...>, y qemu también tiene un servidor gdbserver incorporado. El gdbserver puede formar un socio remoto con gdb, y trabajar a través de la red ip: port o a través del puerto serie / dev / ttyS *, uno en este extremo y otro en el otro.

  En cuanto a la instalación de la máquina virtual qemu, se puede compilar a partir del código fuente, make & make install, que se puede descargar aquí: http://wiki.qemu.org/Download . También puede instalar apt-get install qemu-kvm directamente en el paquete ubuntu. No detallado aquí. Cuando está instalado, los archivos posibles son estos:

Código de copia

1 qemu-system-i386 
2 
3 qemu-system-x86_64 
4 
5 qemu-img 
6 
7 qemu-io 
8 ....

Código de copia

  ¿Qué significa esto? La primera línea representa la máquina virtual qemu utilizada en la máquina i386, y la segunda línea representa la máquina virtual utilizada en x86_64. Los otros no han sido utilizados. Para más detalles, consulte el documento oficial del sitio web: http://wiki.qemu.org/Main_Page . Por supuesto, mi propio sistema es x86_64, y se usa el segundo.

 

Paso 4: deja que el kernel te tome un momento ~

  

1 qemu-system-x86_64 -kernel ./bzImage -initrd ./initrd.img -smp 2 -gdb tcp :: 1234 -S

  Inicie qemu con el comando primero.

  Hay muchos parámetros de qemu-system-x86_64, aquí hay una breve introducción:

  -kernel es para especificar un archivo de kernel grande, y es bzImage lo que hará el truco.

  -initrd especifica un archivo initrd.img. Este archivo se puede copiar desde /boot/initrd.img-3.13.0-43-generic. ¿De qué se trata? Puede consultar esto:  http://www.linuxfly.org/post/94/  , o este  http://blog.csdn.net/chrisniu1984/article/details/3907874   .

  -smp puede adivinar por el nombre, es para especificar algunos procesadores para qemu, o algunos hilos <ah, probablemente significa hilo>.

  -gdb es para iniciar el gdbserver incrustado de qemu, escuchando en el puerto tcp local 1234 --- si está escrito así: -gdb tcp: 192.168.1.100: 1234, parece que no hay problema.

  -S es suspender gdbserver y dejar que gdb remote lo conecte. También hay un -s, que es otra situación para usar.

  Si le resulta difícil escribir el comando <aunque eso es genial>, puede usar el siguiente método para guardar el comando en un archivo, como qemu.start:

  

1 #! / Bin / bash 
2 qemu-system-x86_64 -kernel ./bzImage -initrd ./initrd.img -smp 2 -gdb tcp :: 1234 -S 
3 <save> 
4 chmod + x qemu.start 
5 
6. /qemu.start

  Luego puede iniciar qemu <observe la ruta de su archivo bzImage & initrd.img>

  Consejo: man qemu-system-x86_64, obtendrá ayuda.

 

Paso 5: Use gdb para conectar el qemu que se ha iniciado:

  

Código de copia

1 ../tools/gdb/bin/gdb vmlinux 
 2 
 3 ----- 
 4 GNU gdb (GDB) 7.8 
 5 Copyright (C) 2014 Free Software Foundation, Inc. 
 6 Licencia GPLv3 +: GNU GPL versión 3 o posterior <http : //gnu.org/licenses/gpl.html> 
 7 Este es un software gratuito: usted es libre de cambiarlo y redistribuirlo. 
 8 NO HAY GARANTÍA, en la medida permitida por la ley. Escriba "mostrar copia" 
 9 y "mostrar garantía" para obtener más detalles. 
10 Este GDB se configuró como "x86_64-unknown-linux-gnu". 
11 Escriba "show configuration" para obtener detalles de la configuración. 
12 Para obtener instrucciones sobre cómo informar errores, consulte: 
13 <http://www.gnu.org/software/gdb/bugs/>.
15 <http://www.gnu.org/software/gdb/documentation/>. 
16 Para obtener ayuda, escriba "ayuda". 
17 Escriba "apropos word" para buscar comandos relacionados con "word" ... 
18 Lectura de símbolos de vmlinux ... hecho. 
19 ----- 
20 
21 (gdb) control remoto de destino: 1234 
22 Depuración remota usando: 1234 
23 0x0000000000000000 en irq_stack_union () 
24 
25 (gdb) b start_kernel 
26 Punto de interrupción 1 en 0xffffffff81d2fb02: archivo init / main.c, línea 476. 
27 
28 (gdb) c 
29 Continuando. 
30 
31 Punto de interrupción 1, start_kernel () en init / main.c: 476 
32 476 { 
33 
34 
35 (gdb) n 
36 485 smp_setup_processor_id ();
37 (gdb) n 
38491 boot_init_stack_canary ();
39 (gdb) n 
40 493 cgroup_init_early ();

Código de copia

  La primera línea indica que debo iniciar mi propio gdb compilado, hay dos formas: comienza gdb fileName, o después de que comienza gdb, luego use file fileName para comenzar

  La línea 21 indica que el gdbserver remoto está conectado. Dado que está en la misma computadora portátil, no se especifica la dirección IP, solo el número de puerto. ---- Por supuesto, si está conectado al puerto uart, funcionará.

  La línea 25 es para romper un punto de interrupción en la entrada de una función.

  La línea 28 debería ser un comando para permitir que qemu continúe ejecutándose. En este momento, la pantalla de qemu parpadeará: "Arrancando desde ROM ..."

  Detrás, significa el siguiente paso: siguiente ... siguiente ... Por supuesto, también puede elegir el paso paso s ... ¿Hasta dónde se imprimirá el mensaje en qemu? Solo después de console_init (); esta línea de código.

 

  Para hacer una nota ligeramente importante: no he habilitado el sistema de archivos aquí. Si es necesario, puede intentar usar busybox para hacer uno, y luego consultar el manual de depuración del núcleo qemu o los recursos de red para unirse a la depuración.

-------------------------------------------------- ------------------------------------ Línea divisoria sucia ----------- -------------------------------------------------- -------------------------------

Postdata:

  En cuanto a los comandos gdb, hay muchos, muchos, si es nuevo en el núcleo, haga clic aquí:    http://www.sourceware.org/gdb/ Lo    mejor es mordisquear lentamente la documentación oficial del sitio web y luego ver la comprensión de los demás. , Debería ser casi lo mismo. O eche un vistazo a esto:  http://www.yolinux.com/TUTORIALS/GDB-Commands.html

  He estado buscando métodos de depuración del núcleo en estos días, qemu + gdb es una forma, por supuesto, hay otros métodos. Pero para resumir, el costo es el más pequeño con qemu + gdb. Si es una PC de pantalla grande, puede intentar incluir qemu + gdb + eclipse en el entorno IDE. Y si eres un portátil, no haces un IDE, es suficiente debajo del shell vim.

  Un poco de ideas confusas: también leí algunos libros del sistema operativo + lecturas introductorias del kernel de Linux, pero nunca tuve la oportunidad de intentar ejecutar el siguiente kernel paso a paso para ver cómo funciona. <El método de construcción en el libro es relativamente costoso : O dos computadoras, o la que cederás por la mitad>. Con el tiempo, se aflojará, y mucho menos mirará el código en detalle. El kernel de Linux es realmente genial, pero no hay necesidad de mitigarlo. Si tiene un cierto nivel de comprensión de los principios del sistema operativo y el diseño del programa, también puede hacer un sistema operativo completo, aunque puede ser difícil. Por lo tanto, la unidad de conocimiento y acción también es necesaria.

  Finalmente, si está realmente interesado en el núcleo, al menos debe hablar inglés y luego prestar atención a la Lista de correo del núcleo lo antes posible, aunque es inseparable, pero el mundo también está cambiando. El libro tiene un límite de tiempo.

Publicado ocho artículos originales · ganado elogios 0 · Vistas 2874

Supongo que te gusta

Origin blog.csdn.net/skyxiaoyan1/article/details/85008628
Recomendado
Clasificación