BHyVe BIOS emulation to boot legacy systems
Short description: Implement BIOS emulation on BHyVe hypervisor, to make BHyVe able to support more guest OSes.
Applications without contact details will be marked invalid.
Project Title: BHyVe BIOS emulation to boot legacy systems
Name: Takuya ASADA
Languages (spoken and written): Japanese, English
I can spend 20-30 hours per week.
I also need to work on a research project in a university.
OpenBSD developer, Ph. D. student in Tokyo University of Technology.
I had worked at an embedded software company for 3 year, at that time I mainly worked on SMP and 64bit support for NetBSD based router firmware.
Using the knowledge gained, I become OpenBSD developer and contributed SMP support for OpenBSD/sgi port.
I gave presentation on AsiaBSDCon 2010 about the work:
I also working on OpenBSD porting project for Cavium OCTEON, which is MIPS architecture based multicore SoC for network appliance.
I've been researching Network I/O performance and parallelizing in university, writing small articles on my blog frequently:
Gave a presentation about modern Network I/O in Japan Vyatta User Group meeting:
Gave a presentation about Network I/O on virtualized enviroment in Internet Week 2011(The conference organized by JPNIC):
Participated GSoC 2011, implemented "Multiqueue BPF support" for FreeBSD:
Possible Mentor: Peter Grehan
Current BHyVe implementation only support FreeBSD/amd64 as a guest OS.
One of the reason BHyVe doesn't support more guest OS is, BHyVe cannot boot guest OSes from disk image.
We need to implement custom guest OS loader for each OSes instead.
That's because BHyVe doesn't have BIOS emulation.
To implement BIOS emulation, we will use "VMX Unrestricted mode support" feature which is supported on Westmere models and beyond. It allows 16-bit guests to run in VMX non-root mode, we don't need to have a instruction emulation code on BHyVe for real mode.
The project goal is booting FreeBSD/amd64 guest from disk image on BHyVe, but once the implementation will worked, porting the guest OSes on BHyVe will be lot more easier than today.
The project steps are:
* defining hypercall interface for BHyVe guest
- we going to use hypercall notifying BIOS call request to BHyVe hypervisor.
- hypercall will issue when guest invoke VMCALL instruction.
- here is an interface of the hypercall:
- DX: hypercall function number. we will define function 0x0 = "BIOS call".
- other registers: can use for hypercall function arguments. we will use them for passing BIOS call arguments, and interrupt number(via CX).
* implement hypercall trap handler on vmm.ko
- add VM_EXITCODE_HYPERCALL on sys/amd64/include/vmm.h.
- handle EXIT_REASON_VMCALL in vmx_exit_process(), return to user mode with vmexit->exitcode = VM_EXITCODE_HYPERCALL.
- add "#define VM_HYPERCALL_BIOSCALL 0x0" in sys/amd64/include/vmm.h.
* implement pseudo BIOS
- pseudo BIOS provides real mode interrupt vector table and software interrupt(BIOS call) handler code for guest enviroment.
The handler code doesn't actually contain BIOS call handling program, it just invokes hypercall using VMCALL instruction.
The instruction will issue VMExit, and BIOS call will handle in BHyVe hypervisor.
- actual handler code will like this:
xor dx, dx
mov cx, 13h
* implement new loader for BIOS emulation boot (usr.sbin/bhyvebiosload)
- fork from use.sbin/bhyveload.
- load boot sector on MBR of disk image, copy it to the guest memory space.
(copy 0x0 - 0x1be from disk image to 0000:07c00h)
- load pseudo BIOS image to guest memory space.
- setup BIOS data area(0040:0000h) on guest memory space.
- set hypercall function number to BIOS call:
vm_set_register(ctp, BSP, VM_REG_GUEST_RDX, VM_HYPERCALL_BIOSCALL)
* implement BIOS emulation mode on usr.sbin/bhyve
- add new argument "-b" to toggle BIOS emulation mode.
- enable unrestricted guest mode on cpu0 in initialization stage.
it will call these functions:
vm_set_capability(ctp, BSP, VM_CAP_UNRESTRICTED_GUEST, 1) vm_set_register(ctp, BSP, VM_REG_GUEST_RIP, 0x7c00) vm_set_register(ctp, BSP, VM_REG_GUEST_CS, 0x0) - if vm_set_capability() fails, BIOS emulation mode should exit with error message.
- add handler for VM_EXITCODE_HYPERCALL, named it vmexit_hypercall().
- vmexit_hypercall() fetch hypercall function number by vm_get_register(RDX).
if ((uint8_t)rdx) == VM_HYPERCALL_BIOS, then get interrupt number vm_get_register(RCX). restore DX and CX value from guest stack if necessary, emulate requested BIOS call, write return value on register using vm_set_register().
* BIOS call implementation plan
- On this project we'll focus to boot FreeBSD/amd64, so we won't implement *all* BIOS call, but will implement necessary BIOS call for it.
This paper describes what BIOS routines called in FreeBSD boot process:
I pickup required BIOS call from the paper, here's a list:
10h 02h n/a Set Cursor Position
10h 03h n/a Read Cursor Position and Type
10h 06h n/a Scroll Active Page Up
10h 08h n/a Read Character and Attribute
10h 09h n/a Write Character and Attribute
10h 0Eh Write Character in Teletype Mode
12h 88h Base Memory Size
13h 00h Disk Controller Reset
13h 02h Read Disk Sectors
13h 03h Write Disk Sectors
13h 08h Read Disk Drive Parameters
13h 41h Check If Extensions Present
13h 42h Extended Read Sectors
13h 43h Extended Write Sectors
13h 4Bh 01h Terminate Disk Emulation
14h 00h Initialize Serial Port
14h 01h Send Byte
14h 02h Receive Byte
14h 03h Read Status
15h 86h n/a Wait
15h 88h Extended Memory Size
15h E8h 01h Get Extended Memory Info
15h E8h 20h Get System Memory Map
16h 00h Read Keyboard Input
16h 01h Check Keyboard Status
1Ah 00h Get System Time
1Ah 02h n/a Read CMOS Time
Note that maybe we don't have to support both video/keyboard and serial.
We're still considering witch to use, if we choose video/keyboard then we won't need 14h(serial).
Or if we choose serial, maybe we won't need 10h(video) and 16h(keyboard).
- Considering to take some code from "doscmd", BSD Licensed DOS emulator, to implement these BIOS calls.
* BIOS data area implementation plan:
- Pickup from same paper on above:
40:13h Main Memory Size
40:17h Keyboard Shift Flags 1
40:49h Video Mode
40:50h Video: Cursor Position Page 0
40:72h Warm Boot Flag
Considering to setup static values for these parameters, will be done in "bhyvebiosload".
- Considering to take some code from "doscmd", too.
Milestone 1: week 1
- implement hypercall interface on vmm.ko
Milestone 2: week 2
- implement hypercall caller test code on guest kernel
- implement hypercall callee test code on /usr/sbin/bhyve
- test it
Milestone 3: week 3
- implement pseudo BIOS
Milestone 4: week 4
- implement /usr/sbin/bhyvebiosload
Milestone 5: week 5
- implement BIOS emulation mode on /usr/sbin/bhyve
- "-b" argument
- cpu0 initialization
- handle VM_HYPERCALL_BIOS in vmexit_hypercall()
Milestone 6: week 6
- implement BIOS call caller test code on disk image
- implement BIOS call callee test code on /usr/sbin/bhyvebiosload
- test it
Milestone 7: week 7
- implement BIOS console output (10h or 14h)
- implement "Hello World!" test code on disk image
- test it
Milestone 8: week 8 (mid-term)
- implement BIOS console input (14h or 16h)
- implement echo console test code on disk image
- test it
Milestone 9: week 9
- implement BIOS disk IO(13h)
- implement disk IO test code on disk image
- test it
Milestone 10: week 10
- implement other BIOS calls(12h, 15h, 1Ah)
- test it
Milestone 11: week 11
- implement BIOS data area loader on /usr/sbin/bhyvebiosload
- test it
Milestone 12: week 12-13 (pencil down)
- test FreeBSD/amd64 disk image