Cómo depurar el kernel usando gdb y bochs
Al compilar Bochs, agregue la opción --enable-gdb-stub:
$ ./configure --enable-gdb-stub
$ make
$ sudo make install
2. Generar kernel
Modificar Makefile
Agregar CFLAGS a la opción -g para incluir Símbolos de depuración
CFLAGS = -I include/ -I include/sys/ -c -g -fno-builtin -Wall
Dado que kernel.bin es demasiado grande después de agregar símbolos de depuración, Por favor, quítelo y cópielo en una imagen de disco
sudo cp -fv kernel.bin /mnt/floppy
Para:
strip kernel.bin - o kernel.bin.stripped
sudo cp -fv kernel.bin.stripped /mnt/floppy/kernel.bin
De esta manera, kernel.bin ejecutado en la máquina virtual de bochs El kernel.bin que se elimina y luego se entrega a gdb tendrá símbolos de depuración.
Compilar kernel
$ crear imagen
3.base=0, bss_base=0
Ejecutar
$ bochs -q -f bochsrc.gdb # Tenga en cuenta que la opción de compilación --enable-gdb-stub debe usarse cuando se usa bochs
4. Use gdb para depurar
Abrir otra Consola y ejecute gdb
$ gdb
Esta es la primera vez que ejecuta gdb. p>$ gdb
Utilice gdb para depurar
archivo (gdb) kernel.bin ← Tenga en cuenta que kernel.bin aquí debe ser un kernel con símbolos de depuración y -g opción de compilación p>
Leer símbolos de /home/forrest/local/ src/osfs/oranges
Utilice la opción de compilación -g para leer kernel.bin src/osfs/oranges/phases/chapter11/a. /kernel.bin...done..done.
(gdb) destino localhost remoto: 1234
Depuración remota usando localhost: 1234
0x0000fff0 en ? ()
(gdb) b start.c: 26
Punto de interrupción 1 en 0x14a6: archivo kernel/start.c, línea 26.
(gdb) c
Continuar. memcpy(&gdt, /* Nuevo GDT */
(gdb)
.gdbinit
porque necesita ejecutar el archivo de comando kernel.bin y el destino localhost remoto: 12:00, por lo que debe ejecutar el comando en el archivo kernel.bin.
bin y target localhost remoto: 1234 comandos, puede crear un archivo .gdbinit, por ejemplo:
$ vi .gdbinit
archivo kernel.bin
target localhost remoto: 1234
establecer intel de sabor de desensamblado
b start.c: 26
b kernel/main.c: 183
De esta manera, la próxima vez que ejecute un comando directamente desde el archivo gdb, el comando se ejecutará automáticamente.
.gdbinit puede hacer muchas cosas, como agregar dos puntos de interrupción en el ejemplo anterior.
Personalizar funciones en .gdbinit
Puedes agregar funciones personalizadas en .gdbinit, por ejemplo:::.....
definir lsproc
set $count = 16
set $idx = 0
printf "Las primeras d TAREAS/PROCESOS:\n",$count p>
while($idx lt; $count)
if(proc_table[$idx].p_flags ! = 0x20)
if($idx lt; 5)
printf "[2d] TAREA: 8s", $idx, proc_table[$idx].nombre
printf "[2d] TAREA: 8s", $idx, proc_table[$idx ].p_flags p>
else
printf "[2d] PROC: 8s", $idx, proc_table[$idx].name
printf "\t p_flags : 8Xh\n" , proc_table[$idx].p_flags<
end
end
set $idx
end p>
end
De esta manera, ejecutar lsproc en gdb imprimirá la información de todos los procesos, lo cual es muy conveniente:
(gdb) lsproc
Primeros 16 TAREA/PROCESO:
[ 0] TAREA: TTY p_flags: 4h
[ 1] TAREA: SYS p_flags: 4h
[ 2] TAREA: HD p_flags : 4h
[ 3] TAREA: FS p_flags: 4h
[ 3] TAREA: FS p_flags: 4h
[ 4] TAREA: MM p_flags: 4h
[ 5] PROC: INIT p_flags: Ch
[ 6] PROC: TestA p_flags: 0h
[ 7] PROC: TestB p_flags: 0h p>
[ 8] PROC: TestC p_flags: 0h
[ 9] PROC: INIT_9 p_flags: 4h
[10] PROC: INIT_10 p_flags: 4h