#!/usr/bin/perl -w
+use Data::Dumper;
print <<END
;
$pdir = $ENV{PALACIOS_DIR};
+$qdir = $ENV{PALACIOS_QEMU_DIR};
+
+$haveqemu = defined($qdir);
if (!defined($pdir)) {
print "Please set PALACIOS_DIR (you probably have not sourced ENV) and try again\n";
do_swapping(\%config, $pdir);
+
print "We will give your guest the default performance tuning characteristics\n";
$config{perftune_block} .= <<PERFTUNE
<group name="yield">
$config{extensions_block} .= " <extension name=\"VMWARE_IFACE\"></extension>\n";
}
+
+do_bioses(\%config, $pdir, $dir);
+
+
#
# Basic debugging
#
#
do_device(\%config, $pdir, "V3_CONFIG_PIT", "8254_PIT", "PIT",1); # must have
-#
-# Keyboard and mouse (PS/2 controller)
-#
-do_device(\%config, $pdir, "V3_CONFIG_KEYBOARD", "KEYBOARD", "keyboard",1); #must have
+if (defined($ENV{PALACIOS_QEMU_DIR})) {
+ print "\nYour Palacios configuration includes the ability to use QEMU devices from a patched QEMU.\n";
+ print "Do you want to use QEMU's PS/2, graphics, and serial port devices? [n] : ";
+ if (get_user("n") eq "y") {
+ do_qemu_ui(\%config, $pdir, $dir);
+ }
+}
+
+if (!defined($config{qemu_ui})) {
+ #
+ # Keyboard and mouse (PS/2 controller)
+ #
+ do_device(\%config, $pdir, "V3_CONFIG_KEYBOARD", "KEYBOARD", "keyboard",1); #must have
-#
-# Displays, Consoles, Serial
-#
-print "\nWe will now consider consoles and serial ports.\n\n";
-do_consoles_and_ports(\%config, $pdir);
+ #
+ # Displays, Consoles, Serial
+ #
+ print "\nWe will now consider consoles and serial ports.\n\n";
+ do_consoles_and_ports(\%config, $pdir);
+
+}
#
print $target "<vm class=\"PC\">\n\n";
print $target file_setup(\%config), "\n";
+print $target bios_setup(\%config),"\n";
print $target memory_setup(\%config), "\n";
print $target swapping_setup(\%config), "\n";
print $target paging_setup(\%config), "\n";
close(PAL);
+print Dumper(\%config);
+
+if (defined($config{qemu}) && $config{qemu} eq "y") {
+ gen_qemu_startup(\%config, $pdir, $dir);
+}
+
print "\n\nYour guest is now ready in the directory $dir\n\n";
print "To run it, do:\n\n";
print " cd $dir\n";
if ($canswap) {
#Config for swapping
$cr->{swapping} = yn_question("Do you want to use swapping?", "n", "y", "n");
-
+
if ($cr->{swapping} eq "y") {
$cr->{swap_alloc} = quant_question("How much memory do you want to allocate [MB] ?", $mem/2);
print "We will use the default swapping strategy.\n";
$cr->{swap_file} = get_user("./swap.bin");
}
}
+}
-}
+sub add_bios {
+ my ($cr, $name, $fileid, $address) =@_;
+
+ push @{$cr->{bios_list}}, { name=>$name, fileid=>$fileid, address=>$address };
+
+}
+
+sub do_bios {
+ my ($cr, $pdir, $dir) = @_;
+ my $nextbios = defined($cr->{bios_list}) ? "bios".($#{$cr->{bios_list}}+1) : "bios0";
+
+ if (yn_question("Add a".($nextbios eq "bios0" ? "" : "nother")." custom bios? ", "n", "y", "n") eq "y") {
+ my ($n, $fn, $addr) ;
+ print "What is your name for this bios? [$nextbios] : ";
+ $n = get_user($nextbios);
+ while (1) {
+ print "Where is the path to the file for bios $n ? ";
+ $fn = get_user("");
+ if (!(-e $fn)) {
+ print "Cannot find $fn, try again\n";
+ next;
+ } else {
+ if (system("cp $fn $dir/$n.dat")) {
+ print "Unable to copy $fn\n";
+ next;
+ } else {
+ add_file($cr, "$n", "$n.dat");
+ print "What is the destination physical linear address (in hex) for bios $n [0xf0000] ? ";
+ $addr = get_user("0xf0000");
+ add_bios($cr,$n,$n,$addr);
+ return 1;
+ }
+ }
+ }
+ } else {
+ return 0;
+ }
+}
+
+sub do_bioses {
+ my ($cr, $pdir, $dir) = @_;
+
+ $cr->{bios_custom} = yn_question("Do you want to customize BIOSes? (done automatically later for QEMU devices) ", "n", "y", "n");
+
+ if ($cr->{bios_custom} eq "y") {
+ $cr->{bios_custom_nobios} = yn_question("Disable built-in system bios? ", "n", "y", "n");
+ $cr->{bios_custom_novgabios} = yn_question("Disable built-in VGA bios? ", "n", "y", "n");
+
+ while (do_bios($cr, $pdir, $dir)) {}
+ }
+}
+
+
+
sub do_device {
my ($cr,$pdir,$feature, $class, $id, $hardfail, $optblob, $nestblob) =@_;
}
}
+sub add_qemu_device {
+ my ($cr, $pdir, $type, $name, $url) = @_;
+
+ $cr->{qemu}='y';
+
+ push @{$cr->{qemu_devices}}, { type=>$type, name=>$name, url=>$url } ;
+
+}
+
+sub do_qemu_ui {
+ my ($cr, $pdir, $dir) = @_;
+ my $vgabios=$ENV{PALACIOS_QEMU_DIR}."/share/qemu/vgabios-cirrus.bin";
+
+ $cr->{qemu_ui}='y';
+
+ # PS/2 is a generic device
+ add_device($cr,"GENERIC","qemu-ps2",
+ " forward=\"host_device\" hostdev=\"user:qemu-ps2\" ",
+ " <ports> <start>0x60</start> <end>0x60</end> <mode>PASSTHROUGH</mode> </ports>\n".
+ " <ports> <start>0x64</start> <end>0x64</end> <mode>PASSTHROUGH</mode> </ports>\n".
+ " <ports> <start>0x80</start> <end>0x80</end> <mode>PASSTHROUGH</mode> </ports>\n");
+ add_qemu_device($cr,$pdir, "qemu-ps2", "qemu-ps2", "user:qemu-ps2");
+
+ # so is serial
+ add_device($cr,"GENERIC", "qemu-serial",
+ " forward=\"host_device\" hostdev=\"user:qemu-serial\" ",
+ " <ports> <start>0x3f8</start> <end>0x3ff</end> <mode>PASSTHROUGH</mode> </ports>\n".
+ " <ports> <start>0x2f8</start> <end>0x2ff</end> <mode>PASSTHROUGH</mode> </ports>\n".
+ " <ports> <start>0x3e8</start> <end>0x3ef</end> <mode>PASSTHROUGH</mode> </ports>\n".
+ " <ports> <start>0x2e8</start> <end>0x2ef</end> <mode>PASSTHROUGH</mode> </ports>\n");
+ add_qemu_device($cr,$pdir, "qemu-serial", "qemu-serial", "user:qemu-serial");
+
+ # Video has both a generic device and a PCI device (enhanced vga) and a bios
+ add_device($cr,"GENERIC", "qemu-video-legacy",
+ " forward=\"host_device\" hostdev=\"user:qemu-video-legacy\" ",
+ " <ports> <start>0x3b4</start> <end>0x3da</end> <mode>PASSTHROUGH</mode> </ports>\n".
+ " <memory> <start>0xa0000</start> <end>0xbffff</end> <mode>PASSTHROUGH</mode> </memory>\n");
+ add_qemu_device($cr,$pdir, "qemu-video-legacy", "qemu-video-legacy", "user:qemu-video-legacy");
+
+ add_device($cr, "PCI_FRONT", "qemu-video",
+ " hostdev=\"user:qemu-video\" ",
+ " <bus>pci0</bus>\n");
+
+ add_qemu_device($cr,$pdir, "qemu-video", "qemu-video", "user:qemu-video");
+
+ print "To use QEMU video, we will need to add the relevant bios. \n";
+ while (1) {
+ print "Where is the QEMU video bios ? [$vgabios] : ";
+ $vgabios = get_user($vgabios);
+ if (-e $vgabios) {
+ if (system("cp $vgabios $dir/qemu-videobios.dat")) {
+ print "Cannot copy $vgabios, try again\n";
+ next;
+ } else {
+ last;
+ }
+ } else {
+ print "Cannot find $vgabios, try again\n";
+ next;
+ }
+ }
+ add_file($cr, "qemu-videobios", "qemu-videobios.dat");
+ add_bios($cr, "qemu-videobios", "qemu-videobios", "0xc0000");
+ $cr->{bios_custom} = 'y';
+ $cr->{bios_custom_novgabios} = 'y';
+
+}
+
sub do_consoles_and_ports {
my ($cr, $pdir) = @_;
;
}
my @par = find_devices_by_class($cr,"SERIAL");
- if ($#par<0) {
+ if ($#par<0 && !defined($cr->{qemu_ui})) {
$block .=<<GENERIC3
<ports>
<!-- Serial COM 1 -->
}
}
+sub bios_setup {
+ my $cr=shift;
+
+ if (!defined($cr->{bios_custom}) || $cr->{bios_custom} eq "n") {
+ return " <!-- this configuration does not use a custom bios setup but you can add one with the <bioses> syntax-->\n";
+ } else {
+ my $s;
+ my $b;
+ $s = " <bioses>\n";
+ $s.= " <disable_rombios/>\n" if defined($cr->{bios_custom_nobios}) && $cr->{bios_custom_nobios} eq "y";
+ $s.= " <disable_vgabios/>\n" if defined($cr->{bios_custom_novgabios}) && $cr->{bios_custom_novgabios} eq "y";
+ foreach $b (@{$cr->{bios_list}}) {
+ $s.= " <bios file=\"".$b->{fileid}."\" address=\"".$b->{address}."\" />\n";
+ }
+ $s.= " </bioses>\n";
+ return $s;
+ }
+}
+
sub device_setup {
my $cr=shift;
my $cd;
return 0;
}
}
+
+
+sub gen_qemu_startup {
+ my ($cr, $pdir, $dir) = @_;
+ my $d;
+
+ # FIX ME
+ print "Generating QEMU Startup Script\n";
+
+ open(Q,">$dir/qemu_startup.sh");
+ print Q $ENV{PALACIOS_QEMU_DIR}."/bin/qemu-system-x86_64 -m 2048 -accel pal ";
+ foreach $d (@{$cr->{qemu_devices}}) {
+ if ($d->{type} eq "qemu-ps2") {
+ print Q " -map KBD ".$d->{url}." ";
+ } elsif ($d->{type} eq "qemu-serial") {
+ print Q " -serial stdio -map SERIAL ".$d->{url}." ";
+ } elsif ($d->{type} eq "qemu-video-legacy") {
+ print Q " -map VGA ".$d->{url}." ";
+ } elsif ($d->{type} eq "qemu-video") {
+ print Q " -vga cirrus -map CIRRUS ".$d->{url}." ";
+ } elsif ($d->{type} eq "qemu-e1000") {
+ print Q " -nic e1000 -map E1000 ".$d->{url}." ";
+ } elsif ($d->{type} eq "qemu-ide-legacy") {
+ print Q " -ide ... -map IDE-LEGACY ".$d->{url}." ";
+ } elsif ($d->{type} eq "qemu-ide") {
+ print Q " -ide ... -map IDE ".$d->{url}." ";
+ } else {
+ die "Do not know how to handle QEMU device of type ".$d->{type}."\n";
+ }
+ }
+
+ print Q "\n";
+
+ close(Q);
+}
$maxalloc = get_user($maxalloc);
-$shadow = 'y';
+$gb4 = 'n';
-print "Do you need to run guests with shadow paging or for other reasons that require 4GB enforcement of page allocation? [$shadow] : ";
+print "Do you need to use features that require 4GB enforcement of page allocation? [$gb4] : ";
-$shadow = get_user($shadow);
+$gb4 = get_user($gb4);
if ($hotremove eq "y") {
print "Your kernel supports hot remove. Do you want to use it? [$hotremove] : ";
print "Do you need userspace access to your VMs' physical memory? [$devmem] : ";
$devmem = get_user($devmem);
+$qemu='n';
+$qemudir=$pdir."/linux_usr/qemu";
+
+$hostdev = get_palacios_core_feature($pdir,"V3_CONFIG_HOST_DEVICE");
+
+if ($hostdev eq "y") {
+ print "Your Palacios configuration includes the host device interface.\n";
+ print "You can use it to interface with QEMU devices if you have a\n";
+ print "patched version of QEMU (see linux_usr/qemu for more info)\n\n";
+ print "Do you plan to use QEMU devices? [n] : ";
+ $qemu = get_user($qemu);
+ if ($qemu eq "y") {
+ while (1) {
+ print "What is the path to your patched version of QEMU ? [$qemudir] : ";
+ $qemudir = get_user($qemudir);
+ last if -e "$qemudir/bin/qemu-system-x86_64";
+ print "$qemudir/bin/qemu-system-x86_64 cannot be found\n";
+ }
+ }
+}
+
print <<END2
Parameters
Initial Palacios Memory (MB) $mem
Can Hot Remove: $canhotremove
Will Hot Remove: $hotremove
- Enforce 4 GB Limit: $shadow
+ Enforce 4 GB Limit: $gb4
Compiled Memory Block Size: $compmemblocksize
Override Memory Block Size: $override_memblocksize
Actual Memory Block Size: $memblocksize
Allow Devmem: $devmem
+ Support QEMU devices: $qemu
+ QEMU directory: $qemudir
END2
;
print "Writing ./ENV\n";
open(ENV,">ENV");
print ENV "export PALACIOS_DIR=$pdir\n";
+if ($qemu eq "y") {
+ print ENV "export PALACIOS_QEMU_DIR=$qemudir\n";
+}
print ENV "export PATH=$pdir/linux_usr:\$PATH\n";
close(ENV);
`chmod 644 ENV`;
print " Number of blocks: $numchunks\n";
print " Number of nodes: $numnodes\n";
print " Blocks/node: $chunkspernode\n";
-print " 32 bit limit? $shadow\n";
+print " 32 bit limit? $gb4\n";
print " Hot-removed? $hotremove\n";
if ($numnodes*$chunkspernode*$chunk != $mem) {
$cmd = "v3_mem -a";
$cmd.= " -k " if $hotremove eq 'n';
-$cmd.= " -l " if $shadow eq 'y';
+$cmd.= " -l " if $gb4 eq 'y';
for ($i=0;$i<$numnodes;$i++) {
for ($j=0;$j<$chunkspernode;$j++) {