Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Jul 2012 12:07:13 +0900
From:      Takuya ASADA <syuu@dokukino.com>
To:        soc-status@freebsd.org, Peter Grehan <grehan@freebsd.org>
Subject:   [status report #6] BHyVe BIOS emulation to boot legacy systems
Message-ID:  <CALG4x-UYQjiuyVA73KBN671fpLYEWjoDy7n-=%2BAEC1M0D91fuA@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
* project summary
The project goal is to support BIOS emulation on BHyVe, enabling boot
from disk image.
I going to focus booting FreeBSD/amd64 from disk image on this GSoC,
but final goal is to make BHyVe able to support more guest OSes.

* Implementing & testing real mode interrupt handler
Implementing pseudo-BIOS call hander, and Hypercall feature.

I decided to change pseudo BIOS design, I suggested to use registers
to notify INT number for hypervisor, but it doesn't required since
each interrupt handler has different address.

Even if we will use Hypercall for different purpose in future, it stil
can determine which is pseudo-BIOS call and which is not, because we
can define "all Hypercall(not pseudo-BIOS call) must use protected
mode".

So all we have to execute in pseudo BIOS call handler is:

    vmcall
    iret

That's it.

Then,
1. bhyve handle VMCALL
2. calculate INT number from GUEST_RIP
3. call vm_get_register() to get BIOS call arguments
4. perform BIOS call emulation
5. call vm_set_register() to set return value
6. restart VM
7. CPU invokes iret

No need to push/pop registers on stack in guest mode.

I made boot sector image for testing, which sets values on registers,
and calls INT instruction.
And modify /usr/sbin/bhyvebiosload to load boot sector of disk image,
append debug prints on /usr/sbin/bhyve to print out register dumps and
interrupt number.

bootsector image includes these codes:
	mov $0x1, %ax
	mov $0x2, %bx
	mov $0x3, %cx
	mov $0x4, %dx
	int $0x13
	int $0x14

And here's running image:
$ sudo bhyvebiosload -d ~/testbootsect/testbootsect.bin -m 128 -M 256 vm0
$ sudo bhyve -b -m 128 -M 256 vm0
VMCALL handled
rsp=7ff8 rip=44c rax=1 rbx=2 rcx=3 rdx=4
intr=19
$ sudo vmmctl --vm=vm0 --get-all
lowmem		0x0000000100000000/134217728
highmem		0x0000000108000000/268435456
efer[0]		0x0000000000000901
cr0[0]		0x0000000000000030
cr3[0]		0x0000000000000000
cr4[0]		0x0000000000002000
dr7[0]		0x0000000000000000
rsp[0]		0x0000000000007ff8
rip[0]		0x000000000000044c
rax[0]		0x0000000000000001
rbx[0]		0x0000000000000002
rcx[0]		0x0000000000000003
rdx[0]		0x0000000000000004
rsi[0]		0x0000000000000000
rdi[0]		0x0000000000000000
rbp[0]		0x0000000000000000
r8[0]		0x0000000000000000
r9[0]		0x0000000000000000
r10[0]		0x0000000000000000
r11[0]		0x0000000000000000
r12[0]		0x0000000000000000
r13[0]		0x0000000000000000
r14[0]		0x0000000000000000
r15[0]		0x0000000000000000
rflags[0]	0x0000000000000002
vcpu0
vcpu migration across host cpus 	1
vcpu total runtime              	78142
vm exits due to external interrupt	0
ds desc[0]	0x0000000000000000/0x0000ffff/0x00000093
es desc[0]	0x0000000000000000/0x0000ffff/0x00000093
fs desc[0]	0x0000000000000000/0x0000ffff/0x00000093
gs desc[0]	0x0000000000000000/0x0000ffff/0x00000093
ss desc[0]	0x0000000000000000/0x0000ffff/0x00000093
cs desc[0]	0x0000000000000000/0x0000ffff/0x00000093
tr desc[0]	0x0000000000000000/0x0000ffff/0x00000083
ldtr desc[0]	0x0000000000000000/0x0000ffff/0x00000082
gdtr[0]		0x0000000000000000/0x0000ffff
idtr[0]		0x0000000000000000/0x0000ffff
cs[0]		0x0000
ds[0]		0x0000
es[0]		0x0000
fs[0]		0x0000
gs[0]		0x0000
ss[0]		0x0000
tr[0]		0x0000
ldtr[0]		0x0000
pincpu[0]	unpinned
pinbased_ctls[0]	0x0000003f
procbased_ctls[0]	0x95006172
procbased_ctls2[0]	0x000000a2
gla[0]		0x0000000000000000
gpa[0]		0x0000000000000000
entry_interruption_info[0]	0x00000000
eptp[0]		0x00000000aaae901e
exception_bitmap[0]	0x00040000
io_bitmap_a[0]	0x00000000
io_bitmap_b[0]	0x00000000
tsc_offset[0]	0x0000000000000000
cr0_mask[0]		0xffffffff60000020
cr0_shadow[0]		0x0000000000000020
cr4_mask[0]		0x0000000000000000
cr4_shadow[0]		0x0000000000000000
cr3_target_count[0]	0x00000000
cr3_target0[0]		0x0000000000000000
cr3_target1[0]		0x0000000000000000
cr3_target2[0]		0x0000000000000000
cr3_target3[0]		0x0000000000000000
apic_access_addr[0]	0x0000000000000000
virtual_apic_addr[0]	0x0000000000000000
tpr_threshold[0]	0x00000000
msr_bitmap[0]		0x00000000aaaf2000
msr 0xc0000080[0]		RW
msr 0xc0000100[0]		RW
msr 0xc0000101[0]		RW
msr 0xc0000102[0]		RW
msr 0x00000277[0]		RW
vpid[0]		0x0081
ple_window[0]		0x00000000
ple_gap[0]		0x00000000
instruction_error[0]	0x00000000
exit_ctls[0]		0x003f6ffb
entry_ctls[0]		0x000051fb
host_pat[0]		0x0001050600070406
guest_pat[0]		0x0007040600070406
host_cr0[0]		0x0000000080050033
host_cr3[0]		0x000000001e671000
host_cr4[0]		0x00000000000026f0
host_rip[0]		0xffffffff81812090
host_rip[0]		0xffffff8002af5000
guest_sysenter_cs[0]	0x00000000
guest_sysenter_sp[0]	0x0000000000000000
guest_sysenter_ip[0]	0x0000000000000000
vmcs_pointer[0]	0xffffffffffffffff
vmcs_exit_reason[0]	0x0000000000000012
vmcs_exit_qualification[0]	0x0000000000000000
vmcs_exit_interruption_info[0]	0x00000000
vmcs_exit_interruption_error[0]	0x00000000
vmcs_guest_interruptibility[0]	0x00000000
errno = 22

19 is 0x13, so we succeeded to handle "int $0x13" instruction.
Returning to guest is not yet tested.

svn diff -r238305:238881
https://socsvn.freebsd.org/socsvn/soc2012/syuu/bhyve-bios



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CALG4x-UYQjiuyVA73KBN671fpLYEWjoDy7n-=%2BAEC1M0D91fuA>