VirtualBox Guest Additions: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
m Bot: Replace deprecated source tag with syntaxhighlight
 
(21 intermediate revisions by 6 users not shown)
Line 11:
Pseudo-code examples in the following sections will assume the availability of these functions; adjust them to match your environment:
 
<sourcesyntaxhighlight lang="c">
void * allocate_physical_page(uint32_t * physical); // Allocate one page of memory, providing its physical address as an output and virtual address as a return value.
void * map_physical_pageallocate_physical_page(uint32_t * physical); // Map a physical page into the virtual memory space.
// Map a physical page into the virtual memory space.
void install_interrupt_handler(irq, int (*irq_function)(void)); // Install an interrupt request handler function.
void * map_physical_page(uint32_t physical);
void outportl(port, value); // Write a 32-bit value to an MMIO port.
// Install an interrupt request handler function.
void outports(port, value); // Write a 16-bit value to an MMIO port.
void install_interrupt_handler(irq, int (*irq_function)(void));
pci_device_t pci_find(vendor,device); // Return an object describing the requested PCI device, if found.
// Write a 32-bit value to an MMIO port.
uint32_t pci_read_field(pci_device_t device, field, size); // Read a field from the given PCI device
void outportl(port, value);
</source>
// Write a 16-bit value to an MMIO port.
void outports(port, value);
// Return an object describing the requested PCI device, if found.
pci_device_t pci_find(vendor,device);
// Read a field from the given PCI device
uint32_t pci_read_field(pci_device_t device, field, size);
</syntaxhighlight>
 
== Initializing the Device ==
Line 25 ⟶ 32:
Before we can do anything with the guest device, we need to tell it about ourselves. There are two protocols that current versions of VirtualBox support: 1.03 and 1.04. We will use 1.03, the so-called "Legacy Protocol", as it is slightly simpler.
 
<sourcesyntaxhighlight lang="c">
#define VBOX_VENDOR_ID 0x80EE
#define VBOX_DEVICE_ID 0xCAFE
Line 59 ⟶ 66:
/* BAR0 is the IO port. */
vbox_port = pci_read_field(vbox_pci, PCI_BAR0, 4) & 0xFFFFFFF00xFFFFFFFC;
 
/* BAR1 is the memory-mapped "vmmdevmem" area. */
Line 83 ⟶ 90:
/* (We could check the return value here as well) */
}
</syntaxhighlight>
</source>
 
 
Line 91 ⟶ 98:
We'll need to define some new packets, install an interrupt handler, and also set some bits in the VMMDevMem space.
 
<sourcesyntaxhighlight lang="c">
#define VBOX_REQUEST_ACK_EVENTS 41
#define VBOX_REQUEST_GET_DISPLAY_CHANGE 51
Line 125 ⟶ 132:
/* Adjust as necessary for your interrupt handling. */
static int vbox_irq_handler(struct regs * r) {
if (!vbox_vmmdev[2]) return 0; /* Nothing to process? Maybe this interrupt was from something sharing the line. */
outportl(vbox_port, vbox_display_phys); /* Request display change information. */
 
vbox_ack->events = vbox_vmmdev[2];
outportl(vbox_port, vbox_ack_phys); /* Acknowledge events */
 
outportl(vbox_port, vbox_display_phys); /* Request display change information. */
 
/* vbox_display now has information on our display size. If it changed we can tell our display driver to update. */
Line 185 ⟶ 196:
vbox_vmmdev[3] = 0xFFFFFFFF;
}
</syntaxhighlight>
</source>
 
== Mouse Integration ==
Line 192 ⟶ 203:
Mouse Integration operates entirely over the guest device. Once enabled, mouse movements are sent to the guest through mouse packet requests and a corresponding interrupt. It is important to note that the format of the coordinates in these packets is based on a range from 0 to 0xFFFF which needs to be scaled to the display resolution. Why this approach was taken over using actual pixel coordinates (scaled or otherwise) is unknown.
 
<sourcesyntaxhighlight lang="c">
#define VBOX_REQUEST_GET_MOUSE 1
#define VBOX_REQUEST_SET_MOUSE 2
Line 226 ⟶ 237:
...
 
vbox_mouse = allocate_physical_page(void*)kvmalloc_p(0x1000, &vbox_mouse_phys);
vbox_mouse->header.size = sizeof(struct vbox_mouse_absolute);
vbox_mouse->header.version = VBOX_REQUEST_HEADER_VERSION;
Line 233 ⟶ 244:
vbox_mouse->header.reserved1 = 0;
vbox_mouse->header.reserved2 = 0;
vbox_mouse->features = (1 << 0) | (1 << 4); /* bit 0 says "guest supports (and wants) absolute mouse"; bit 4 says we'll query absolute positions on interrupts */
vbox_mouse->x = 0;
vbox_mouse->y = 0;
Line 242 ⟶ 253:
...
}
</syntaxhighlight>
</source>
 
== Seamless Desktop ==
 
The seamless desktop mode in VirtualBox works by sending the virtual machine a list of rectangles representing the non-background visible regions of the desktop. The host creates a borderless, maximized window and shapes it based on the rectangles provided by the guest, yielding the appearance of a seamless desktop. You can tie this into a driver that receives window bounds information from your GUI. Note that seamless works best with (and maybe requires?) Auto-Resize Guest Display support.
 
<syntaxhighlight lang="c">
 
#define VBOX_REQUEST_SET_VISIBLE_REGION 71
 
struct vbox_rtrect {
int32_t xLeft;
int32_t yTop;
int32_t xRight;
int32_t yBottom;
}
 
struct vbox_visibleregion {
struct vbox_header header;
uint32_t count;
struct vbox_rtrect rect[];
}
 
static uint32_t vbox_visibleregion_phys;
static vbox_visibleregion * vbox_visibleregion;
 
...
 
static void vbox_set_visible_region(uint32_t count, ...) {
vbox_visibleregion = allocate_physical_page(&vbox_visibleregion_phys);
vbox_visibleregion->header.size = sizeof(struct vbox_visibleregion) + sizeof(vbox_rtrect) * count;
vbox_visibleregion->header.version = VBOX_REQUEST_HEADER_VERSION;
vbox_visibleregion->header.requestType = VBOX_REQUEST_SET_VISIBLE_REGION;
vbox_visibleregion->header.rc = 0;
vbox_visibleregion->header.reserved1 = 0;
vbox_visibleregion->header.reserved2 = 0;
vbox_visibleregion->count = count;
 
/* Set each of the rectangles... */
vbox_visibleregion->rect[i].xLeft = ...;
/* etc */
outportl(vbox_port, vbox_visibleregion_phys);
}
 
</syntaxhighlight>
 
''There is an additional interface for the seamless mode using the (undocumented) host-guest communication interface. In the case of the seamless mode, this functionality only communicates whether the seamless mode has been requested and is not necessary for it to function.''
 
''There are also hints in the VirtualBox codebase that a direct guest-host window mapping feature was planned but has not been implemented. This would presumably allow the guest to provide separate textures for each window, possibly alongside window title and icon information...''
 
== Pointer Shape ==
 
The Pointer Shape functionality allows you to send a mouse cursor texture to the host, saving you the need to draw it yourself in software. This functionality is especially useful in combination with the Seamless mode, as it allows your cursor to be rendered outside of the visible regions. This works with the absolute mouse functionality so there is no need to inform the host of the mouse cursor position as it already knows.
 
== Shared Folders and Clipboard ==
The virtual Guest Additions PCI device provides access to a service on the host called the Host-Guest Communication Manager (HGCM). This service is responsible for providing functionality for Shared Folders, Shared Clipboard and making configuration changes to the guest itself.
 
All requests to the communication manager are made with the same packet header, and there are 5 values used for the packet type field:
 
{| {{wikitable}}
! Value (decimal)
! Request Type
|-
| 60 || Connect
|-
| 61 || Disconnect
|-
| 62 || Call Function (32-bit)
|-
| 63 || Call Function (64-bit)
|-
| 64 || Cancel Request
|}
 
After the standard Guest Addition Header, each communication manager packet (except the cancel request packet) has a second header, depending on the request type above.
 
=== Connect ===
 
{| {{wikitable}}
! Offset (hex)
! Length
! Description
|-
| 0x20 || 4 || Location Type
|-
| 0x24 || 128 || Location
|-
| 0xA4 || 4 || Client ID
|}
 
The Location field contains the name of the library to connect. There are 4 pre-defined library names: VBoxSharedFolders, VBoxSharedClipboard, VBoxGuestPropSvc, VBoxSharedOpenGL
 
Additional libraries may also be accessed by providing the library name in the Location field.
 
The Location Type field should be set to 1 to connect to an additional library, and 2 to connect to one of the pre-defined libraries.
 
The Client ID is filled by the host after the request is complete. This value should be used in any further calls to this service.
 
=== Disconnect ===
{| {{wikitable}}
! Offset (hex)
! Length
! Description
|-
| 0x20 || 4 || Client ID
|}
 
=== Call Function ===
 
Both the 32-bit and 64-bit call function packets use the same service header, followed by a list of parameter records. 32-bit function parameter records are 12 bytes long, and 64-bit function parameter records are 16 bytes long.
 
{| {{wikitable}}
! Offset (hex)
! Length
! Description
|-
| 0x20 || 4 || Type
|-
| 0x24 || 4 || Client ID
|-
| 0x28 || 4 || Function Code
|-
| 0x2c || 4 || Parameter Count
|-
| 0x30 || * || Parameters
|}
 
 
==== 32-bit Parameter ====
{| {{wikitable}}
! Offset (hex)
! Length
! Description
|-
| 0x00 || 4 || Type
|-
| 0x04 || 8 || Value
|}
 
==== 64-bit Parameter ====
{| {{wikitable}}
! Offset (hex)
! Length
! Description
|-
| 0x00 || 4 || Type
|-
| 0x04 || 12 || Value
|}
 
==== Parameter Types ====
{| {{wikitable}}
! Value (decimal)
! Request Type
|-
| 1 || 32-bit Value
|-
| 2 || 64-bit Value
|-
| 3 || Physical Address
|-
| 4 || Linear Address
|-
| 5 || Linear Address (Host-to-Guest only)
|-
| 6 || Linear Address (Guest-to-Host only)
|-
| 7 || Linear Address (Pre-Locked by Guest)
|-
| 8 || Linear Address (Host-to-Guest only, Pre-Locked by Guest)
|-
| 9 || Linear Address (Guest-to-Host only, Pre-Locked by Guest)
|}
 
Physical and Linear Address parameter values have the following structure:
 
{| {{wikitable}}
! Offset (hex)
! Length
! Description
|-
| 0x00 || 4 || Buffer Length
|-
| 0x04 || 4/8 || Address (32-Bit/64-Bit)
|}
 
=== Functions ===
{| {{wikitable}}
! Value (decimal)
! Function
! Parameters
|-
| 1 || Query Mappings || 3
|-
| 2 || Query Map Name || 2
|-
| 3 || Create Handle || 3
|-
| 4 || Close Handle || 2
|-
| 5 || Read || 5
|-
| 6 || Write || 5
|-
| 7 || Lock || 5
|-
| 8 || List Directory || 8
|-
| 9 || Information || 5
|-
| 11 || Delete || 3
|-
| 14 || Rename || 4
|-
| 15 || Flush || 2
|-
| 24 || Set File Size || 3
|}
 
=== Query Mappings ===
The Query Mappings command returns a list of all of the shared folders configured for this guest. The buffer passed by the guest will be filled with mapping records, and the Count parameter will be set to the number of records returned. The Root value for each record will be used to reference this shared folder in future commands. If the buffer size is insufficient to hold all of the records, the buffer pointer size field will be set to the minimum size necessary to contain the entire list of mapping records. By default, all strings returned by the host will be in UCS2 encoding. Passing the UTF8 flag will force all requests to return strings in UTF8 format. The Automount Only flag will only return shared folders that have been marked as Automount in the guest configuration.
 
{| {{wikitable}}
! Number
! Parameter
! Type
|-
| 1 || Flags || 32-Bit (0 - UCS2, 1 - UTF8, 2 - Automount Only)
|-
| 2 || Count || 32-Bit
|-
| 3 || Buffer || Pointer
|}
 
==== Mapping Record ====
{| {{wikitable}}
! Offset (hex)
! Length
! Description
|-
| 0x00 || 4 || Flags (1 - New, 2 - Deleted)
|-
| 0x04 || 4 || Root
|}
 
 
=== Query Map Name ===
The Query Map Name command will return the name for the specified shared folder in the guest configuration.
 
{| {{wikitable}}
! Number
! Parameter
! Type
|-
| 1 || Root || 32-Bit
|-
| 2 || Buffer || Pointer
|}
 
 
== Other Stuff ==
VirtualBox also provides a mechanism for writing to its log files, though this is not managed through the guest device. Simple writing bytes to port 0x504 will produce log entries. The capability bit for this functionality is bit 0.
 
 
==See Also==
 
===External Links===
*[https://github.com/klange/toaruos/blob/master/modules/vbox.c ToaruOS VirtualBox guest driver]
*[https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Devices/VMMDev/VMMDev.cpp VirtualBox host implementation of the guest additions]
*[https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Additions VirtualBox guest implementations]
*[https://www.virtualbox.org/wiki/Technical_documentation VirtualBox Technical Documentation (SDK)]
 
[[Category:Emulators]]