However Bochs is good for fully debug in OS kernel development without expansive hardware tracer.
Bochs come with prebuilt execution file. But the exe that support long mode didn't support debugger. The debugger enable one didn't support long mode. If you want to play with long mode and SMP and debugger. You need to build a Bochs yourself.
refer Bochs building instruction
http://bochs.sourceforge.net/doc/docbook/user/compiling.html
0. download latest Bochs source code
1. download MingGW and setup it.
2. select msys-base, mingw32-gcc-g++, mingw32-base, mingw-developer-toolkit
3. modify /etc/fstab to mount your bochs source code
4. run msys
5. decompress Bochs source code tgz
6. run ./configure with these Options
--with-win32 \
--enable-smp \
--enable-vmx \
--enable-avx \
--enable-x86-debugger \
--enable-debugger \
--enable-debugger-gui \
--enable-x86-64 \
--enable-configurable-msrs \
--enable-all-optimizations \ --enable-long-phy-address \
--enable-pci \ --enable-clgd54xx \ --enable-voodoo \--enable-sb16
--enable-es1370 \--enable-usb \
--enable-usb-ohci \ --enable-usb-xhci \
below copy from http://wiki.osdev.org/Bochs
I/O debugger macros
Some useful macros when Bochs is compiled with the I/O debug ports enabled (port_e9_hack: enabled=1 if Bochs 2.4 or newer, configure --port-e9-hack if not):Magic Breakpoint
When you're using Bochs with the internal debugger, you can trigger the debugger via a facility called magic breakpoints. To trigger a breakpoint, you can insert xchg bx, bx (in GAS syntax, xchgw %bx, %bx) anywhere in the code and Bochs will trap into the debugger as soon as it executes it. On real hardware this has no effect as it merely replaces the BX register with itself.You should put the following line in your Bochs configuration file to have it listen to magic breakpoints:
magic_break: enabled=1
Debugging SMP
When using the internal debugger, you may use the following command to switch CPUs:set $cpu = n
Internal debugger commands
You can pass a file containing debug commands to automatically run whenever you start bochs with the internal debugger. (bochs -rcBochs places an automatic breakpoint just before the BIOS loads, this can be automatically skipped by putting continue as the first command in the said file.
Debugging Triple Faults
When using the internal debugger, you may change this line in your Bochs configuration file:reset_on_triple_fault 0
This line disables the emulator reset on a Triple fault, enabling you to debug the code after a Triple fault occured (Very useful while implementing paging).
refer
http://bochs.sourceforge.net/doc/docbook/user/bochsrc.html
Below copy from Bochs developer manual
3.1. I/O Interface to Bochs Debugger
This device was added by Dave Poirier (eks@void-core.2y.net).Compiling Bochs with iodebug support
./configure --enable-iodebug makeOther optional fields may be added to the ./configure line, see Bochs documentation for all the information. To enable the iodebug plugin at runtime, it must be loaded with the 'plugin_ctrl' bochsrc option.
Using the I/O Interface to the debugger port range: 0x8A00 - 0x8A01 Port 0x8A00 servers as command register. You can use it to enable the i/o interface, change which data register is active, etc. Port 0x8A01 is used as data register for the memory monitoring.
3.1.1. Commands supported by port 0x8A00
0x8A00 Used to enable the device. Any I/O to the debug module before this command is sent is sent will simply be ignored. 0x8A01 Selects register 0: Memory monitoring range start address (inclusive) 0x8A02 Selects register 1: Memory monitoring range end address (exclusive) 0x8A80 Enable address range memory monitoring as indicated by register 0 and 1 and clears both registers 0x8AE0 - Return to Debugger Prompt If the debugger is enabled (via --enable-debugger), sending 0x8AE0 to port 0x8A00 after the device has been enabled will return the Bochs to the debugger prompt. Basically the same as doing CTRL+C. 0x8AE2 - Instruction Trace Disable If the debugger is enabled (via --enable-debugger), sending 0x8AE2 to port 0x8A00 after the device has been enabled will disable instruction tracing 0x8AE3 - Instruction Trace Enable If the debugger is enabled (via --enable-debugger), sending 0x8AE3 to port 0x8A00 after the device has been enabled will enable instruction tracing 0x8AE4 - Register Trace Disable If the debugger is enabled (via --enable-debugger), sending 0x8AE4 to port 0x8A00 after the device has been enabled will disable register tracing. 0x8AE5 - Register Trace Enable If the debugger is enabled (via --enable-debugger), sending 0x8AE5 to port 0x8A00 after the device has been enabled will enable register tracing. This currently output the value of all the registers for each instruction traced. Note: instruction tracing must be enabled to view the register tracing 0x8AFF Disable the I/O interface to the debugger and the memory monitoring functions.
Note: all accesses must be done using word
Note: reading this register will return 0x8A00 if currently activated, otherwise 0
3.1.2. Access to port 0x8A01 (write-only)
All accesses to this port must be done using words. Writing to this port will shift to the left by 16 the current value of the register and add the provided value to it.Sample: reg0 = 0x01234567 out port: 0x8A01 data: 0xABCD reg0 = 0x4567ABCD
3.1.3. Sample
Enable memory monitoring on first page of text screen (0xb8000-0xb8fa0): add in bochrc file: optromimage1: file="asmio.rom", address=0xd0000/* * Make asmio ROM file: * gcc -c asmio.S * objcopy -O binary asmio.o asmio.rom */ .text .global start .code16 /* ROM Header */ .byte 0x55 .byte 0xAA .byte 1 /* 512 bytes long */ start: /* Monitor memory access on first page of text screen */ mov $0x8A00,%dx /* Enable iodebug (0x8A00->0x8A00) */ mov %dx,%ax out %ax,%dx mov $0x8A01,%ax /* Select register 0 start addr (0x8A01->0x8A00) */ out %ax,%dx mov $0x8A01,%dx /* Write start addr 0xB8000 (high word first) */ mov $0xB,%ax out %ax,%dx mov $0x8000,%ax /* Write start addr (low word) */ out %ax,%dx mov $0x8A02,%ax /* Select register 1 end addr (0x8A02->0x8A00) */ mov $0x8A00,%dx out %ax,%dx mov $0x8A01,%dx /* Write end addr 0xB8FA0 (high word first) */ mov $0xB,%ax out %ax,%dx mov $0x8FA0,%ax /* Write end addr (low word) */ out %ax,%dx mov $0x8A00,%dx /* Enable addr range memory monitoring (0x8A80->0x8A00) */ mov $0x8A80,%ax out %ax,%dx mov $0x8A00,%dx /* Return to Bochs Debugger Prompt (0x8AE0->0x8A00) */ mov $0x8AE0,%ax out %ax,%dx lret .byte 0x6b /* Checksum (code dependent!, update it as needed) */ .align 512 /* NOP follow */
8.13. Using Bochs internal debugger
You can now conditionally compile in a GDB like command line debugger, that allows you to set breakpoints, step through instructions, and other useful functions. If there isn't a command for something you believe is generally useful for the debugger, let me know and I'll implement it if possible.Note: This section describes how to enable and use the Bochs command line debugger. For it's builtin graphical front-end please see the debugger gui section how to enable it.
--enable-debugger
and --enable-disasm
flags.
For example:
./configure --enable-debugger --enable-disasm
Note: You must use flex version 2.5.4 or greater. I have heard that version 2.5.2 will not work.
bochs:1>From here, you may use the following commands:
8.13.1. Execution Control
c continue executing cont continue s [count] execute count instructions, default is 1 step [count] s [cpu] [count] for SMP simulation, execute count instructions on cpu, default is 1 step [cpu] [count] s all [count] for SMP simulation, execute count instructions on all cpus step all [count] Ctrl-C stop execution, and return to command line prompt Ctrl-D if at empty line on command line, exit q quit debugger and execution quit exit
8.13.2. BreakPoints
NOTE: The format of 'seg', 'off', and 'addr' in these descriptions, are as follows. I don't have any way to set the current radix. hexidecimal: 0xcdef0123 decimal: 123456789 octal: 01234567 vbreak seg:off Set a virtual address instruction breakpoint vb seg:off lbreak addr Set a linear address instruction breakpoint lb addr pbreak [*] addr Set a physical address instruction breakpoint pb [*] addr (the '*' is optional for GDB compatibility) break [*] addr b [*] addr info break Display state of all current breakpoints bpe n Enable a breakpoint bpd n Disable a breakpoint delete n Delete a breakpoint del n d n
8.13.3. Memory WatchPoints
watch read addr Insert a read watch point at physical addressaddr
watch r addr Insert a read watch point at physical addressaddr
watch write addr Insert a write watch point at physical addressaddr
watch w addr Insert a write watch point at physical addressaddr
watch Display state of current memory watchpoints watch stop Stop simulation when a watchpoint is encountered (default) watch continue Do not stop simulation when a watchpoint is encountered unwatch addr Remove watchpoint to specific physical address unwatch Remove all watch points trace-mem on/off Enable/Disable memory access tracing
8.13.4. Manipulating Memory
x /nuf addr Examine memory at linear address addr xp /nuf addr Examine memory at physical address addr n Count of how many units to display u Unit size; one of b Individual bytes h Halfwords (2 bytes) w Words (4 bytes) g Giant words (8 bytes) NOTE: these are *not* typical Intel nomenclature sizes, but they are consistent with GDB convention. f Printing format. one of x Print in hexadecimal d Print in decimal u Print in unsigned decimal o Print in octal t Print in binary n, f, and u are optional parameters. u and f default to the last values you used, or to w(words) and x(hex) if none have been supplied. n currently defaults to 1. If none of these optional parameters are used, no slash should be typed. addr is also optional. If you don't specify it, it will be the value the next address (as if you had specified n+1 in the last x command). setpmem addr datasize val Set physical memory location of size datasize to value val. writemem dump a number of bytes of virtual memory starting from the specified linear address into a file crc addr1 addr2 Show CRC32 for physical memory range addr1..addr2
8.13.5. Info commands
r|reg|regs|registers List of CPU integer registers and their contents fp|fpu List of all FPU registers and their contents mmx List of all MMX registers and their contents sse|xmm List of all SSE registers and their contents ymm List of all AVX registers and their contents sreg Show segment registers and their contents dreg Show debug registers and their contents creg Show control registers and their contents info cpu List of all CPU registers and their contents info eflags Show decoded EFLAGS register info break Information about current breakpoint status info tab Show paging address translation info device Show state of the specified device
8.13.6. Manipulating CPU Registers
set reg = expr Change a CPU register to value of expression. Currently only general purpose registers and instruction pointer are supported. You may not change eflags, segment registers, floating point or SIMD registers. Examples: set eax = 2+2/2 set esi = 2*eax+ebx registers List of CPU registers and their contents regs reg r
8.13.7. Disassembly commands
disassemble start end Disassemble instructions in given linear address range, inclusive of start, exclusive of end. Use "set $disassemble_size =" to tell debugger desired segment size. Use a value for end of less than start (or zero) if you only want the first instruction disassembled. disassemble switch-mode Switch between Intel and AT&T disassebly styles for debugger disassembler. disassemble size = n Tell debugger what segment size to use when the "disassemble" command is used. Use values of 0, 16 or 32 for n. Value of 0 means "use segment size specified by current CS segment". Default is 0. set $auto_disassemble = n Cause debugger to disassemble current instruction every time execution stops if n=1. Default is 0. Segment size of current CPU context is used for disassembly, so the "disassemble size" variable is ignored. set disassemble on The same as 'set $auto_disassemble = 1' set disassemble off The same as 'set $auto_disassemble = 0'
8.13.8. Instruction tracing
trace on Disassemble every executed instruction. Note that instructions which caused exceptions are not really executed, and therefore not traced. trace off Disable instruction tracing.
8.13.9. Instrumentation
To use instrumentation features in bochs, you must compile in support for it. You should build a custom instrumentation library in a separate directory in the "instrument/" directory. To tell configure which instrumentation library you want to use, use the--enable-instrumentation
option.
The default library consists of a set of stubs, and the following are
equivalent:
./configure [...] --enable-instrumentation ./configure [...] --enable-instrumentation="instrument/stubs"You could make a separate directory with your custom library, for example "instrument/myinstrument", copy the contents of the "instrument/stubs" directory to it, then customize it. Use:
./configure [...] --enable-instrumentation="instrument/myinstrument"
8.13.10. Instrumentation commands
instrument [command] calls BX_INSTR_DEBUG_CMD instrumentation callback with [command]
8.13.11. Other Commands
ptimePrint the current time (number of ticks since start of simulation).
sb delta
Insert a time break point "delta" instructions into the future ("delta" is a 64-bit integer followed by "L", for example 1000L).
sba time
Insert a time break point at "time" ("time" is a 64-bit integer followed by "L", for example 1000L).
print-stack [num words
]
Print the num words
top 16-bit words on the stack. Num
words
defaults to 16. Only works reliably in protected mode when
the base address of the stack segment is zero.
modebpToggles CPU mode switch breakpoint.
ldsym [global]Load symbols from filefilename
[offset
]
filename
. If the global keyword is
added, then the the symbols will be visible in all contexts for which
symbols have not been loaded. Offset
(default is 0) is added to
every symbol entry. The symbols are loaded in the current (executing)
context.The symbol file consists of zero or more lines of the format "%x %s".
show [string
]
Toggles show symbolic info (calls to begin with). show - shows current show mode show mode - show, when processor switch mode show int - show, when interrupt is happens show call - show, when call is happens show ret - show, when iret is happens show off - toggles off symbolic info show dbg-all - turn on all show flags show dbg-none - turn off all show flags
8.13.12. The Bochs debugger gui
The graphical front-end for the Bochs command line debugger is available for Windows and GTK2 hosts.To use the gui debugger, you must configure Bochs with the default debugger switches and the
--enable-debugger-gui
flag.
For example:
./configure --enable-debugger --enable-disasm --enable-debugger-guiAt runtime you need to add the value
gui_debug
to the
display_library options parameter
in order to use the gui instead of the command line debugger. This example shows how to
use it with the 'x' gui:
display_library: x, options="gui_debug"The gui debugger consists of a gui window with a menu bar, a button bar and some child windows that show the cpu registers, disassembler output, memory dump and the internal debugger output. A command prompt for entering debugger commands is also available.
List the features here.
Most of the gui debugger settings are now saved to an INI file on exit and restored at the next run.