Commit 28a5af12 authored by kaf24's avatar kaf24

bitkeeper revision 1.1691.1.5 (42a6b4baIjkVZx9lVWvoA9RqgAGLMQ)

The following allows you to run unmodified guest operating systems
under Xen on VMX (VT) enabled processors. The tree lives under
<ROOT>/tools/dfw. Instead of booting a guest kernel, boot vmxloader and
specify the disk image in qemurc.

        Leendert
Signed-Off-By: default avatarLeendert van Doorn <leendert@watson.ibm.com>
parent a61fd890
......@@ -567,6 +567,46 @@
41090ec8Pj_bkgCBpg2W7WfmNkumEA tools/examples/xmexample1
40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmexample2
41fc0c18_k4iL81hu4pMIWQu9dKpKA tools/examples/xmexample3
42a6b4b7KssGzTDVN-XG2FM1gCEnnw tools/firmware/Makefile
42a6b4b7qP95OSsEL8XWKKZ1p1myjQ tools/firmware/README
42a6b4b78PWdYzKYvLt_EHhvQCl9ig tools/firmware/rombios/Makefile
42a6b4b75sz5KF9Lry2EGnPMhOdnUA tools/firmware/rombios/apmbios.S
42a6b4b7YwP9rl3AJRTmZbBoal_c6Q tools/firmware/rombios/biossums.c
42a6b4b83gANosDYd43YaK7ATQvBEg tools/firmware/rombios/makesym.perl
42a6b4b8qcIQIBXDeOY3JRwsLM6lhw tools/firmware/rombios/rombios.c
42a6b4b8K7yqnU3-QxndYNZUgHpniw tools/firmware/rombios/rombios.diffs
42a6b4b86GMM969Y82nK3HuUi6eP9g tools/firmware/vgabios/BUGS
42a6b4b8J_MHMVmmF_igI7zeDxSiwA tools/firmware/vgabios/COPYING
42a6b4b8SYW5q21pPPuQt88Bkpqc2Q tools/firmware/vgabios/ChangeLog
42a6b4b8INe7qe20YYlwATaAADEMQA tools/firmware/vgabios/Makefile
42a6b4b8AYFCsoAeqqQ8dibmgxkfLA tools/firmware/vgabios/Notes
42a6b4b8NUXHh1hudvvNCuqgo9cB-Q tools/firmware/vgabios/README
42a6b4b8MM0Pj6uDwdJ4Eyg6hB-oEA tools/firmware/vgabios/TODO
42a6b4b8AL0YrgudjmQr7QvJ3we1Cg tools/firmware/vgabios/biossums.c
42a6b4b8Zce-r8OtpctwvqHBS8cHEw tools/firmware/vgabios/clext.c
42a6b4b8fIyMd0d8tIPV4JDAvB5l1A tools/firmware/vgabios/dataseghack
42a6b4b8M4BsNDRAJMHpY8H2iRu0qA tools/firmware/vgabios/vbe.c
42a6b4b8Z2pSU4e5qrUR5r1vEKNbKQ tools/firmware/vgabios/vbe.h
42a6b4b8EyiklW2C9eD9_t0OmRfmFQ tools/firmware/vgabios/vbe_display_api.txt
42a6b4b8oXcw5CgLj-mBVT4dUc-Umw tools/firmware/vgabios/vbetables.h
42a6b4b85jkZnCar41YreYVUAY7IDQ tools/firmware/vgabios/vgabios.c
42a6b4b8xxpRYh1BesaSgW3gpgMsaQ tools/firmware/vgabios/vgabios.h
42a6b4b8WSA5xHF-R5F8iBcB6BC5wA tools/firmware/vgabios/vgafonts.h
42a6b4b9C66bPuUTaLjCnJ0I-kGz9w tools/firmware/vgabios/vgatables.h
42a6b4b969QLJRt3TU_v3yYhZI45Gg tools/firmware/vmxassist/Makefile
42a6b4b95iuk7M2s-edoSFrWcdoYcw tools/firmware/vmxassist/TODO
42a6b4b9Q6VB27GxRNCARsDN2ZuKNw tools/firmware/vmxassist/gen.c
42a6b4b9NmLjb36-sXiiWzcGHjTOJA tools/firmware/vmxassist/head.S
42a6b4b9jmF9m22iiwu8XwEm1j5fnQ tools/firmware/vmxassist/machine.h
42a6b4b9ABmGHA1LzYjpq63FBs4hcw tools/firmware/vmxassist/mkhex
42a6b4b9xmj4TLHJtV-DhnwT9mMpfw tools/firmware/vmxassist/setup.c
42a6b4b9PjgANTP8Y8JFTToBrV9ssg tools/firmware/vmxassist/trap.S
42a6b4b9GlymU0VmQyan23pagDaRTQ tools/firmware/vmxassist/util.c
42a6b4b9mmqUyFn487gP4spU_R6xtg tools/firmware/vmxassist/util.h
42a6b4b9JssxvlpcV_-QcGRMDGgL_w tools/firmware/vmxassist/vm86.c
42a6b4b92oUAJMzCE-YcVlA2Z-2zyg tools/firmware/vmxassist/vm86.h
42a6b4b9TlkVUYTkLd_Bvq9vlrEx6g tools/firmware/vmxassist/vmxassist.ld
42a6b4b92L-2zFg-Qal6YweeE-pMiA tools/firmware/vmxassist/vmxloader.c
428d0d82yOaUzYQuYQxH7VzQytKo-g tools/ioemu/COPYING
428d0d82EdPp1TqJBembLgyB1y413w tools/ioemu/COPYING.LIB
428d0d82fd6-QydvFfHmeQBGrKnrrA tools/ioemu/Changelog
......
XEN_ROOT = ../..
include $(XEN_ROOT)/tools/Rules.mk
SUBDIRS :=
SUBDIRS += rombios
SUBDIRS += vgabios
SUBDIRS += vmxassist
.PHONY: all install clean
all:
@set -e; for subdir in $(SUBDIRS); do \
$(MAKE) -C $$subdir $@; \
done
install:
@set -e; for subdir in $(SUBDIRS); do \
$(MAKE) -C $$subdir $@; \
done
clean:
@set -e; for subdir in $(SUBDIRS); do \
$(MAKE) -C $$subdir $@; \
done
Domain FirmWare support
-----------------------
One of the key advantages of full virtualization hardware support (such
as Intel's VT or AMD's Pacifica) is the ability to run unmodified guest
operating systems. However, since most OSes rely on BIOS support during
their early bringup, we need to provide a surrogate ROMBIOS and VGABIOS
firmware layer.
What's more, we need to support real-mode which is required by
the firmware and bootstrap loaders. Real-mode support is especially
challenging for Intel's VMX (VT) enabled CPUs where there is no real-mode
support for VMX guest partitions. In this case you either have to do full
emulation (full real-mode emulator; more complete but potentially slower)
or partial emulation (use the VM8086 extensions, emulate only those
instructions that are missing; faster, but potentially incomplete). The
vmxassist code in this subdirectory uses the later approach because it
is smaller and faster.
The approach is relatively straight forward. Vmxloader contains three
payloads (rombios, vgabios and vmxassist) and it is bootstrapped as any
other 32-bit OS. Vmxloader copies its payloads to the addresses below
and transfers control to vmxassist.
vgabios VGABIOS (standard and Cirrus).
Resides at C000:0000.
vmxassist VMXAssist VM86 realmode emulator for VMX.
Resides at D000:0000.
rombios ROMBIOS code. Derived from Bochs.
Resides at F000:0000
Vmxassist first sets up it own world (GDT, IDT, TR, etc), enables
VM8086 and then transfers control to F000:FFF0 and executes 16-bit
code. Unsupported instructions cause a general protection failure at
which point vmxassist kicks in and emulates the offending instruction.
Whever the emulated code transitions to 32-bit protected mode, vmxassist
will go away. Whenever 32-bit protected code transitions to real-mode,
Xen/VMX will detect this and transfer control to vmxassist.
Most of the vmxassist complexity comes from properly handling the
real to protected mode and protected to real mode transitions and
the proper emulation of the segment registers. Even though the Intel
manual clearly states that you should immediately perform a jmp far
after a mode transition, many operating systems execute additional
instructions and some even refer to segment selectors and pop data
from the stack. Vmxassist contains a number of work arounds for these
OSes.
Acknowledgements
----------------
The rombios was taken (largely unmodified) from Bochs, which was written
by Kevin Lawton. The VGABIOS was written by Christophe Bothamy. Arun Sharma,
Asit Mallick and Nitin Kamble (Intel) provided the E820 patches and lots
of useful feedback.
Contact
-------
Leendert van Doorn
IBM T.J. Watson Research Center
19 Skyline Drive
Hawthorne, NY 10532
leendert@watson.ibm.com
Tested Operating Systems
------------------------
Since vmxassist uses partial emulation, it may always miss opcodes
that are required by a particular OS. The table below lists the OSes
I have tried. The Install column indicates a full CD/DVD install into
a VMX partition. The Disk column indicates booting from prefabricated
disk image.
Operating System Install Disk
------------------------------------------------------------
RedHat Enterprise Linux (RHEL3_U5) Yes Yes
Fedora Code (FC3) (-) Yes
FreeBSD 5.3 (-) Yes
MS-DOS 5.0 (-) Yes
(-) not tried yet
BIOS_BUILDS = BIOS-bochs-latest
#BIOS_BUILDS += BIOS-bochs-2-processors
#BIOS_BUILDS += BIOS-bochs-4-processors
#BIOS_BUILDS += BIOS-bochs-8-processors
all: bios
bios: biossums ${BIOS_BUILDS}
clean:
rm -f *.o *.a *.s rombios.bin _rombios*_.c
rm -f as86-sym.txt ld86-sym.txt
rm -f rombios*.txt rombios*.sym usage biossums
rm -f BIOS-bochs-*
BIOS-bochs-latest: rombios.c biossums
gcc -DBX_SMP_PROCESSORS=1 -E -P $< > _rombios_.c
bcc -o rombios.s -C-c -D__i86__ -0 -S _rombios_.c
sed -e 's/^\.text//' -e 's/^\.data//' rombios.s > _rombios_.s
as86 _rombios_.s -b tmp.bin -u- -w- -g -0 -j -O -l rombios.txt
-perl makesym.perl < rombios.txt > rombios.sym
mv tmp.bin BIOS-bochs-latest
./biossums BIOS-bochs-latest
rm -f _rombios_.s
BIOS-bochs-2-processors: rombios.c biossums
gcc -DBX_SMP_PROCESSORS=2 -E -P $< > _rombios2_.c
bcc -o rombios2.s -C-c -D__i86__ -0 -S _rombios2_.c
sed -e 's/^\.text//' -e 's/^\.data//' rombios2.s > _rombios2_.s
as86 _rombios2_.s -b tmp2.bin -u- -w- -g -0 -j -O -l rombios2.txt
-perl makesym.perl < rombios2.txt > rombios2.sym
mv tmp2.bin BIOS-bochs-2-processors
./biossums BIOS-bochs-2-processors
rm -f _rombios2_.s
BIOS-bochs-4-processors: rombios.c biossums
gcc -DBX_SMP_PROCESSORS=4 -E -P $< > _rombios4_.c
bcc -o rombios4.s -C-c -D__i86__ -0 -S _rombios4_.c
sed -e 's/^\.text//' -e 's/^\.data//' rombios4.s > _rombios4_.s
as86 _rombios4_.s -b tmp4.bin -u- -w- -g -0 -j -O -l rombios4.txt
-perl makesym.perl < rombios4.txt > rombios4.sym
mv tmp4.bin BIOS-bochs-4-processors
./biossums BIOS-bochs-4-processors
rm -f _rombios4_.s
BIOS-bochs-8-processors: rombios.c biossums
gcc -DBX_SMP_PROCESSORS=8 -E -P $< > _rombios8_.c
bcc -o rombios8.s -C-c -D__i86__ -0 -S _rombios8_.c
sed -e 's/^\.text//' -e 's/^\.data//' rombios8.s > _rombios8_.s
as86 _rombios8_.s -b tmp8.bin -u- -w- -g -0 -j -O -l rombios8.txt
-perl makesym.perl < rombios8.txt > rombios8.sym
mv tmp8.bin BIOS-bochs-8-processors
./biossums BIOS-bochs-8-processors
rm -f _rombios8_.s
biossums: biossums.c
gcc -o biossums biossums.c
// APM BIOS support for the Bochs BIOS
// Copyright (C) 2004 Fabrice Bellard
//
// Debugging extensions, 16-bit interface and extended power options
// Copyright (C) 2005 Struan Bartlett
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#if defined(APM_REAL)
#define APMSYM(s) apmreal_ ## s
#elif defined(APM_PROT16)
#define APMSYM(s) apm16_ ## s
#elif defined(APM_PROT32)
#define APMSYM(s) apm32_ ## s
#else
#error unsupported APM mode
#endif
APMSYM(out_str):
push eax
push ebx
mov ebx, eax
APMSYM(out_str1):
SEG CS
mov al, byte ptr [bx]
cmp al, #0
je APMSYM(out_str2)
outb dx, al
inc ebx
jmp APMSYM(out_str1)
APMSYM(out_str2):
pop ebx
pop eax
ret
APMSYM(07_poweroff_str):
.ascii "Shutdown"
db 0
APMSYM(07_suspend_str):
.ascii "Suspend"
db 0
APMSYM(07_standby_str):
.ascii "Standby"
db 0
#if DEBUG_APM
APMSYM(put_str):
push edx
mov dx, #INFO_PORT
call APMSYM(out_str)
pop edx
ret
; print the hex number in eax
APMSYM(put_num):
push eax
push ebx
push ecx
push edx
mov ecx, eax
mov bx, #8
mov dx, #INFO_PORT
APMSYM(put_num1):
mov eax, ecx
shr eax, #28
add al, #0x30
cmp al, #0x39
jbe APMSYM(put_num2)
add al, #0x27
APMSYM(put_num2):
outb dx, al
shl ecx, #4
dec bx
jne APMSYM(put_num1)
pop edx
pop ecx
pop ebx
pop eax
ret
APMSYM(put_reg):
outb dx, al
shr eax, #8
outb dx, al
shr eax, #8
outb dx, al
shr eax, #8
outb dx, al
mov eax,ebx
call APMSYM(put_num)
mov al, #0x3b
outb dx,al
mov al, #0x20
outb dx,al
ret
APMSYM(put_regs):
push eax
push edx
push ebx
mov dx, #INFO_PORT
mov ebx, eax
mov eax, #0x3d584145 // 'EAX='
call APMSYM(put_reg)
pop ebx
push ebx
mov eax, #0x3d584245 // 'EBX='
call APMSYM(put_reg)
mov ebx, ecx
mov eax, #0x3d584345 // 'ECX='
call APMSYM(put_reg)
mov ebx, edx
mov eax, #0x3d584445 // 'EDX='
call APMSYM(put_reg)
mov ebx, esi
mov eax, #0x3d495345 // 'ESI='
call APMSYM(put_reg)
mov ebx, edi
mov eax, #0x3d494445 // 'EDI='
call APMSYM(put_reg)
mov al, #0x0a
outb dx, al
pop ebx
pop edx
pop eax
ret
#endif
#if defined(APM_PROT32)
_apm32_entry:
#endif
#if defined(APM_PROT16)
_apm16_entry:
#endif
pushf
#if defined(APM_REAL)
_apmreal_entry:
#endif
#if DEBUG_APM
call APMSYM(put_regs)
#endif
#if defined(APM_REAL)
;-----------------
; APM installation check
APMSYM(00):
cmp al, #0x00
jne APMSYM(01)
mov ah, #1 // APM major version
mov al, #2 // APM minor version
mov bh, #0x50 // 'P'
mov bl, #0x4d // 'M'
// bit 0 : 16 bit interface supported
// bit 1 : 32 bit interface supported
mov cx, #0x3
jmp APMSYM(ok)
;-----------------
; APM real mode interface connect
APMSYM(01):
cmp al, #0x01
jne APMSYM(02)
jmp APMSYM(ok)
;-----------------
; APM 16 bit protected mode interface connect
APMSYM(02):
cmp al, #0x02
jne APMSYM(03)
mov bx, #_apm16_entry
mov ax, #0xf000 // 16 bit code segment base
mov si, #0xfff0 // 16 bit code segment size
mov cx, #0xf000 // data segment address
mov di, #0xfff0 // data segment length
jmp APMSYM(ok)
;-----------------
; APM 32 bit protected mode interface connect
APMSYM(03):
cmp al, #0x03
jne APMSYM(04)
mov ax, #0xf000 // 32 bit code segment base
mov ebx, #_apm32_entry
mov cx, #0xf000 // 16 bit code segment base
// 32 bit code segment size (low 16 bits)
// 16 bit code segment size (high 16 bits)
mov esi, #0xfff0fff0
mov dx, #0xf000 // data segment address
mov di, #0xfff0 // data segment length
jmp APMSYM(ok)
#endif
;-----------------
; APM interface disconnect
APMSYM(04):
cmp al, #0x04
jne APMSYM(07)
jmp APMSYM(ok)
;-----------------
; APM Set Power State
APMSYM(07):
cmp al, #0x07
jne APMSYM(0a)
cmp bx, #1
jne APMSYM(ok)
cmp cx, #3
je APMSYM(07_poweroff)
cmp cx, #2
je APMSYM(07_suspend)
cmp cx, #1
je APMSYM(07_standby)
jne APMSYM(ok)
APMSYM(07_poweroff):
// send power off event to emulator
cli
mov dx, #0x8900
mov ax, #APMSYM(07_poweroff_str)
call APMSYM(out_str)
APMSYM(07_1):
hlt
jmp APMSYM(07_1)
APMSYM(07_suspend):
push edx
mov dx, #0x8900
mov ax, #APMSYM(07_suspend_str)
call APMSYM(out_str)
pop edx
jmp APMSYM(ok)
APMSYM(07_standby):
push edx
mov dx, #0x8900
mov ax, #APMSYM(07_standby_str)
call APMSYM(out_str)
pop edx
jmp APMSYM(ok)
;-----------------
; Get Power Status
APMSYM(0a):
cmp al, #0x0a
jne APMSYM(0b)
mov bh, #0x01 // on line
// mov bh, #0x02 // battery
mov bl, #0xff // unknown battery status
// mov bl, #0x03 // charging
mov ch, #0x80 // no system battery
// mov ch, #0x8 // charging
mov cl, #0xff // unknown remaining time
// mov cl, #50
mov dx, #0xffff // unknown remaining time
mov si, #0 // zero battery
// mov si, #1 // one battery
jmp APMSYM(ok)
;-----------------
; Get PM Event
APMSYM(0b):
cmp al, #0x0b
jne APMSYM(0e)
mov ah, #0x80 // no event pending
jmp APMSYM(error)
;-----------------
; APM Driver Version
APMSYM(0e):
cmp al, #0x0e
jne APMSYM(unimplemented)
mov ah, #1
mov al, #2
jmp APMSYM(ok)
;-----------------
APMSYM(ok):
popf
clc
#if defined(APM_REAL)
jmp iret_modify_cf
#else
retf
#endif
APMSYM(unimplemented):
APMSYM(error):
popf
stc
#if defined(APM_REAL)
jmp iret_modify_cf
#else
retf
#endif
#undef APM_PROT32
#undef APM_PROT16
#undef APM_REAL
#undef APMSYM
/* biossums.c --- written by Eike W. */
#include <stdlib.h>
#include <stdio.h>
typedef unsigned char byte;
void check( int value, char* message );
#define LEN_BIOS_DATA 0x10000
#define MAX_OFFSET (LEN_BIOS_DATA - 1)
#define BIOS_OFFSET 0xFFFF
long chksum_bios_get_offset( byte* data, long offset );
byte chksum_bios_calc_value( byte* data, long offset );
byte chksum_bios_get_value( byte* data, long offset );
void chksum_bios_set_value( byte* data, long offset, byte value );
#define _32__LEN 9
#define _32__CHKSUM 10
#define _32__MINHDR 16
long chksum__32__get_offset( byte* data, long offset );
byte chksum__32__calc_value( byte* data, long offset );
byte chksum__32__get_value( byte* data, long offset );
void chksum__32__set_value( byte* data, long offset, byte value );
#define _MP__LEN 8
#define _MP__CHKSUM 10
#define _MP__MINHDR 16
long chksum__mp__get_offset( byte* data, long offset );
byte chksum__mp__calc_value( byte* data, long offset );
byte chksum__mp__get_value( byte* data, long offset );
void chksum__mp__set_value( byte* data, long offset, byte value );
#define PCMP_BASELEN 4
#define PCMP_CHKSUM 7
#define PCMP_EXT_LEN 40
#define PCMP_EXT_CHKSUM 42
#define PCMP_MINHDR 42
long chksum_pcmp_get_offset( byte* data, long offset );
byte chksum_pcmp_calc_value( byte* data, long offset );
byte chksum_pcmp_get_value( byte* data, long offset );
void chksum_pcmp_set_value( byte* data, long offset, byte value );
#define _PIR_LEN 6
#define _PIR_CHKSUM 31
#define _PIR_MINHDR 32
long chksum__pir_get_offset( byte *data, long offset );
byte chksum__pir_calc_value( byte* data, long offset );
byte chksum__pir_get_value( byte* data, long offset );
void chksum__pir_set_value( byte* data, long offset, byte value );
byte bios_data[LEN_BIOS_DATA];
int main( int argc, char* argv[] ) {
FILE* stream;
long offset, tmp_offset;
byte cur_val = 0, new_val = 0;
int hits;
if( argc != 2 ) {
printf( "Error. Need a file-name as an argument.\n" );
exit( EXIT_FAILURE );
}