Für Bildungszwecke habe ich diesen Bootloader von mikeos.berlios.de/write-your-own-os.html umgeschrieben, um es speziell an Adresse 0x7c00 zu laden.Wie geht man beim Debuggen eines Bootloaders/BIOS mit gdb und QEMU über Interrupt-Aufrufe?
Der letzte Code ist dies:
[BITS 16] ; Tells nasm to build 16 bits code
[ORG 0x7C00] ; The address the code will start
start:
mov ax, 0 ; Reserves 4Kbytes after the bootloader
add ax, 288 ; (4096 + 512)/ 16 bytes per paragraph
mov ss, ax
mov sp, 4096
mov ax, 0 ; Sets the data segment
mov ds, ax
mov si, texto ; Sets the text position
call imprime ; Calls the printing routine
jmp $ ; Infinite loop
texto db 'It works! :-D', 0
imprime: ; Prints the text on screen
mov ah, 0Eh ; int 10h - printing function
.repeat:
lodsb ; Grabs one char
cmp al, 0
je .done ; If char is zero, ends
int 10h ; Else prints char
jmp .repeat
.done:
ret
times 510-($-$$) db 0 ; Fills the remaining boot sector with 0s
dw 0xAA55 ; Standard boot signature
ich durch das Programm Schritt und sehen, die Register zu ändern, zusammen mit dem Befehl ausgeführt wird, mit gdb Schritt (si) und Inspektion mit QEMU überwachen (info Register , x/i $ eip, usw.).
Nachdem ich in Int 10h (die BIOS-Druckroutine) komme, werden die Dinge ein bisschen seltsam. Wenn ich 500 Anweisungen auf einmal mache, kann ich das Zeichen "I" (das erste Zeichen meiner Zeichenkette) auf dem Bildschirm sehen. Also habe ich wieder angefangen und bin 400 Schritte gegangen (si 400) und dann habe ich einen Schritt nach dem anderen gemacht, um zu sehen, in welchem genauen Schritt "I" gedruckt wurde. Es ist nie passiert. Ich ging tatsächlich 200 Schritte nacheinander und nichts passierte. Sobald ich 100 Schritte gleichzeitig gegangen bin (si 100), habe ich wieder "Ich" auf den Bildschirm gedruckt.
Also, ich frage mich, ob es ein Timing-Problem (einige System-Interrupt kommt in die Quere, wie ich ein Debugging Schritt für Schritt). Was könnte das noch sein?
Wie auch immer, gibt es eine Möglichkeit, den gesamten BIOS-Interrupt und andere Funktionen zu überspringen und einfach den Bootloader-Code zu ändern? Wie von Peter Quiring in den Kommentaren vorgeschlagen, habe ich versucht, nächste. Das hat nicht funktioniert.
(gdb) next
Cannot find bounds of current function
Also versuchte ich nexti und es verhält sich einfach wie si.
Danke!
Vielleicht funktioniert die qemu Bildschirmaktualisierung anders, wenn Sie Einzelschritt sind. – Jester
Warum nicht 'next' statt 'step'ing in den Interrupt verwenden? 'next' erlaubt den Interrupt zu beenden und dann die App an der Zeile nach dem Int 10h –
Umm, ist nicht das erste Zeichen Ihrer Textzeichenfolge (wie angegeben) ... 'I'? (nicht 'F'?), und zweiten Char ist 't', (nicht 'I'?) Warum 500,400,200 ... Schritte in das BIOS gibt unterschiedliche Ergebnisse, habe keine Ahnung. Sofern Sie nicht neugierig sind, würde ich das Debuggen der BIOS-Routinen überspringen und die Tatsache genießen, dass Ihr Boot-Sektor ordnungsgemäß läuft. Seien Sie vorsichtig, dass die 'int 10h'-Aufrufe Ihr' SI'-Register nicht beschädigen, vielleicht ein Push/Pop, der den 'int 10h' umgibt? – lornix