Se il tuo kernel non funziona correttamente, Easyboot ti aiuterà di default a visualizzare i dettagli su cosa e dove è andato storto.
Questo è sufficiente per darti un indizio, ma non ti consente di investigare in modo interattivo. Per quello, avresti bisogno di un debugger.
Vantaggi:
Svantaggi:
Per abilitare il Mini Debugger, basta installare il plugin Easyboot copiando
il file minidbg_(arch).plg
appropriato nella partizione di avvio. Tutto qui. Fornisce un'interfaccia video terminale su linea
seriale (con 115200 baud, 8 bit di dati, 1 bit di stop, nessuna parità).
Su hardware reale, collegare un terminale VT100 o VT220, o un altro computer tramite cavo seriale che esegua PuTTY (Windows) o minicom (Linux).
Per le macchine virtuali, esegui semplicemente qemu con gli argomenti -serial stdio
e sarai in grado di controllare il debugger
dalla stessa finestra che hai usato per eseguire qemu. Ad esempio:
qemu-system-x86_64 -serial stdio -hda disk.img
Ogni volta che il tuo kernel salta, riceverai immediatamente un prompt del debugger e sarai in grado di esaminare la situazione.
Nel prompt del debugger, digita ?
o h
per ottenere aiuto. Per richiamare esplicitamente il debugger, inserisci int 3
(un
byte 0xCC) nel tuo codice. Suggerisco di aggiungere la seguente definizione al tuo kernel:
/* x86 */
#define breakpoint __asm__ __volatile__("int $3")
/* ARM */
#define breakpoint __asm__ __volatile__("brk #0")
Mini debugger by bzt
Exception 03: Breakpoint instruction, code 0
rax: 0000000000000000 rbx: 00000000000206C0 rcx: 000000000000270F
rdx: 00000000000003F8 rsi: 00000000000001B0 rdi: 0000000000102336
rsp: 000000000008FFB8 rbp: 000000000008FFF8 r8: 0000000000000004
r9: 0000000000000002 r10: 0000000000000000 r11: 0000000000000003
r12: 0000000000000000 r13: 0000000000000000 r14: 0000000000000000
r15: 0000000000000000
> ?
Mini debugger commands:
?/h this help
c continue execution
n move to the next instruction
r dump registers
x [os [oe]] examine memory from offset start (os) to offset end (oe)
i [os [oe]] disassemble instructions from offset start to offset end
> i pc-1 pc+4
00101601: CC int 3
00101602: FA cli
00101603: F4 hlt
00101604: EB FC jmp 101602h
00101606: 90 1 x nop
>
Vantaggi:
Svantaggi:
Quando la macchina virtuale è in esecuzione, dal menu seleziona View
> compatmonitor0
, oppure fai clic sulla finestra in modo
che catturi il focus e premi Ctrl+Alt+2 (per rilasciare il focus premi
Ctrl+Alt+G).
Vantaggi:
Svantaggi:
Prima di fare qualsiasi cosa, modifica il tuo ambiente di compilazione per generare due file kernel. Uno con i simboli di debug e
uno senza. Questo è importante perché i simboli di debug possono facilmente occupare molto spazio, probabilmente diversi megabyte.
Per prima cosa, compila il tuo kernel con il flag -g
. Quindi, una volta completata la compilazione, copia il tuo kernel
cp mykernel.elf mykernel_sym.elf
e rimuovi le informazioni di debug con strip mykernel.elf
. In seguito, avvierai mykernel.elf
e fornirai mykernel_sym.elf
a gdb.
Successivamente, crea uno script gdb denominato gdb.rc
. Utilizza quanto segue come modello:
target remote localhost:1234
set architecture i386:x86-64
symbol-file mykernel_sym.elf
layout split
layout src
layout regs
break *_start
continue
Ciò collega gdb alla macchina virtuale, le comunica il tipo di macchina, carica le informazioni di debug, configura il layout, imposta un punto di interruzione proprio nel punto di ingresso del kernel e infine avvia la macchina virtuale.
Una volta completata questa configurazione, puoi iniziare il debug. Una sessione di debug funziona così: in un terminale, avvia
qemu con i flag -s -S
. Si bloccherà. Ad esempio:
qemu-system-x86_64 -s -S -hda disk.img
Quindi, in un altro terminale, avviamo gdb con lo script che abbiamo creato in precedenza:
gdb -w -x gdb.rc
Questo dovrebbe visualizzare tutto in una finestra come questa:
Se sei arrivato fin qui, congratulazioni, puoi iniziare il vero lavoro con il tuo kernel!