- support for VMWare version 4 disk image format implemented (patch by Sharvil

Nanavati)
- siminterface + wx code cleanup (removed unused stuff and wx log messages,
  floppy media type name handling simplified)
This commit is contained in:
Volker Ruppert 2006-12-17 08:17:28 +00:00
parent d363ceef3b
commit 9c8b9eae6a
11 changed files with 490 additions and 79 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.cc,v 1.173 2006-12-10 13:03:25 vruppert Exp $
// $Id: siminterface.cc,v 1.174 2006-12-17 08:17:27 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// See siminterface.h for description of the siminterface concept.
@ -446,34 +446,22 @@ int bx_real_sim_c::get_cdrom_options(int level, bx_list_c **out, int *where)
}
char *bochs_start_names[] = { "quick", "load", "edit", "run" };
int n_bochs_start_names = 3;
char *floppy_type_names[] = { "none", "1.2M", "1.44M", "2.88M", "720K", "360K", "160K", "180K", "320K", "auto", NULL };
int floppy_type_n_sectors[] = { -1, 80*2*15, 80*2*18, 80*2*36, 80*2*9, 40*2*9, 40*1*8, 40*1*9, 40*2*8, -1 };
int n_floppy_type_names = 10;
char *floppy_status_names[] = { "ejected", "inserted", NULL };
int n_floppy_status_names = 2;
char *bochs_bootdisk_names[] = { "none", "floppy", "disk","cdrom", NULL };
int n_bochs_bootdisk_names = 4;
char *loader_os_names[] = { "none", "linux", "nullkernel", NULL };
int n_loader_os_names = 3;
char *keyboard_type_names[] = { "xt", "at", "mf", NULL };
int n_keyboard_type_names = 3;
char *atadevice_type_names[] = { "disk", "cdrom", NULL };
int n_atadevice_type_names = 2;
//char *atadevice_mode_names[] = { "flat", "concat", "external", "dll", "sparse", "vmware3", "undoable", "growing", "volatile", "z-undoable", "z-volatile", NULL };
char *atadevice_mode_names[] = { "flat", "concat", "external", "dll", "sparse", "vmware3", "undoable", "growing", "volatile", NULL };
int n_atadevice_mode_names = 9;
//char *atadevice_mode_names[] = { "flat", "concat", "external", "dll", "sparse", "vmware3", "vmware4", "undoable", "growing", "volatile", "z-undoable", "z-volatile", NULL };
char *atadevice_mode_names[] = { "flat", "concat", "external", "dll", "sparse", "vmware3", "vmware4", "undoable", "growing", "volatile", NULL };
char *atadevice_status_names[] = { "ejected", "inserted", NULL };
int n_atadevice_status_names = 2;
char *atadevice_biosdetect_names[] = { "none", "auto", "cmos", NULL };
int n_atadevice_biosdetect_names = 3;
char *atadevice_translation_names[] = { "none", "lba", "large", "rechs", "auto", NULL };
int n_atadevice_translation_names = 5;
char *clock_sync_names[] = { "none", "realtime", "slowdown", "both", NULL };
int clock_sync_n_names=4;
void bx_real_sim_c::set_notify_callback(bxevent_handler func, void *arg)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.h,v 1.203 2006-11-12 10:07:17 vruppert Exp $
// $Id: siminterface.h,v 1.204 2006-12-17 08:17:28 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Intro to siminterface by Bryce Denney:
@ -1040,12 +1040,13 @@ enum {
#define BX_ATA_MODE_DLL_HD 3
#define BX_ATA_MODE_SPARSE 4
#define BX_ATA_MODE_VMWARE3 5
#define BX_ATA_MODE_UNDOABLE 6
#define BX_ATA_MODE_GROWING 7
#define BX_ATA_MODE_VOLATILE 8
#define BX_ATA_MODE_Z_UNDOABLE 9
#define BX_ATA_MODE_Z_VOLATILE 10
#define BX_ATA_MODE_LAST 10
#define BX_ATA_MODE_VMWARE4 6
#define BX_ATA_MODE_UNDOABLE 7
#define BX_ATA_MODE_GROWING 8
#define BX_ATA_MODE_VOLATILE 9
#define BX_ATA_MODE_Z_UNDOABLE 10
#define BX_ATA_MODE_Z_VOLATILE 11
#define BX_ATA_MODE_LAST 11
#define BX_CLOCK_SYNC_NONE 0
#define BX_CLOCK_SYNC_REALTIME 1
@ -1057,30 +1058,18 @@ enum {
#define BX_CLOCK_TIME0_UTC 2
BOCHSAPI extern char *bochs_start_names[];
BOCHSAPI extern int n_bochs_start_names;
BOCHSAPI extern char *floppy_type_names[];
BOCHSAPI extern int floppy_type_n_sectors[];
BOCHSAPI extern int n_floppy_type_names;
BOCHSAPI extern char *floppy_status_names[];
BOCHSAPI extern int n_floppy_status_names;
BOCHSAPI extern char *bochs_bootdisk_names[];
BOCHSAPI extern int n_bochs_bootdisk_names;
BOCHSAPI extern char *loader_os_names[];
BOCHSAPI extern int n_loader_os_names;
BOCHSAPI extern char *keyboard_type_names[];
BOCHSAPI extern int n_keyboard_type_names;
BOCHSAPI extern char *atadevice_type_names[];
BOCHSAPI extern int n_atadevice_type_names;
BOCHSAPI extern char *atadevice_mode_names[];
BOCHSAPI extern int n_atadevice_mode_names;
BOCHSAPI extern char *atadevice_status_names[];
BOCHSAPI extern int n_atadevice_status_names;
BOCHSAPI extern char *atadevice_biosdetect_names[];
BOCHSAPI extern int n_atadevice_biosdetect_names;
BOCHSAPI extern char *atadevice_translation_names[];
BOCHSAPI extern int n_atadevice_translation_names;
BOCHSAPI extern char *clock_sync_names[];
BOCHSAPI extern int clock_sync_n_names;
////////////////////////////////////////////////////////////////////
// base class simulator interface, contains just virtual functions.

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: win32dialog.cc,v 1.52 2006-12-06 15:05:08 akrisak Exp $
// $Id: win32dialog.cc,v 1.53 2006-12-17 08:17:28 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
#include "config.h"
@ -213,9 +213,11 @@ static BOOL CALLBACK FloppyDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP
}
cap = devtype->get() - (int)devtype->get_min();
SetWindowText(GetDlgItem(hDlg, IDDEVTYPE), floppy_type_names[cap]);
for (i = 0; i < n_floppy_type_names; i++) {
i = 0;
while (floppy_type_names[i] != NULL) {
SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_ADDSTRING, 0, (LPARAM)floppy_type_names[i]);
SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_SETITEMDATA, i, (LPARAM)(mediatype->get_min() + i));
i++
}
cap = mediatype->get() - (int)mediatype->get_min();
SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_SETCURSEL, cap, 0);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxdialog.cc,v 1.101 2006-10-21 15:36:07 vruppert Exp $
// $Id: wxdialog.cc,v 1.102 2006-12-17 08:17:28 vruppert Exp $
/////////////////////////////////////////////////////////////////
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
@ -118,12 +118,10 @@ void LogMsgAskDialog::Init()
btnSizer->Add(btn, 1, wxALL, 5);
}
wxSize ms = message->GetSize();
// wxLogMessage(wxT("message size is %d,%d"), ms.GetWidth(), ms.GetHeight());
SetAutoLayout(TRUE);
SetSizer(vertSizer);
vertSizer->Fit(this);
wxSize size = vertSizer->GetMinSize();
// wxLogMessage(wxT("minsize is %d,%d"), size.GetWidth(), size.GetHeight());
int margin = 10;
SetSizeHints (size.GetWidth () + margin, size.GetHeight () + margin);
Center ();
@ -134,22 +132,21 @@ void LogMsgAskDialog::Init()
// go away.
void LogMsgAskDialog::OnEvent(wxCommandEvent& event)
{
int id = event.GetId ();
int id = event.GetId();
int ret = -1;
switch (id) {
case ID_Continue: ret = BX_LOG_ASK_CHOICE_CONTINUE; break;
case ID_Die: ret = BX_LOG_ASK_CHOICE_DIE; break;
case ID_DumpCore: ret = BX_LOG_ASK_CHOICE_DUMP_CORE; break;
case ID_Debugger: ret = BX_LOG_ASK_CHOICE_ENTER_DEBUG; break;
case wxID_HELP: ShowHelp (); return;
case wxID_HELP: ShowHelp(); return;
default:
return; // without EndModal
}
// wxLogMessage(wxT("you pressed button id=%d, return value=%d"), id, ret);
EndModal (ret);
EndModal(ret);
}
void LogMsgAskDialog::ShowHelp ()
void LogMsgAskDialog::ShowHelp()
{
wxMessageBox(MSG_NO_HELP, MSG_NO_HELP_CAPTION, wxOK | wxICON_ERROR, this );
}
@ -247,20 +244,23 @@ void FloppyConfigDialog::AddRadio (
n_rbtns++;
}
void FloppyConfigDialog::SetDriveName (wxString name)
void FloppyConfigDialog::SetDriveName(wxString name)
{
SetTitle(wxString(FLOPPY_CONFIG_TITLE) + name);
ChangeStaticText(vertSizer, instr, wxString(FLOPPY_CONFIG_INSTRS) + name +
wxT("."));
}
void FloppyConfigDialog::SetCapacityChoices(int n, char *choices[])
void FloppyConfigDialog::SetCapacityChoices(char *choices[])
{
for (int i=0; i<n; i++)
int i = 0;
while (choices[i] != NULL) {
capacity->Append(wxString(choices[i], wxConvUTF8));
i++;
}
}
void FloppyConfigDialog::SetCapacity (int cap)
void FloppyConfigDialog::SetCapacity(int cap)
{
capacity->SetSelection(cap);
CreateBtn->Enable(floppy_type_n_sectors[cap] > 0);
@ -279,7 +279,6 @@ void FloppyConfigDialog::Init()
SetSizer(vertSizer);
vertSizer->Fit(this);
wxSize size = vertSizer->GetMinSize();
// wxLogMessage(wxT("minsize is %d,%d"), size.GetWidth(), size.GetHeight());
int margin = 5;
SetSizeHints (size.GetWidth() + margin, size.GetHeight() + margin);
Center();
@ -534,7 +533,6 @@ void AdvancedLogOptionsDialog::Init()
SetSizer(vertSizer);
vertSizer->Fit(this);
wxSize size = vertSizer->GetMinSize();
// wxLogMessage(wxT("minsize is %d,%d"), size.GetWidth(), size.GetHeight());
int margin = 5;
SetSizeHints(size.GetWidth() + margin, size.GetHeight() + margin);
Center();
@ -599,7 +597,6 @@ int AdvancedLogOptionsDialog::GetAction(int dev, int evtype) {
void AdvancedLogOptionsDialog::OnEvent(wxCommandEvent& event)
{
int id = event.GetId();
// wxLogMessage(wxT("you pressed button id=%d"), id);
switch (id) {
case ID_Browse:
BrowseTextCtrl(logfile);
@ -707,7 +704,6 @@ void DebugLogDialog::Init()
SetSizer(mainSizer);
mainSizer->Fit(this);
wxSize size = mainSizer->GetMinSize();
// wxLogMessage(wxT("minsize is %d,%d"), size.GetWidth(), size.GetHeight());
int margin = 5;
SetSizeHints(size.GetWidth() + margin, size.GetHeight() + margin);
Center();
@ -771,7 +767,6 @@ void DebugLogDialog::AppendText (wxString text) {
void DebugLogDialog::OnEvent(wxCommandEvent& event)
{
int id = event.GetId();
//wxLogMessage(wxT("event was from id=%d, type=%d"), id, (int)event.GetEventType ());
switch (id) {
case wxID_OK:
Show(FALSE);
@ -863,7 +858,6 @@ void ParamDialog::Init()
SetSizer(mainSizer);
mainSizer->Fit(this);
wxSize size = mainSizer->GetMinSize();
// wxLogMessage(wxT("minsize is %d,%d"), size.GetWidth(), size.GetHeight());
int margin = 5;
SetSizeHints(size.GetWidth() + margin, size.GetHeight() + margin);
Center();
@ -1454,10 +1448,9 @@ void ParamDialog::CopyParamToGui ()
void ParamDialog::OnEvent(wxCommandEvent& event)
{
int id = event.GetId ();
//wxLogMessage ("event was from id=%d", id);
if (isGeneratedId (id)) {
ParamStruct *pstr = (ParamStruct*) idHash->Get (id);
int id = event.GetId();
if (isGeneratedId(id)) {
ParamStruct *pstr = (ParamStruct*) idHash->Get(id);
if (pstr == NULL) {
wxLogDebug(wxT("ParamStruct not found for id=%d"), id);
return;

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////
// $Id: wxdialog.h,v 1.67 2006-12-10 13:03:25 vruppert Exp $
// $Id: wxdialog.h,v 1.68 2006-12-17 08:17:28 vruppert Exp $
////////////////////////////////////////////////////////////////////
//
// wxWidgets dialogs for Bochs
@ -198,7 +198,7 @@ public:
void SetFilename(wxString f);
// Use char* instead of wxString because the array we use is already
// expressed as a char *[].
void SetCapacityChoices(int n, char *choices[]);
void SetCapacityChoices(char *choices[]);
void SetCapacity(int cap);
int GetRadio();
int GetCapacity() { return capacity->GetSelection(); }

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxmain.cc,v 1.151 2006-10-29 08:48:30 vruppert Exp $
// $Id: wxmain.cc,v 1.152 2006-12-17 08:17:28 vruppert Exp $
/////////////////////////////////////////////////////////////////
//
// wxmain.cc implements the wxWidgets frame, toolbar, menus, and dialogs.
@ -1314,7 +1314,7 @@ void MyFrame::editFloppyConfig(int drive)
{
FloppyConfigDialog dlg(this, -1);
dlg.SetDriveName(wxString(drive==0? BX_FLOPPY0_NAME : BX_FLOPPY1_NAME, wxConvUTF8));
dlg.SetCapacityChoices(n_floppy_type_names, floppy_type_names);
dlg.SetCapacityChoices(floppy_type_names);
bx_list_c *list = (bx_list_c*) SIM->get_param((drive==0)? BXPN_FLOPPYA : BXPN_FLOPPYB);
if (!list) { wxLogError(wxT("floppy object param is null")); return; }
bx_param_filename_c *fname = (bx_param_filename_c*) list->get_by_name("path");
@ -1350,13 +1350,10 @@ void MyFrame::editFloppyConfig(int drive)
// otherwise the SetFilename() should have done the right thing.
}
int n = dlg.ShowModal();
wxLogMessage(wxT("floppy config returned %d"), n);
if (n==wxID_OK) {
char filename[1024];
wxString fn(dlg.GetFilename());
strncpy(filename, fn.mb_str(wxConvUTF8), sizeof(filename));
wxLogMessage(wxT("filename is '%s'"), filename);
wxLogMessage(wxT("capacity = %d (%s)"), dlg.GetCapacity(), floppy_type_names[dlg.GetCapacity()]);
fname->set(filename);
disktype->set(disktype->get_min() + dlg.GetCapacity());
if (sim_thread == NULL) {

View File

@ -99,6 +99,7 @@ OBJS_THAT_SUPPORT_OTHER_PLUGINS = \
svga_cirrus.o \
hdimage.o \
vmware3.o \
vmware4.o \
$(CDROM_OBJS) \
$(SOUNDLOW_OBJS) \
$(NETLOW_OBJS)
@ -133,8 +134,8 @@ libbx_%.la: %.lo
$(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH)
# special link rules for plugins that require more than one object file
libbx_harddrv.la: harddrv.lo hdimage.lo vmware3.lo $(CDROM_OBJS:.o=.lo)
$(LIBTOOL) --mode=link $(CXX) -module harddrv.lo hdimage.lo vmware3.lo $(CDROM_OBJS:.o=.lo) -o libbx_harddrv.la -rpath $(PLUGIN_PATH)
libbx_harddrv.la: harddrv.lo hdimage.lo vmware3.lo vmware4.lo $(CDROM_OBJS:.o=.lo)
$(LIBTOOL) --mode=link $(CXX) -module harddrv.lo hdimage.lo vmware3.lo vmware4.lo $(CDROM_OBJS:.o=.lo) -o libbx_harddrv.la -rpath $(PLUGIN_PATH)
libbx_keyboard.la: keyboard.lo scancodes.lo
$(LIBTOOL) --mode=link $(CXX) -module keyboard.lo scancodes.lo -o libbx_keyboard.la -rpath $(PLUGIN_PATH)
@ -162,8 +163,8 @@ bx_%.dll: %.o
$(CXX) $(CXXFLAGS) -shared -o $@ $< $(WIN32_DLL_IMPORT_LIBRARY)
# special link rules for plugins that require more than one object file
bx_harddrv.dll: harddrv.o hdimage.o vmware3.o $(CDROM_OBJS)
$(CXX) $(CXXFLAGS) -shared -o bx_harddrv.dll harddrv.o hdimage.o vmware3.o $(CDROM_OBJS) $(WIN32_DLL_IMPORT_LIBRARY)
bx_harddrv.dll: harddrv.o hdimage.o vmware3.o vmware4.o $(CDROM_OBJS)
$(CXX) $(CXXFLAGS) -shared -o bx_harddrv.dll harddrv.o hdimage.o vmware3.o vmware4.o $(CDROM_OBJS) $(WIN32_DLL_IMPORT_LIBRARY)
bx_keyboard.dll: keyboard.o scancodes.o
$(CXX) $(CXXFLAGS) -shared -o bx_keyboard.dll keyboard.o scancodes.o $(WIN32_DLL_IMPORT_LIBRARY)
@ -427,7 +428,7 @@ harddrv.o: harddrv.@CPP_SUFFIX@ iodev.h ../bochs.h ../config.h ../osdep.h \
../iodev/virt_timer.h ../iodev/serial.h ../iodev/sb16.h \
../iodev/unmapped.h ../iodev/ne2k.h ../iodev/guest2host.h \
../iodev/slowdown_timer.h ../iodev/extfpuirq.h ../iodev/gameport.h \
hdimage.h vmware3.h cdrom.h
hdimage.h vmware3.h vmware4.h cdrom.h
hdimage.o: hdimage.@CPP_SUFFIX@ iodev.h ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
@ -796,6 +797,11 @@ vmware3.o: vmware3.@CPP_SUFFIX@ iodev.h ../bochs.h ../config.h ../osdep.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
../extplugin.h ../gui/gui.h ../gui/textconfig.h ../config.h \
../gui/keymap.h ../instrument/stubs/instrument.h hdimage.h vmware3.h
vmware4.o: vmware4.@CPP_SUFFIX@ iodev.h ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
../extplugin.h ../gui/gui.h ../gui/textconfig.h ../config.h \
../gui/keymap.h ../instrument/stubs/instrument.h hdimage.h vmware4.h
biosdev.lo: biosdev.@CPP_SUFFIX@ iodev.h ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
@ -1016,7 +1022,7 @@ harddrv.lo: harddrv.@CPP_SUFFIX@ iodev.h ../bochs.h ../config.h ../osdep.h \
../iodev/virt_timer.h ../iodev/serial.h ../iodev/sb16.h \
../iodev/unmapped.h ../iodev/ne2k.h ../iodev/guest2host.h \
../iodev/slowdown_timer.h ../iodev/extfpuirq.h ../iodev/gameport.h \
hdimage.h vmware3.h cdrom.h
hdimage.h vmware3.h vmware4.h cdrom.h
hdimage.lo: hdimage.@CPP_SUFFIX@ iodev.h ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
@ -1385,3 +1391,8 @@ vmware3.lo: vmware3.@CPP_SUFFIX@ iodev.h ../bochs.h ../config.h ../osdep.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
../extplugin.h ../gui/gui.h ../gui/textconfig.h ../config.h \
../gui/keymap.h ../instrument/stubs/instrument.h hdimage.h vmware3.h
vmware4.lo: vmware4.@CPP_SUFFIX@ iodev.h ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
../extplugin.h ../gui/gui.h ../gui/textconfig.h ../config.h \
../gui/keymap.h ../instrument/stubs/instrument.h hdimage.h vmware4.h

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: harddrv.cc,v 1.189 2006-12-13 16:59:29 vruppert Exp $
// $Id: harddrv.cc,v 1.190 2006-12-17 08:17:28 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -38,6 +38,7 @@
#include "iodev.h"
#include "hdimage.h"
#include "vmware3.h"
#include "vmware4.h"
#include "cdrom.h"
#define LOG_THIS theHardDrive->
@ -146,7 +147,7 @@ void bx_hard_drive_c::init(void)
char ata_name[20];
bx_list_c *base;
BX_DEBUG(("Init $Id: harddrv.cc,v 1.189 2006-12-13 16:59:29 vruppert Exp $"));
BX_DEBUG(("Init $Id: harddrv.cc,v 1.190 2006-12-17 08:17:28 vruppert Exp $"));
for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
sprintf(ata_name, "ata.%d.resources", channel);
@ -313,6 +314,12 @@ void bx_hard_drive_c::init(void)
channels[channel].drives[device].hard_drive = new vmware3_image_t();
break;
case BX_ATA_MODE_VMWARE4:
BX_INFO(("HD on ata%d-%d: '%s' 'vmware4' mode ", channel, device,
SIM->get_param_string("path", base)->getptr()));
channels[channel].drives[device].hard_drive = new vmware4_image_t();
break;
case BX_ATA_MODE_UNDOABLE:
BX_INFO(("HD on ata%d-%d: '%s' 'undoable' mode ", channel, device,
SIM->get_param_string("path", base)->getptr()));
@ -370,8 +377,8 @@ void bx_hard_drive_c::init(void)
if ((image_mode == BX_ATA_MODE_FLAT) || (image_mode == BX_ATA_MODE_CONCAT) ||
(image_mode == BX_ATA_MODE_GROWING) || (image_mode == BX_ATA_MODE_UNDOABLE) ||
(image_mode == BX_ATA_MODE_VOLATILE) || (image_mode == BX_ATA_MODE_VMWARE3) ||
(image_mode == BX_ATA_MODE_SPARSE)) {
geometry_detect = ((cyl == 0) || (image_mode == BX_ATA_MODE_VMWARE3));
(image_mode == BX_ATA_MODE_VMWARE4) || (image_mode == BX_ATA_MODE_SPARSE)) {
geometry_detect = ((cyl == 0) || (image_mode == BX_ATA_MODE_VMWARE3) || (image_mode == BX_ATA_MODE_VMWARE4));
if ((heads == 0) || (spt == 0)) {
BX_PANIC(("ata%d/%d cannot have zero heads, or sectors/track", channel, device));
}
@ -390,7 +397,7 @@ void bx_hard_drive_c::init(void)
if (geometry_detect) {
// Autodetect number of cylinders
disk_size = BX_HD_THIS channels[channel].drives[device].hard_drive->hd_size;
if (image_mode != BX_ATA_MODE_VMWARE3) {
if (image_mode != BX_ATA_MODE_VMWARE3 && image_mode != BX_ATA_MODE_VMWARE4) {
cyl = (int)(disk_size / (heads * spt * 512));
BX_HD_THIS channels[channel].drives[device].hard_drive->cylinders = cyl;
SIM->get_param_num("cylinders", base)->set(cyl);

View File

@ -1,10 +1,10 @@
/////////////////////////////////////////////////////////////////////////
// $Id: vmware3.cc,v 1.16 2006-11-19 09:55:23 vruppert Exp $
// $Id: vmware3.cc,v 1.17 2006-12-17 08:17:28 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
/*
* This file provides support for VMWare's virtual disk image
* format.
* format version 3.
*
* Author: Sharvil Nanavati, for Net Integration Technologies, Inc.
* Contact: snrrrub@yahoo.com

329
bochs/iodev/vmware4.cc Normal file
View File

@ -0,0 +1,329 @@
/////////////////////////////////////////////////////////////////////////
// $Id: vmware4.cc,v 1.1 2006-12-17 08:17:28 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
/*
* This file provides support for VMWare's virtual disk image
* format version 4 and above.
*
* Author: Sharvil Nanavati
* Contact: snrrrub@gmail.com
*
* Copyright (C) 2006 Sharvil Nanavati.
*
* 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.1 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
*/
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
// is used to know when we are exporting symbols and when we are importing.
#define BX_PLUGGABLE
#define NO_DEVICE_INCLUDES
#include "iodev.h"
#include "hdimage.h"
#include "vmware4.h"
#define LOG_THIS bx_devices.pluginHardDrive->
const off_t vmware4_image_t::INVALID_OFFSET = (off_t)-1;
const int vmware4_image_t::SECTOR_SIZE = 512;
vmware4_image_t::vmware4_image_t()
: file_descriptor(-1),
tlb(0),
tlb_offset(INVALID_OFFSET),
current_offset(INVALID_OFFSET),
is_dirty(false)
{
}
vmware4_image_t::~vmware4_image_t()
{
close();
}
int vmware4_image_t::open(const char * pathname)
{
close();
int flags = O_RDWR;
#ifdef O_BINARY
flags |= O_BINARY;
#endif
file_descriptor = ::open(pathname, flags);
if(!is_open())
return -1;
if(!read_header())
BX_PANIC(("unable to read vmware4 virtual disk header from file '%s'", pathname));
tlb = new Bit8u [header.tlb_size_sectors * SECTOR_SIZE];
if(tlb == 0)
BX_PANIC(("unable to allocate %lld bytes for vmware4 image's tlb", header.tlb_size_sectors * SECTOR_SIZE));
tlb_offset = INVALID_OFFSET;
current_offset = 0;
is_dirty = false;
hd_size = header.total_sectors * SECTOR_SIZE;
cylinders = hd_size / (16 * 63);
heads = 16;
sectors = 63;
BX_DEBUG(("VMware 4 disk geometry:"));
BX_DEBUG((" .size = %lld", hd_size));
BX_DEBUG((" .cylinders = %d", cylinders));
BX_DEBUG((" .heads = %d", heads));
BX_DEBUG((" .sectors = %d", sectors));
return 1;
}
void vmware4_image_t::close()
{
if(file_descriptor == -1)
return;
flush();
delete [] tlb, tlb = 0;
::close(file_descriptor);
file_descriptor = -1;
}
Bit64s vmware4_image_t::lseek(Bit64s offset, int whence)
{
switch(whence)
{
case SEEK_SET:
current_offset = (off_t)offset;
return current_offset;
case SEEK_CUR:
current_offset += (off_t)offset;
return current_offset;
case SEEK_END:
current_offset = header.total_sectors * SECTOR_SIZE + (off_t)offset;
return current_offset;
default:
BX_DEBUG(("unknown 'whence' value (%d) when trying to seek vmware4 image", whence));
return INVALID_OFFSET;
}
}
ssize_t vmware4_image_t::read(void * buf, size_t count)
{
ssize_t total = 0;
while(count > 0)
{
off_t readable = perform_seek();
if(readable == INVALID_OFFSET)
{
BX_DEBUG(("vmware4 disk image read failed on %d bytes at " FMT_LL "d", count, current_offset));
return -1;
}
off_t copysize = (count > readable) ? readable : count;
memcpy(buf, tlb + current_offset - tlb_offset, copysize);
current_offset += copysize;
total += copysize;
count -= copysize;
}
return total;
}
ssize_t vmware4_image_t::write(const void * buf, size_t count)
{
ssize_t total = 0;
while(count > 0)
{
off_t writable = perform_seek();
if(writable == INVALID_OFFSET)
{
BX_DEBUG(("vmware4 disk image write failed on %d bytes at " FMT_LL "d", count, current_offset));
return -1;
}
off_t writesize = (count > writable) ? writable : count;
memcpy(tlb + current_offset - tlb_offset, buf, writesize);
current_offset += writesize;
total += writesize;
count -= writesize;
is_dirty = true;
}
return total;
}
bool vmware4_image_t::is_open() const
{
return (file_descriptor != -1);
}
bool vmware4_image_t::is_valid_header() const
{
if(header.id[0] != 'K' || header.id[1] != 'D' || header.id[2] != 'M' ||
header.id[3] != 'V')
{
BX_DEBUG(("not a vmware4 image"));
return false;
}
if(header.version != 1)
{
BX_DEBUG(("unsupported vmware4 image version"));
return false;
}
return true;
}
bool vmware4_image_t::read_header()
{
if(!is_open())
BX_PANIC(("attempt to read vmware4 header from a closed file"));
if(::read(file_descriptor, &header, sizeof(VM4_Header)) != sizeof(VM4_Header))
return false;
header.version = dtoh32(header.version);
header.flags = dtoh32(header.flags);
header.total_sectors = dtoh64(header.total_sectors);
header.tlb_size_sectors = dtoh64(header.tlb_size_sectors);
header.description_offset_sectors = dtoh64(header.description_offset_sectors);
header.description_size_sectors = dtoh64(header.description_size_sectors);
header.slb_count = dtoh32(header.slb_count);
header.flb_offset_sectors = dtoh64(header.flb_offset_sectors);
header.flb_copy_offset_sectors = dtoh64(header.flb_copy_offset_sectors);
header.tlb_offset_sectors = dtoh64(header.tlb_offset_sectors);
if(!is_valid_header())
BX_PANIC(("invalid vmware4 virtual disk image"));
BX_DEBUG(("VM4_Header (size=%d)", sizeof(VM4_Header)));
BX_DEBUG((" .version = %d", header.version));
BX_DEBUG((" .flags = %d", header.flags));
BX_DEBUG((" .total_sectors = %lld", header.total_sectors));
BX_DEBUG((" .tlb_size_sectors = %lld", header.tlb_size_sectors));
BX_DEBUG((" .description_offset_sectors = %lld", header.description_offset_sectors));
BX_DEBUG((" .description_size_sectors = %lld", header.description_size_sectors));
BX_DEBUG((" .slb_count = %d", header.slb_count));
BX_DEBUG((" .flb_offset_sectors = %lld", header.flb_offset_sectors));
BX_DEBUG((" .flb_copy_offset_sectors = %lld", header.flb_copy_offset_sectors));
BX_DEBUG((" .tlb_offset_sectors = %lld", header.tlb_offset_sectors));
return true;
}
//
// Returns the number of bytes that can be read from the current offset before needing
// to perform another seek.
//
off_t vmware4_image_t::perform_seek()
{
if(current_offset == INVALID_OFFSET)
{
BX_DEBUG(("invalid offset specified in vmware4 seek"));
return INVALID_OFFSET;
}
//
// The currently loaded tlb can service the request.
//
if(tlb_offset / (header.tlb_size_sectors * SECTOR_SIZE) == current_offset / (header.tlb_size_sectors * SECTOR_SIZE))
return (header.tlb_size_sectors * SECTOR_SIZE) - (current_offset - tlb_offset);
flush();
Bit64u index = current_offset / (header.tlb_size_sectors * SECTOR_SIZE);
Bit32u slb_index = (Bit32u)(index % header.slb_count);
Bit32u flb_index = (Bit32u)(index / header.slb_count);
Bit32u slb_sector = read_block_index(header.flb_offset_sectors, flb_index);
Bit32u slb_copy_sector = read_block_index(header.flb_copy_offset_sectors, flb_index);
if(slb_sector == 0 && slb_copy_sector == 0)
{
BX_DEBUG(("loaded vmware4 disk image requires un-implemented feature"));
return INVALID_OFFSET;
}
if(slb_sector == 0)
slb_sector = slb_copy_sector;
Bit32u tlb_sector = read_block_index(slb_sector, slb_index);
tlb_offset = index * header.tlb_size_sectors * SECTOR_SIZE;
if(tlb_sector == 0)
{
//
// Allocate a new tlb
//
memset(tlb, 0, header.tlb_size_sectors * SECTOR_SIZE);
//
// Instead of doing a write to increase the file size, we could use
// ftruncate but it is not portable.
//
off_t eof = ((::lseek(file_descriptor, 0, SEEK_END) + SECTOR_SIZE - 1) / SECTOR_SIZE) * SECTOR_SIZE;
::write(file_descriptor, tlb, header.tlb_size_sectors * SECTOR_SIZE);
tlb_sector = eof / SECTOR_SIZE;
write_block_index(slb_sector, slb_index, tlb_sector);
write_block_index(slb_copy_sector, slb_index, tlb_sector);
::lseek(file_descriptor, eof, SEEK_SET);
}
else
{
::lseek(file_descriptor, tlb_sector * SECTOR_SIZE, SEEK_SET);
::read(file_descriptor, tlb, header.tlb_size_sectors * SECTOR_SIZE);
::lseek(file_descriptor, tlb_sector * SECTOR_SIZE, SEEK_SET);
}
return (header.tlb_size_sectors * SECTOR_SIZE) - (current_offset - tlb_offset);
}
void vmware4_image_t::flush()
{
if(!is_dirty)
return;
//
// Write dirty sectors to disk first. Assume that the file is already at the
// position for the current tlb.
//
::write(file_descriptor, tlb, header.tlb_size_sectors * SECTOR_SIZE);
is_dirty = false;
}
Bit32u vmware4_image_t::read_block_index(Bit64u sector, Bit32u index)
{
Bit32u ret;
::lseek(file_descriptor, sector * SECTOR_SIZE + index * sizeof(Bit32u), SEEK_SET);
::read(file_descriptor, &ret, sizeof(Bit32u));
return dtoh32(ret);
}
void vmware4_image_t::write_block_index(Bit64u sector, Bit32u index, Bit32u block_sector)
{
block_sector = htod32(block_sector);
::lseek(file_descriptor, sector * SECTOR_SIZE + index * sizeof(Bit32u), SEEK_SET);
::write(file_descriptor, &block_sector, sizeof(Bit32u));
}

95
bochs/iodev/vmware4.h Normal file
View File

@ -0,0 +1,95 @@
/////////////////////////////////////////////////////////////////////////
// $Id: vmware4.h,v 1.1 2006-12-17 08:17:28 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
/*
* This file provides support for VMWare's virtual disk image
* format version 4 and above.
*
* Author: Sharvil Nanavati
* Contact: snrrrub@gmail.com
*
* Copyright (C) 2006 Sharvil Nanavati.
*
* 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.1 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
*/
#ifndef _VMWARE4_H
#define _VMWARE4_H 1
class vmware4_image_t : public device_image_t
{
public:
vmware4_image_t();
virtual ~vmware4_image_t();
int open(const char* pathname);
void close();
Bit64s lseek(Bit64s offset, int whence);
ssize_t read(void* buf, size_t count);
ssize_t write(const void* buf, size_t count);
private:
static const off_t INVALID_OFFSET;
static const int SECTOR_SIZE;
#if defined(_MSC_VER)
#pragma pack(push, 1)
#elif defined(__MWERKS__) && defined(macintosh)
#pragma options align=packed
#endif
typedef struct _VM4_Header
{
Bit8u id[4];
Bit32u version;
Bit32u flags;
Bit64u total_sectors;
Bit64u tlb_size_sectors;
Bit64u description_offset_sectors;
Bit64u description_size_sectors;
Bit32u slb_count;
Bit64u flb_offset_sectors;
Bit64u flb_copy_offset_sectors;
Bit64u tlb_offset_sectors;
}
#if !defined(_MSC_VER)
GCC_ATTRIBUTE((packed))
#endif
VM4_Header;
#if defined(_MSC_VER)
#pragma pack(pop)
#elif defined(__MWERKS__) && defined(macintosh)
#pragma options align=reset
#endif
bool is_open() const;
bool is_valid_header() const;
bool read_header();
off_t perform_seek();
void flush();
Bit32u read_block_index(Bit64u sector, Bit32u index);
void write_block_index(Bit64u sector, Bit32u index, Bit32u block_sector);
int file_descriptor;
VM4_Header header;
Bit8u* tlb;
off_t tlb_offset;
off_t current_offset;
bool is_dirty;
};
#endif