VBoxBFE.cpp revision 2d269b9d4acadc069e0136446af1d75721aa63f5
/* $Id$ */
/** @file
* Basic Frontend (BFE): VBoxBFE main routines.
*
* VBoxBFE is a limited frontend that sits directly on the Virtual Machine
* Manager (VMM) and does _not_ use COM to communicate.
* On Linux and Windows, VBoxBFE is based on SDL; on L4 it's based on the
* L4 console. Much of the code has been copied over from the other frontends
*/
/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_GUI
#ifndef VBOXBFE_WITHOUT_COM
using namespace com;
#endif
#ifdef VBOXBFE_WITH_USB
#endif
#ifdef VBOX_WITH_HGCM
#endif
#include <iprt/initterm.h>
#include <iprt/semaphore.h>
#include "VBoxBFE.h"
#include <stdio.h>
#include <stdlib.h> /* putenv */
#include <errno.h>
#if defined(RT_OS_LINUX) || defined(RT_OS_L4)
#include <fcntl.h>
#endif
#include "ConsoleImpl.h"
#include "DisplayImpl.h"
#include "MouseImpl.h"
#include "KeyboardImpl.h"
#include "VMMDevInterface.h"
#include "StatusImpl.h"
#include "Framebuffer.h"
#include "MachineDebuggerImpl.h"
#ifdef VBOXBFE_WITH_USB
# include "HostUSBImpl.h"
#endif
#include "SDLConsole.h"
#include "SDLFramebuffer.h"
#endif
#ifdef RT_OS_L4
#include "L4Console.h"
#include "L4Framebuffer.h"
#include "L4IDLInterface.h"
#endif
#ifdef RT_OS_L4
#endif
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
#define VBOXSDL_ADVANCED_OPTIONS
#define MAC_STRING_LEN 12
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
static DECLCALLBACK(void) vmstateChangeCallback(PVM pVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser);
/*******************************************************************************
* Global Variables *
*******************************************************************************/
#ifdef VBOXBFE_WITH_USB
#endif
#ifdef RT_OS_L4
int gHostKey; /* not used */
int gHostKeySym = KEY_RIGHTCTRL;
#elif defined (DEBUG_dmik)
// my mini kbd doesn't have RCTRL...
int gHostKey = KMOD_RSHIFT;
int gHostKeySym = SDLK_RSHIFT;
#else
int gHostKey = KMOD_RCTRL;
int gHostKeySym = SDLK_RCTRL;
#endif
bool gfAllowFullscreenToggle = true;
static bool g_fIOAPIC = false;
static bool g_fACPI = true;
static bool g_fAudio = false;
#ifdef VBOXBFE_WITH_USB
static bool g_fUSB = false;
#endif
static char *g_pszHdaFile = NULL;
static bool g_fHdaSpf = false;
static char *g_pszHdbFile = NULL;
static bool g_fHdbSpf = false;
static char *g_pszCdromFile = NULL;
static char *g_pszFdaFile = NULL;
const char *g_pszStateFile = NULL;
static const char *g_pszBootDevice = "IDE";
#ifdef VBOXSDL_ADVANCED_OPTIONS
static bool g_fRawR0 = true;
static bool g_fRawR3 = true;
static bool g_fPATM = true;
static bool g_fCSAM = true;
#endif
static bool g_fRestoreState = false;
static const char *g_pszShareDir[MaxSharedFolders];
static const char *g_pszShareName[MaxSharedFolders];
static bool g_fShareReadOnly[MaxSharedFolders];
static unsigned g_uNumShares;
static bool g_fPreAllocRam = false;
static int g_iBootMenu = 2;
static bool g_fReleaseLog = true; /**< Set if we should open the release. */
const char *g_pszProgressString;
unsigned g_uProgressPercent = ~0U;
/**
* Network device config info.
*/
typedef struct BFENetworkDevice
{
enum
{
NOT_CONFIGURED = 0,
NONE,
NAT,
HIF,
} enmType; /**< The type of network driver. */
bool fSniff; /**< Set if the network sniffer should be installed. */
const char *pszSniff; /**< Output file for the network sniffer. */
const char *pszName; /**< The device name of a HIF device. The name of the internal network. */
#ifdef RT_OS_OS2
bool fHaveConnectTo; /**< Whether fConnectTo is set. */
bool fHaveFd; /**< Set if fd is valid. */
#endif
} BFENETDEV, *PBFENETDEV;
/** Array of network device configurations. */
/** @todo currently this is only set but never read. */
static char szError[512];
/**
*/
bool fActivateHGCM()
{
return !!(g_uNumShares > 0);
}
/**
* Converts the passed in network option
*
* @returns Index into g_aNetDevs on success. (positive)
* @returns VERR_INVALID_PARAMETER on failure. (negative)
* @param pszArg The argument.
* @param cchRoot The length of the argument root.
*/
{
uint32_t n;
if (RT_FAILURE(rc))
{
return -1;
}
if (n < 1 || n > NetworkAdapterCount)
{
RTPrintf("Error: The network device number is out of range: %RU32 (1 <= 0 <= %u) (%s)\n",
n, NetworkAdapterCount, pszArg);
return -1;
}
return n;
}
/**
* Generates a new unique MAC address based on our vendor ID and
* parts of a GUID.
*
* @returns iprt status code
* @param pAddress An array into which to store the newly generated address
*/
{
/*
* Our strategy is as follows: the first three bytes are our fixed
* vendor ID (080027). The remaining 3 bytes will be taken from the
* start of a GUID. This is a fairly safe algorithm.
*/
LogFlowFunc(("called\n"));
if (RT_FAILURE(rc))
{
return rc;
}
return VINF_SUCCESS;
}
/**
* Print a syntax error.
*
* @returns return value for main().
* @param pszMsg The message format string.
* @param ... Format arguments.
*/
static int SyntaxError(const char *pszMsg, ...)
{
RTPrintf("error: ");
return 1;
}
/**
* Print a fatal error.
*
* @returns return value for main().
* @param pszMsg The message format string.
* @param ... Format arguments.
*/
static int FatalError(const char *pszMsg, ...)
{
RTPrintf("fatal error: ");
return 1;
}
/**
* Start progress display.
*/
void startProgressInfo(const char *pszStr)
{
g_uProgressPercent = 0;
}
/**
* Update progress display.
*/
{
if (gConsole)
}
/**
* End progress display.
*/
void endProgressInfo(void)
{
g_uProgressPercent = ~0U;
}
/**
* Print program usage.
*/
static void show_usage()
{
RTPrintf("Usage:\n"
" -hda <file> Set first hard disk to file\n"
" -hdb <file> Set second hard disk to file\n"
" -fda <file> Set first floppy disk to file\n"
" -boot <a|c|d> Set boot device (a = floppy, c = first hard disk, d = DVD)\n"
" -boot menu <0|1|2> Boot menu (0 = disable, 1 = menu only, 2 = message + menu)\n"
" -m <size> Set memory size in megabytes (default 128MB)\n"
" -vram <size> Set size of video memory in megabytes\n"
" -prealloc Force RAM pre-allocation\n"
" -fullscreen Start VM in fullscreen mode\n"
" -restore Restore the VM if the statefile exists, normal start otherwise\n"
" -share <dir> <name> [readonly]\n"
" Share directory <dir> as name <name>. Optionally read-only.\n"
" -nohostkey Disable hostkey\n"
" -[no]acpi Enable or disable ACPI (default: enabled)\n"
" -[no]ioapic Enable or disable the IO-APIC (default: disabled)\n"
" -audio Enable audio\n"
#ifndef RT_OS_L4
" -natdev<1-N> [mac] Use NAT networking on network adapter <N>. Use hardware\n"
" address <mac> if specified.\n"
#endif
" -hifdev<1-N> Use Host Interface Networking with host interface <int>\n"
" <int> [mac] on network adapter <N>. Use hardware address <mac> if\n"
" specified.\n"
#ifndef RT_OS_L4
" -intnet<1-N> Attach network adapter <N> to internal network <net>. Use\n"
" <net> [mac] hardware address <mac> if specified.\n"
#endif
#if 0
" -netsniff<1-N> Enable packet sniffer\n"
#endif
#ifdef RT_OS_OS2
" -brdev<1-N> lan<X> Bridge network adaptor <N> with the 'lanX' device.\n"
#endif
#ifdef RT_OS_LINUX
" -tapfd<1-N> <fd> Use existing TAP device, don't allocate\n"
#endif
#ifdef VBOX_WITH_VRDP
" -vrdp [port] Listen for VRDP connections on port (default if not specified)\n"
#endif
#ifdef VBOX_SECURELABEL
" -securelabel Display a secure VM label at the top of the screen\n"
" -seclabelfnt TrueType (.ttf) font file for secure session label\n"
" -seclabelsiz Font point size for secure session label (default 12)\n"
#endif
" -[no]rellog Enable or disable the release log './VBoxBFE.log' (default: enabled)\n"
#ifdef VBOXSDL_ADVANCED_OPTIONS
" -[no]rawr0 Enable or disable raw ring 3\n"
" -[no]rawr3 Enable or disable raw ring 0\n"
" -[no]patm Enable or disable PATM\n"
" -[no]csam Enable or disable CSAM\n"
#endif
#ifdef RT_OS_L4
" -env <var=value> Set the given environment variable to \"value\"\n"
#endif
"\n");
}
/** entry point */
{
bool fFullscreen = false;
#ifdef VBOX_WITH_VRDP
#endif
#ifdef VBOX_SECURELABEL
bool fSecureLabel = false;
char *secureLabelFontFile = NULL;
#endif
#ifdef RT_OS_L4
#endif
int rc = VINF_SUCCESS;
// less than one parameter is not possible
if (argc < 2)
{
show_usage();
return 1;
}
/*
* Parse the command line arguments.
*/
{
{
return SyntaxError("missing argument for boot drive!\n");
rc = VINF_SUCCESS;
{
case 'a':
{
g_pszBootDevice = "FLOPPY";
break;
}
case 'c':
{
g_pszBootDevice = "IDE";
break;
}
case 'd':
{
g_pszBootDevice = "DVD";
break;
}
default:
}
}
{
return SyntaxError("missing argument for boot menu!\n");
rc = VINF_SUCCESS;
}
{
return SyntaxError("missing argument for memory size!\n");
if (RT_FAILURE(rc))
return SyntaxError("bad memory size: %s (error %Rrc)\n",
}
{
return SyntaxError("missing argument for vram size!\n");
if (RT_FAILURE(rc))
return SyntaxError("bad video ram size: %s (error %Rrc)\n",
}
{
return SyntaxError("missing argument for restore!\n");
}
g_fRestoreState = true;
{
if (g_uNumShares >= MaxSharedFolders)
return SyntaxError("too many shared folders specified!\n");
return SyntaxError("missing 1s argument for share!\n");
return SyntaxError("missing 2nd argument for share!\n");
{
g_fShareReadOnly[g_uNumShares] = true;
curArg++;
}
g_uNumShares++;
}
fFullscreen = true;
gfAllowFullscreenToggle = false;
{
gHostKey = 0;
gHostKeySym = 0;
}
g_fACPI = true;
g_fACPI = false;
g_fIOAPIC = true;
g_fIOAPIC = false;
g_fAudio = true;
#ifdef VBOXBFE_WITH_USB
g_fUSB = true;
#endif
{
return SyntaxError("missing file name for first hard disk!\n");
/* resolve it. */
if (!g_pszHdaFile)
return SyntaxError("The path to the specified harddisk, '%s', could not be resolved.\n", argv[curArg]);
}
{
g_fHdaSpf = true;
}
{
return SyntaxError("missing file name for second hard disk!\n");
/* resolve it. */
if (!g_pszHdbFile)
return SyntaxError("The path to the specified harddisk, '%s', could not be resolved.\n", argv[curArg]);
}
{
g_fHdbSpf = true;
}
{
return SyntaxError("missing file/device name for first floppy disk!\n");
/* resolve it. */
if (!g_pszFdaFile)
return SyntaxError("The path to the specified floppy disk, '%s', could not be resolved.\n", argv[curArg]);
}
{
return SyntaxError("missing file/device name for first hard disk!\n");
/* resolve it. */
if (!g_pszCdromFile)
return SyntaxError("The path to the specified cdrom, '%s', could not be resolved.\n", argv[curArg]);
}
#ifdef RT_OS_L4
/* This is leaving a lot of dead code in the L4 version of course,
but I don't think that that is a major problem. We may even
activate it sometime... */
#else
#endif
{
if (i < 0)
return 1;
/* The HIF device name / The Internal Network name. */
{
? "The TAP network device name is missing! (%s)\n"
: "The internal network name is missing! (%s)\n"
, pszArg);
}
/* The MAC address. */
const char *pszMac;
else
{
if (RT_FAILURE(rc))
return SyntaxError("failed to generate a hardware address for network device %d (error %Rrc)\n",
i, rc);
}
{
if (c1 > 9)
c1 -= 7;
if (c2 > 9)
c2 -= 7;
}
}
{
if (i < 0)
return 1;
g_aNetDevs[i].fSniff = true;
/** @todo filename */
}
#ifdef RT_OS_OS2
{
if (i < 0)
return 1;
return SyntaxError("%d is not a hif device! Make sure you put the -hifdev argument first.\n", i);
return SyntaxError("bad interface name '%s' specified with '%s'. Expected 'lan0', 'lan1' and similar.\n",
g_aNetDevs[i].fHaveConnectTo = true;
}
#endif
#ifdef RT_OS_LINUX
{
if (i < 0)
return 1;
if (RT_FAILURE(rc))
g_aNetDevs[i].fHaveFd = true;
}
#endif /* RT_OS_LINUX */
#ifdef VBOX_WITH_VRDP
{
// -vrdp might take a port number (positive).
portVRDP = 0; // indicate that it was encountered.
{
if (RT_FAILURE(rc))
}
}
#endif /* VBOX_WITH_VRDP */
#ifdef VBOX_SECURELABEL
{
fSecureLabel = true;
LogFlow(("Secure labelling turned on\n"));
}
{
return SyntaxError("missing font file name for secure label!\n");
}
{
return SyntaxError("missing font point size for secure label!\n");
}
#endif
g_fReleaseLog = true;
g_fReleaseLog = false;
g_fPreAllocRam = true;
#ifdef VBOXSDL_ADVANCED_OPTIONS
g_fRawR0 = true;
g_fRawR0 = false;
g_fRawR3 = true;
g_fRawR3 = false;
g_fPATM = true;
g_fPATM = false;
g_fCSAM = true;
g_fCSAM = false;
#endif /* VBOXSDL_ADVANCED_OPTIONS */
#ifdef RT_OS_L4
++curArg;
#endif /* RT_OS_L4 */
/* just show the help screen */
else
{
show_usage();
return 1;
}
}
gMachineDebugger = new MachineDebugger();
#if defined(USE_SDL)
/* First console, then framebuffer!! */
gConsole = new SDLConsole();
gFramebuffer = new SDLFramebuffer();
gFramebuffer = new L4Framebuffer();
#else
#error "todo"
#endif
if (!gConsole->initialized())
goto leave;
/* start with something in the titlebar */
/*
* Start the VM execution thread. This has to be done
* asynchronously as powering up can take some time
* (accessing devices such as the host DVD drive). In
* the meantime, we have to service the SDL event loop.
*/
if (RT_FAILURE(rc))
{
return -1;
}
#ifdef RT_OS_L4
/* Start the external IDL interface */
L4CtrlInit();
#endif
/* loop until the powerup processing is done */
do
{
#if defined(VBOXBFE_WITH_X11) && defined(USE_SDL)
if ( machineState == VMSTATE_CREATING
|| machineState == VMSTATE_LOADING)
{
switch (event)
{
LogFlow(("CONEVENT_USR_SCREENRESIZE\n"));
gFramebuffer->resize();
/* notify the display that the resize has been completed */
break;
break;
case CONEVENT_USR_QUIT:
RTPrintf("Error: failed to power up VM! No error text available.\n");
goto leave;
}
}
else
#endif
RTThreadSleep(1000);
}
while ( machineState == VMSTATE_CREATING
|| machineState == VMSTATE_LOADING);
if (machineState == VMSTATE_TERMINATED)
goto leave;
/* did the power up succeed? */
if (machineState != VMSTATE_RUNNING)
{
RTPrintf("Error: failed to power up VM! No error text available (rc = 0x%x state = %d)\n", rc, machineState);
goto leave;
}
#ifdef RT_OS_L4
/* The L4 console provides (currently) a fixed resolution. */
* gFramebuffer->getHostYres()
/* Limit the VRAM of the guest to the amount of memory we got actually
* mapped from the L4 console. */
* gFramebuffer->getHostXres()
if (g_u32VRamSize > u32MaxVRAM)
{
}
#endif
/*
* Main event loop
*/
LogFlow(("VBoxSDL: Entering big event loop\n"));
while (1)
{
switch (event)
{
case CONEVENT_NONE:
/* Handled internally */
break;
case CONEVENT_QUIT:
case CONEVENT_USR_QUIT:
goto leave;
case CONEVENT_SCREENUPDATE:
/// @todo that somehow doesn't seem to work!
gFramebuffer->repaint();
break;
break;
{
LogFlow(("CONEVENT_USR_SCREENRESIZE\n"));
gFramebuffer->resize();
/* notify the display that the resize has been completed */
break;
}
#ifdef VBOX_SECURELABEL
{
/*
* Query the new label text
*/
/*
* Now update the label
*/
break;
}
#endif /* VBOX_SECURELABEL */
}
}
LogFlow(("Returning from main()!\n"));
if (pVM)
{
/*
* If get here because the guest terminated using ACPI off we don't have to
* switch off the VM because we were notified via vmstateChangeCallback()
* that this already happened. In any other case stop the VM before killing her.
*/
if (machineState != VMSTATE_OFF)
{
/* Power off VM */
}
/* And destroy it */
}
delete gFramebuffer;
delete gConsole;
delete gDisplay;
delete gKeyboard;
delete gMouse;
delete gStatus;
delete gMachineDebugger;
}
#ifndef VBOX_WITH_HARDENING
/**
* Main entry point.
*/
{
# ifdef RT_OS_L4
# ifndef L4API_l4v2onv4
/* clear Fiasco kernel trace buffer */
# endif
/* set the environment. Must be done before the runtime is
initialised. Yes, it really must. */
for (int i = 0; i < argc; i++)
{
if (++i >= argc)
return SyntaxError("missing argument to -env (format: var=value)!\n");
/* add it to the environment */
}
# endif /* RT_OS_L4 */
/*
* Before we do *anything*, we initialize the runtime.
*/
if (RT_FAILURE(rc))
}
#endif /* !VBOX_WITH_HARDENING */
/**
* VM state callback function. Called by the VMM
* using its state machine states.
*
* Primarily used to handle VM initiated power off, suspend and state saving,
* but also for doing termination completed work (VMSTATE_TERMINATE).
*
* In general this function is called in the context of the EMT.
*
* @todo machineState is set to VMSTATE_RUNNING before all devices have received power on events
* this can prematurely allow the main thread to enter the event loop
*
* @param pVM The VM handle.
* @param enmState The new state.
* @param enmOldState The old state.
* @param pvUser The user argument.
*/
static DECLCALLBACK(void) vmstateChangeCallback(PVM pVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser)
{
switch (enmState)
{
/*
* The VM has terminated
*/
case VMSTATE_OFF:
{
break;
}
/*
* The VM has been completely destroyed.
*
* Note: This state change can happen at two points:
* 1) At the end of VMR3Destroy() if it was not called from EMT.
* 2) At the end of vmR3EmulationThread if VMR3Destroy() was called by EMT.
*/
case VMSTATE_TERMINATED:
{
break;
}
default: /* shut up gcc */
break;
}
}
/**
* VM error callback function. Called by the various VM components.
*
* @param pVM The VM handle.
* @param pvUser The user argument.
* @param rc VBox status code.
* @param pszError Error message format string.
* @param args Error message arguments.
* @thread EMT.
*/
{
/** @todo accessing shared resource without any kind of synchronization */
if (RT_SUCCESS(rc))
szError[0] = '\0';
else
{
}
}
/**
* VM Runtime error callback function. Called by the various VM components.
*
* @param pVM The VM handle.
* @param pvUser The user argument.
* @param fFata Wheather it is a fatal error or not.
* @param pszErrorId Error ID string.
* @param pszError Error message format string.
* @param args Error message arguments.
* @thread EMT.
*/
const char *pszErrorId,
{
}
/** VM asynchronous operations thread */
{
int rc = VINF_SUCCESS;
int rc2;
/*
* Setup the release log instance in current directory.
*/
if (g_fReleaseLog)
{
static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
if (RT_SUCCESS(rc2))
{
/* some introductory information */
char szNowUct[64];
RTLogRelLogger(pLogger, 0, ~0U,
"VBoxBFE %s (%s %s) release log\n"
"Log opened %s\n",
szNowUct);
/* register this logger as the release logger */
}
else
}
/*
* Start VM (also from saved state) and track progress
*/
LogFlow(("VMPowerUp\n"));
/*
* Create empty VM.
*/
if (RT_FAILURE(rc))
{
goto failure;
}
/*
* Register VM state change handler
*/
if (RT_FAILURE(rc))
{
goto failure;
}
#ifdef VBOX_WITH_HGCM
/*
* Add shared folders to the VM
*/
{
for (unsigned i=0; i<g_uNumShares; i++)
{
int cbString;
int rc;
}
}
#endif
#ifdef VBOXBFE_WITH_USB
/*
* Capture USB devices.
*/
if (g_fUSB)
{
}
#endif /* VBOXBFE_WITH_USB */
#ifdef RT_OS_L4
/* L4 console cannot draw a host cursor */
gMouse->setHostCursor(false);
#else
gMouse->setHostCursor(true);
#endif
/*
* Power on the VM (i.e. start executing).
*/
if (RT_SUCCESS(rc))
{
if ( g_fRestoreState
&& *g_pszStateFile
{
startProgressInfo("Restoring");
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
}
gDisplay->setRunning();
}
else
}
else
{
if (RT_SUCCESS(rc))
{
}
else
}
}
/*
* On failure destroy the VM.
*/
if (RT_FAILURE(rc))
goto failure;
return 0;
if (pVM)
{
}
return 0;
}
/**
* Register the main drivers.
*
* @returns VBox status code.
* @param pCallbacks Pointer to the callback table.
* @param u32Version VBox version number.
*/
{
int rc;
AssertReleaseMsg(u32Version == VBOX_VERSION, ("u32Version=%#x VBOX_VERSION=%#x\n", u32Version, VBOX_VERSION));
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
return VINF_SUCCESS;
}
/**
* Constructs the VMM configuration tree.
*
* @returns VBox status code.
* @param pVM VM handle.
*/
{
int rcAll = VINF_SUCCESS;
int rc;
/*
* Root values.
*/
if (g_fPreAllocRam)
{
}
#ifdef VBOXSDL_ADVANCED_OPTIONS
#else
#endif
/*
* PDM.
*/
/*
* Devices
*/
/* device */
/*
* PC Arch.
*/
/*
* PC Bios.
*/
RTUuidClear(&Uuid);
/*
* ACPI
*/
if (g_fACPI)
{
}
/*
* PCI bus.
*/
/*
* DMA
*/
/*
* PCI bus.
*/
/*
* PS/2 keyboard & mouse.
*/
/*
* i82078 Floppy drive controller
*/
/* Attach the status driver */
if (g_pszFdaFile)
{
}
/*
* i8254 Programmable Interval Timer And Dummy Speaker
*/
#ifdef DEBUG
#endif
/*
* i8259 Programmable Interrupt Controller.
*/
/*
* Advanced Programmable Interrupt Controller.
*/
/*
* I/O Advanced Programmable Interrupt Controller.
*/
if (g_fIOAPIC)
{
}
/*
* RTC MC146818.
*/
/*
* Serial ports
*/
/*
* VGA.
*/
/* Default: no bios logo. */
/* Boot menu */
#ifdef RT_OS_L4
/* XXX hard-coded */
char szBuf[64];
/* Tell the guest which is the ideal video mode to use */
#endif
/*
* IDE (update this when the main interface changes)
*/
if (g_pszHdaFile)
{
if (g_fHdaSpf)
{
}
{
}
else
{
}
}
if (g_pszHdbFile)
{
if (g_fHdbSpf)
{
}
{
}
else
{
}
}
if (g_pszCdromFile)
{
// ASSUME: DVD drive is always attached to LUN#2 (i.e. secondary IDE master)
}
/*
* Network adapters
*/
{
{
char szInstance[4];
UPDATE_RC();
/*
* Enable the packet sniffer if requested.
*/
{
/* insert the sniffer filter driver. */
{
UPDATE_RC();
}
}
/*
* Create the driver config (if any).
*/
{
{
}
else
{
}
}
/*
* Configure the driver.
*/
{
/* (Port forwarding goes here.) */
}
{
#if defined(RT_OS_LINUX)
{
}
else
#endif
{
#if defined(RT_OS_LINUX) || defined(RT_OS_L4)
/*
*/
if (RT_FAILURE(rc))
{
return rc;
}
{
{
FatalError("HIF name too long for device #%d: %s\n",
return VERR_BUFFER_OVERFLOW;
}
}
else
if (rc)
{
FatalError("ioctl TUNSETIFF '%s' failed: errno=%d rc=%d (%Rrc)\n",
return rc2;
}
if (rc)
{
FatalError("fcntl F_SETFL/O_NONBLOCK '%s' failed: errno=%d rc=%d (%Rrc)\n",
return rc2;
}
#elif defined(RT_OS_SOLARIS)
# ifdef VBOX_WITH_CROSSBOW
rc = CFGMR3InsertBytes(pCfg, "MAC", &g_aNetDevs[ulInstance].Mac, sizeof(g_aNetDevs[ulInstance].Mac));
UPDATE_RC();
# endif
/*
* The TAP driver does all the opening and setting up,
* as it was originally was ment to be (stupid fork() problems).
*/
{
UPDATE_RC();
}
#elif defined(RT_OS_WINDOWS)
/*
* We need the GUID too here...
*/
#else
FatalError("Name based HIF devices not implemented yet for this host platform\n");
return VERR_NOT_IMPLEMENTED;
#endif
}
}
{
/*
* Internal networking.
*/
}
}
}
/*
* VMM Device
*/
/* the VMM device's Main driver */
/*
* AC'97 ICH audio
*/
if (g_fAudio)
{
/* the Audio driver */
#ifdef RT_OS_WINDOWS
#elif defined(RT_OS_DARWIN)
#elif defined(RT_OS_LINUX)
#else /* portme */
#endif /* !RT_OS_WINDOWS */
}
#ifdef VBOXBFE_WITH_USB
/*
* The USB Controller.
*/
if (g_fUSB)
{
}
#endif /* VBOXBFE_WITH_USB */
return rc;
}