Bochs

From OSDev.wiki
Revision as of 18:56, 24 November 2008 by osdev>Tantrikwizard
Jump to navigation Jump to search

Bochs is a steadily improving simulator for the IA32 platform. Among other niceties (such as removing the need for a reboot to test your latest kernel build, just restart Bochs), it offers detailed debugging functionality that can help greatly during kernel development.

It is strongly suggested to get two installations of Bochs - in addition to the out-of-the-box version (which might well be one of the binary downloads), you should also compile a second instance with the internal debugger enabled - so when something strange occurs that your 'normal' debugging tools can't trace, you can cross-check it with the debug version. You may also wish to enable (and use) the debug i/o ports.

I/O debugger macros

Some useful macros when Bochs is compiled with the I/O debug ports enabled:

//outputs a character to the debug console
#define BochsConsolePrintChar(c) outportb(0xe9, c)
//stops simulation and breaks into the debug console
#define BochsBreak() outportw(0x8A00,0x8A00); outportw(0x8A00,0x08AE0);


Frequent error messages

Running in Bogus Memory

You sent your code pointer (eip) to some uninitialized memory area. This means you either followed a null (or uninitialized) pointer, or you damaged the return address of your stack frame. Make your code more clean, test pointers before you follow them, initialize every pointer (especially those who are on the stack) and enable -Wall.

TripleFault

The CPU didn't manage to invoke an exception handler. This is probably due to a bad IDT register content, or a bad IDT descriptor. Sometimes (but less likely), it can also be due to a severe bug in your exception handler code. Check your exception works with "illegal" ASM instructions like idiv 0, or

push 0xf001
pop ds                   ;; 0xf001 is no valid segment,
mov ax, ~[ds:0x12345678] ;; let's see if we get the GPF

I/O Operand Size

Bochs performs some paranoiac checks on I/O operand size. Reading a byte from port 0x1234 is usually not the same thing as reading a dword. Go back to your chip's datasheet and double-check your sizes are correct.

fetch_raw_descriptor: LDTR.valid=0

Many of you have said "but ... I do not have an LDT and i read it wasn't mandatory!?". You're right. And so is BOCHS. This message usually means that your program tried to load a selector with some garbage value, which happened to have the 3rd bit (Table Indicator) set. The CPU will try to look up the descriptor in the LDT, but there's no LDT registered! In most cases, the error comes from some mispairing of push and pop on the stack, which lead to a non-selector value to be loaded in a segment register.


If you're still stuck, download the Bochs sources package and search for the message you received. Then, maybe you can add extra information to the message-printing code (like the faulty offset of a segfault, the segment limit, etc). But keep away from modifying Bochs' operations! Every time I suspected a bug in Bochs, I was just misunderstanding the Intel Manual...

Differences between Bochs and real hardware

Bochs enables A20Line in the BIOS
Your PC doesn't necessarily do so. Sometimes there's a BIOS option, sometimes there isn't. Check your code that enables A20Line and make sure it has no issues with faster hardware.
Bochs wipes out its memory
In Bochs, memory is always filled with zero until you (or the BIOS) put something else. On a normal PC, uninitialized memory tends to contain garbage (most often all-ones) or traces of previous executions. Check your pointers, initialize them, print your code on paper if necessary.
Bochs floppy has no errors
In a normal PC, it's common to issue up to 3 read commands on a sector/track before it can be read fine. If you don't have proper error check/recovery in your bootsector, you're likely to run something that is not your kernel...
Bochs is flexible about returning to real mode
Unlike what Chris Giese's Protected Mode tutorial states, you do not have to be in 16-bit protected mode to clear the PE bit of cr0. If you fail to enter 16-bit protected mode on a real PC, it will hang, without giving any error indication - no triple fault or anything!
Bochs' timer is not realtime
(unless you configure it closer to real time). Waiting for 2 second on bochs will let any virtual device that needs 2 seconds to be ready be ready, but that could be just 0.02 seconds for you ... or that could be 200 seconds.

Adding clock: sync=realtime, time0=local will cause interrupts at real intervals, but may overload the emulated OS with PIT interrupts and overflow the stack (if it's pre-emptible)

CPU is always Intel
Bochs emulates a Intel CPU, so CPUID will always report back Intel regardless of whats really in your system.

Bochs image files in a nutshell

To use Bochs to boot your custom kernel, search for the "floppya" and "boot" lines in the bochsrc configuration file. The following configuration allows you to use, and boot from, the "real" floppy drive of your computer:

floppya: 1_44=/dev/fd0, status=inserted
boot: floppy

For Windows users, that should read:

floppya: 1_44=a:, status=inserted
boot: floppy

But this is awfully slow, and puts lots of stress on the floppy when you are in a tight patch - make - boot cycle. Bochs offers the use of image files, including an interactive tool to create an image file (bximage.exe). Note that Bochs will emulate the floppy's internals even when the image is a device rather than a regular file ...

See Also

Articles

External Links