http://3zanders.co.uk/2017/10/13/writing-a-bootloader/
Uses NASM and QEMU to write a bootloader.
https://qemu-project.gitlab.io/qemu/system/gdb.html
https://www.bitdegree.org/learn/gdb-debugger#running-the-program-slowly
To use Qemu with GDB use -s and -S. This set it listening at port 1234 and halt the VM until gdb connects.
qemu-system-i386 -s -S -drive file=./boot.bin,cache=none,format=raw
In GDB
connect to qemu
target remote localhost:1234
- Use
info reg
to display all the CPU registers. - Use
x/10i $eip
to display the code at the PC position. - Use
set architecture i8086
to dump 16 bit code. - set tdesc filename target.xml
- x/10i $cs*16+$eip to dump the next 10 lines of code at the PC position
- stepi
https://visualgdb.com/gdbreference/commands/x
To see the disassembled line
gdb) show disassemble-next-line
Debugger's willingness to use disassemble-next-line is off.
(gdb) set disassemble-next-line on
then si
Machine boots
info reg - show registers
cs = 0xf000 (1048560)
ip = 0xfff0
pc = (cs * 16) + ip
= F0000 + FFF0
= FFFF0 (1048560)
This is 16 bytes from BIOS top (at 1048575 or 0xFFFFF)
https://www.programmersought.com/article/33296090366/
Inspecting the program at FFFF0:
x/16b 0xffff0
xffff0: 0xea 0x5b 0xe0 0x00 0xf0 0x30 0x36 0x2f
0xffff8: 0x32 0x33 0x2f 0x39 0x39 0x00 0xfc 0x00
or looking at the instructions
x/2i 0xffff0
0xffff0: ljmp $0x3630,$0xf000e05b
which shows that 0xEA is JMP
https://www.felixcloutier.com/x86/jmp
However the interetation
is a bug because the VM is running in real mode and GDB does not handle it properly, even though we s
et architecture i8086https://stackoverflow.com/questions/59078290/memory-addressing-in-x86-real-mode?noredirect=1&lq=1
set tdesc filename target.xml
Now running it again gives
0xffff0: ljmp $0xf000,$0xe05b
0xffff5: xor %dh,0x322f
0xffff9: xor (%bx),%bp
0xffffb: cmp %di,(%bx,%di)
0xffffd: add %bh,%ah
0xfffff: add %al,(%bx,%si)
0x100001: add %al,(%bx,%si)
0x100003: add %al,(%bx,%si)
0x100005: add %al,(%bx,%si)
0x100007: add %al,(%bx,%si)
Now gives us
(0xf000 x 16) + 0xe05b = F0000 + 0xe05b = FE05B = (1040475)
This jumps us to FE05B
This is 1FA4 (8100) bytes from BIOS top (at 1048575 or 0xFFFFF)
Run stepi (execute instruction)
0xfe05b: cmpl $0x0,%cs:0x62c8
0xfe062: jne 0xfd0b0
0xfe066: xor %dx,%dx
0xfe068: mov %dx,%ss
0xfe06a: mov $0x7000,%esp
0xfe070: mov $0xf07c4,%edx
0xfe076: jmp 0xfcf24
0xfe079: push %ebp
0xfe07b: push %edi
0xfe07d: push %esi
Reference for x386:
http://ref.x86asm.net/coder32.html
Visual chart on the Opcodes: https://i.stack.imgur.com/VTxd0.jpg
Good Reference to the opcodes