Detecting under Bochs Emulation
Detecting under Bochs Emulation
Hi All,
I am looking for a way to determine if my OS is running under Bochs or not. Can someone point me in the right direction for determing if Bochs is running or not?
I am looking for a way to determine if my OS is running under Bochs or not. Can someone point me in the right direction for determing if Bochs is running or not?
Re:Detecting under Bochs Emulation
Under perfect emulation there should be no way to tell at all. Of course, Bochs is nowhere near perfect and nor is any other emulation program. You could try reading from the floppy drive, if it succeeds in one try then it could possibly be an emulator, if it takes more than one try then chances are it's a real system. Dunno other than that, I'm sure guys with more experience know of a lot of differences to the real thing.
Re:Detecting under Bochs Emulation
Depending on how Bochs is compiled:
Anything you write to port 0xE9 will be displayed on the console, if ENABLE_PORT_E9_HACK or similar is defined in the configure script.
Code: Select all
if (inb(0xE9) == 0xE9)
bochs = true;
Re:Detecting under Bochs Emulation
@Kemp,
I agree, in a perfect world, we'd have perfect emulation, but alas we do not.
@Mike,
Thanks! I needed the clarification that you gave. I read that portion of the code for Bochs but wasn't too sure what the heck they were saying about port 0E9h. Anyhow, this works:
Here's the screen dump:
I agree, in a perfect world, we'd have perfect emulation, but alas we do not.
@Mike,
Thanks! I needed the clarification that you gave. I read that portion of the code for Bochs but wasn't too sure what the heck they were saying about port 0E9h. Anyhow, this works:
Code: Select all
BochsDetectedMessage db 'Bochs detected',13,10,0
BochsNotDetectedMessage db 'Bochs not detected',13,10,0
BochsOn dd 0
DetectBochs:
mov dx,0E9h
in al,dx
cmp al,0E9h
je .InBochs
mov eax,0
mov esi,BochsNotDetectedMessage
jmp .Done
.InBochs:
mov eax,1
mov esi,BochsDetectedMessage
.Done:
mov [BochsOn],eax
call PrintString
ret
Code: Select all
smiddy's OS (C) 2004, 2005. All Rights Reserved.
Version 1.00.00.000000AF
CPU: CPUID Instruction: GenuineIntel Pentium III (Coppermine)
A20 Gate: Init KBC: 1st Test: A20 memory address line enabled...
E820: 1,073,741,824 bytes.
E801: 1,073,741,824 bytes.
88xx: 16,777,216 bytes.
CMOS: 67,108,864 bytes.
Entering UnReal Mode...
Probe: 1,073,741,824 bytes.
Mapping Memory 1: 1,073,741,824 installed: E820:
Mapping Memory 2: Bitmap Initialized at 14MB: 1,056,964,608 bytes free for use.
Looking for VENDORS.TXT in root...Found! Loading VENDORS.TXT 198,196 bytes.
ERROR: No Plug and Play BIOS
BIOS32 Entry Found at: 000F9D90h Revision: 0
PCI32 BIOS Found at: 000F9DD0h
PCIIRQ Table found: 000FA030h Slots: 6 Bus: 0 Device: 1 Function: 0
PCI IRQ Slot: 0 Bus: 0 Device: 1 INT A#: 60h
PCI IRQ Slot: 1 Bus: 0 Device: 2 INT A#: 61h
PCI IRQ Slot: 2 Bus: 0 Device: 3 INT A#: 62h
PCI IRQ Slot: 3 Bus: 0 Device: 4 INT A#: 63h
PCI IRQ Slot: 4 Bus: 0 Device: 5 INT A#: 60h
PCI IRQ Slot: 5 Bus: 0 Device: 6 INT A#: 61h
About to cook VENDORS.TXT file for use in enumeration.
The first pass completed:
This file was created on: Sat Jun 25 13:04:43 PDT 2005
Creating database of 891,224 bytes: VendorID, DeviceID, VendorString, DeviceString.
Reducing required information size to items only currently installed.
8086 1237 Intel Corporation - 82440LX/EX PCI & Memory
8086 7000 Intel Corporation - 82371SB PIIX3 PCI-to-ISA Bridge (Triton II)
8086 7010 Intel Corporation - 82371SB PIIX3 IDE Interface (Triton II)
smiddyOS Clock Initializing...Done!
smiddyOS Keyboard Initializing...Done!
Bochs detected
Virtual PC Not Detected
VM Ware Not Detected
Start End Size (bytes) Type Owner/Description
--------- --------- ------------- --- -----------------
00000000h 000003FFh 1,024 02h Interrupt Vector Table (IVT)
00000400h 000004FFh 256 02h BIOS Data Area (BDA)
00000500h 000005FFh 256 02h smiddyOS Data Area (OSDA)
00000600h 0009FBFFh 652,800 02h smiddyOS code
0009FC00h 0009FFFFh 1,024 02h Extended BIOS Data Area (EBDA)
000A0000h 000BFFFFh 131,072 02h VGA Buffer Area
000C0000h 000FFFFFh 262,144 02h ROM/BIOS Area
00100000h 00FFFFFFh 15,728,640 02h smiddyOS code
01000000h 010000BFh 192 02h PCI Vendors and Devices Information (Reduced)
010000C0h 010307FFh 198,464 01h <Free Useable Memory>
01030800h 0110A157h 891,224 02h PCI Vendors and Devices Information (Cooking)
0110A158h 0120A157h 1,048,576 02h Text Windowing Heap
0120A158h 3FFFFFFFh 1,054,826,152 01h <Free Useable Memory>
40000000h FFFFFFFFh 3,221,225,472 02h Unuseable addressable memory area
Press any key to continue...
Re:Detecting under Bochs Emulation
HI,
A possibly more robust method of detecting Bochs is to examine the results returned by "Int 0x15, function 0xE820". For real computers the BIOS is mapped into the highest addresses of physical memory (below 4 GB) and this area is returned by the memory map function as unusable/reserved, while on Bochs it isn't as this high mapping doesn't exist.
Cheers,
Brendan
A possibly more robust method of detecting Bochs is to examine the results returned by "Int 0x15, function 0xE820". For real computers the BIOS is mapped into the highest addresses of physical memory (below 4 GB) and this area is returned by the memory map function as unusable/reserved, while on Bochs it isn't as this high mapping doesn't exist.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Detecting under Bochs Emulation
Hey Brendan,
Humm, my current E820 routine doesn't do a mapping that way within my OS. I'll have to include that code from my E820 application that does the entire mapping and make the comparison. Thanks! Though, I suspect, that if someone reports that as a bug to Bochs they'll fix it to be more like a real PC.
Humm, my current E820 routine doesn't do a mapping that way within my OS. I'll have to include that code from my E820 application that does the entire mapping and make the comparison. Thanks! Though, I suspect, that if someone reports that as a bug to Bochs they'll fix it to be more like a real PC.
Re:Detecting under Bochs Emulation
Hi,
For the time being there's no real reason for the Bochs project to change - as long as the environment that the guest OS runs in is correct it doesn't matter if the early BIOS initialization isn't 100% accurate (anything before the BIOS jumps to 0x07C00 isn't too important as long as it works).
In the meantime, a version of Bochs that doesn't have the 0xE9 hack enabled is much more likely...
Another way to detect Bochs is using the RDTSC instruction - Bochs increments the time stamp counter by one for every instruction (regardless of how many cycles it should take). Something like this should work:
Of course this relies on the RDTSC instruction being available - if your OS requires a Pentium or later CPU it always will be. Notice the care taken to prevent out of order execution on a real CPU from causing a "false positive" - the continued EAX register dependancies and the serializing instruction. Initializing ECX to 0x55555555 just makes the MUL's take longer, and the "lea ebx,[ebx*8 + eax]" is the slowest way of doing "mov ebx,eax" that I could think of . On a real CPU this sequence should always cost more than 16 cycles...
Cheers,
Brendan
Hehee - I've already mentioned on the Bochs bug list that the 64 KB BIOS limit is a problem that will need to be rectified eventually, as 64 KB isn't enough space to support things like ACPI, however I assume such a change would only be done in conjuction with other larger changes that would take considerable time to complete.smiddy wrote:Humm, my current E820 routine doesn't do a mapping that way within my OS. I'll have to include that code from my E820 application that does the entire mapping and make the comparison. Thanks! Though, I suspect, that if someone reports that as a bug to Bochs they'll fix it to be more like a real PC.
For the time being there's no real reason for the Bochs project to change - as long as the environment that the guest OS runs in is correct it doesn't matter if the early BIOS initialization isn't 100% accurate (anything before the BIOS jumps to 0x07C00 isn't too important as long as it works).
In the meantime, a version of Bochs that doesn't have the 0xE9 hack enabled is much more likely...
Another way to detect Bochs is using the RDTSC instruction - Bochs increments the time stamp counter by one for every instruction (regardless of how many cycles it should take). Something like this should work:
Code: Select all
mov ebx,0
mov ecx,0x55555555
rdtsc
lea ebx,[ebx*8 + eax]
mul ecx
mul ecx
mul ecx
mul ecx
mul ecx
mul ecx
mul ecx
mul ecx
mul ecx
mul ecx
mul ecx
or eax,1
and eax,1
cpuid ;Serializing instruction!
rdtsc
sub eax,ebx ;ebx = cycles used between RDTSC instructions
cmp eax,16 ;Is it Bochs (16 cycles only)?
je .isBochs ; yes
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Detecting under Bochs Emulation
Nice peice of code, thanks.
Here's a screen shot of my getmem app, and you're correct it only says what is available. Man I should have checked that out previously.
That is on PC-DOS 3.3. Here's what I would have expected:
Something along those lines.
You seem very knowledgeable on Bochs' internals. Thanks, you have saved me the time in investigating this myself. A hefty pint of your favorite beverage (a nice Sam Adams sounds good right now) for you from me!
Here's a screen shot of my getmem app, and you're correct it only says what is available. Man I should have checked that out previously.
Code: Select all
A:\>getmem
GETMEM.COM - 0.14.0212 Attempt to see what memory is installed... -smiddy
BIOS:
15h:
E820: Base Address - Memory Length - Type
: 0000000000000000 - 000000000009FC00h - 01 << Available to OS >>
: 0000000000100000 - 000000003FF00000h - 01 << Available to OS >>
----------------------------------------------------------------
: Total Memory (Free) : 3FF9FC00h - 1,073,347,584 bytes.
E801:
: Extended memory (1M - 16M) : 3C00h - 15,728,640 bytes.
: Extended memory > 16M : 3F00h - 1,056,964,608 bytes.
: Configured memory (1M - 16M): 000Ah - 10,240 bytes.
: Configured memory > 16M : 3F00h - 1,056,964,608 bytes.
----------------------------------------------------------------
: Total Memory (Free) : 3FF00000h - 1,072,693,248 bytes.
12h:
: Conventional Memory (640K) : 027Fh - 654,336 bytes.
15h:
88 :
: Extended Memory (To 64M) : 3C00h - 15,728,640 bytes.
----------------------------------------------------------------
: Total Memory (Free) : 00F9FC00h - 16,382,976 bytes.
CMOS:
: Conventional Memory (640K) : 0280h - 655,360 bytes.
: Extended Memory (To 64M) : FC00h - 66,060,288 bytes.
----------------------------------------------------------------
: Total Memory (Free) : 03FA0000h - 66,715,648 bytes.
A:\>
Code: Select all
A:\>GETMEM
GETMEM.COM - 0.14.020B Attempt to see what memory is installed... -smiddy
BIOS:
15h:
E820: Base Address - Memory Length - Type
: 0000000000000000 - 000000000009FC00h - 01 << Available to OS >>
: 000000000009FC00 - 0000000000000400h - 02 << Reserved Memory >>
: 00000000000F0000 - 0000000000010000h - 02 << Reserved Memory >>
: 0000000000100000 - 0000000027EF0000h - 01 << Available to OS >>
: 0000000027FF0000 - 0000000000008000h - 03 << ACPI Reclaim Memory >>
: 0000000027FF8000 - 0000000000008000h - 04 << ACPI NVS Memory >>
: 00000000FEC00000 - 0000000000001000h - 02 << Reserved Memory >>
: 00000000FEE00000 - 0000000000001000h - 02 << Reserved Memory >>
: 00000000FFF80000 - 0000000000080000h - 02 << Reserved Memory >>
----------------------------------------------------------------
: Total Memory : 27F8FC00h - 670,628,864 bytes.
You seem very knowledgeable on Bochs' internals. Thanks, you have saved me the time in investigating this myself. A hefty pint of your favorite beverage (a nice Sam Adams sounds good right now) for you from me!