X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=v3_config_guest.pl;h=5b50f4087e4e3f14514909463e1c69aa77547700;hp=abe7d49487a78a2d693f412598bb0e59c1c64d56;hb=82d082daad3fe8afad4be97d97093a3dfb768e1f;hpb=946b9684bf8fa50950f54d69b526c889743e3dae diff --git a/v3_config_guest.pl b/v3_config_guest.pl index abe7d49..5b50f40 100755 --- a/v3_config_guest.pl +++ b/v3_config_guest.pl @@ -1,5 +1,6 @@ #!/usr/bin/perl -w +use Data::Dumper; print <1) { } } +do_swapping(\%config, $pdir); + print "We will give your guest the default performance tuning characteristics\n"; $config{perftune_block} .= <\n"; } + +do_bioses(\%config, $pdir, $dir); + + # # Basic debugging # @@ -170,17 +180,28 @@ if (is_palacios_core_feature_enabled($pdir,"V3_CONFIG_MPTABLE")) { # 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); + } +} -# -# Displays, Consoles, Serial -# -print "\nWe will now consider consoles and serial ports.\n\n"; -do_consoles_and_ports(\%config, $pdir); +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); + +} # @@ -191,12 +212,6 @@ print "\nWe will now consider storage controllers and devices.\n\n"; do_storage(\%config, $pdir, $dir, $name, "pci0", "southbridge"); -# -# NVRAM -# -# Note: do_storage *must* have placed an IDE named ide0 in order for this to work -# -do_device(\%config, $pdir, "V3_CONFIG_NVRAM", "NVRAM", "nvram", 1, undef, " ide0\n"); #must have # @@ -208,6 +223,33 @@ do_network(\%config, $pdir, $dir, $name, "pci0", "southbridge"); # +# Sanity-check - is there something bootable? +# +# +if (!($config{havecd} && !($config{havehd}))) { + print "The guest's storage configuration does not have either a CD or an HD. \n"; + print "This means the guest BIOS will have nothing local to boot. \n"; + if (!($config{havenic})) { + print "The guest also does does not have a NIC, which means the BIOS cannot\n"; + print "do a network boot.\n"; + } else { + print "The guest does have a NIC, so a network boot is possible, if the\n"; + print "BIOS supports it.\n"; + } + print "If this is not your intent, you probably want to CTRL-C and try again.\n"; +} + +print "The BIOS boot sequence will be set to CD,HD. If you need to change this\n"; +print "later, edit the block within the NVRAM device.\n"; + +# +# NVRAM +# +# Note: do_storage *must* have placed an IDE named ide0 in order for this to work +# +do_device(\%config, $pdir, "V3_CONFIG_NVRAM", "NVRAM", "nvram", 1, undef, " ide0\n cd,hd\n"); #must have + +# # # Generic Catch-all Device # @@ -220,7 +262,9 @@ $target = PAL; print $target "\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"; print $target memmap_setup(\%config), "\n"; print $target numa_setup(\%config), "\n"; @@ -234,11 +278,17 @@ print $target "\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"; print " v3_create -b $name.pal $name\n"; -print " v3_launch /dev/v3-vmN (N given by v3_create\n\n"; +print " v3_launch /dev/v3-vmN (N given by v3_create)\n\n"; print "Other useful tools:\n\n"; print " v3_console (CGA console)\n"; print " v3_stream (connect to stream, for example, serial port)\n\n"; @@ -382,6 +432,82 @@ sub get_numa_data() { return %numa; } + +sub do_swapping { + my ($cr, $pdir) = @_; + + my $canswap = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_SWAPPING"); + my $mem = $cr->{mem}; + + 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_strat} = "default"; + print "What file do you want to swap to? [./swap.bin] "; + $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) =@_; @@ -398,6 +524,74 @@ sub do_device { } } +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\" ", + " 0x60 0x60 PASSTHROUGH \n". + " 0x64 0x64 PASSTHROUGH \n". + " 0x80 0x80 PASSTHROUGH \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\" ", + " 0x3f8 0x3ff PASSTHROUGH \n". + " 0x2f8 0x2ff PASSTHROUGH \n". + " 0x3e8 0x3ef PASSTHROUGH \n". + " 0x2e8 0x2ef PASSTHROUGH \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\" ", + " 0x3b4 0x3da PASSTHROUGH \n". + " 0xa0000 0xbffff PASSTHROUGH \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\" ", + " pci0\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) = @_; @@ -429,7 +623,7 @@ sub do_consoles_and_ports { if (!($cancga || $canvga || $canserial || $canvirtioconsole)) { print "Hmm... No console mechanism is enabled in your Palacios build...\n"; print " This is probably not what you want...\n"; -} + } $didcga=0; if ($cancga) { @@ -495,6 +689,7 @@ sub do_consoles_and_ports { print "You have configured your guest without any obvious way of interacting with it....\n"; print " This is probably not what you want...\n"; } + } @@ -595,6 +790,10 @@ sub do_network { } $num++; } + + if ($num>0) { + $cr->{havenic}=1; + } } @@ -641,12 +840,14 @@ sub do_storage { do_storage_backend($cr, $pdir, $dir, $name, "virtioblk$i", "data$i", ""); } } -} + +} + sub do_storage_backend { my ($cr, $pdir, $dir, $name, $frontend, $loc, $frontendblock) = @_; - my ($canramdisk, $canfiledisk, $cannetdisk, $cantmpdisk); + my ($canramdisk, $canfiledisk, $cannetdisk, $cantmpdisk, $canqcowdisk); my @devs=("cd","hd","nothing"); my @disks; my $type; @@ -656,15 +857,17 @@ sub do_storage_backend { $canramdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_RAMDISK"); $canfiledisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_FILEDISK"); + $canqcowdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_QCOWDISK"); $cannetdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_NETDISK"); $cantmpdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_TMPDISK"); push @disks, "ramdisk" if $canramdisk; push @disks, "filedisk" if $canramdisk; + push @disks, "qcowdisk" if $canramdisk; push @disks, "netdisk" if $cannetdisk; push @disks, "tmpdisk" if $cantmpdisk; - if (!$canramdisk && !$canfiledisk && !$cannetdisk && !$cantmpdisk) { + if (!$canramdisk && !$canfiledisk && !$cannetdisk && !$cantmpdisk && !$canqcowdisk) { print "You have no storage implementations enabled in your Palacios build, so it is impossible\n"; print "to add anything to storage controller \"$frontend\" location \"$loc\"\n"; return -1; @@ -683,6 +886,7 @@ sub do_storage_backend { print "A storage device requires one of the following implementations\n"; print " * RAMDISK - the data is kept in memory (common) : ".($canramdisk ? "available" : "UNAVAILABLE")."\n"; print " * FILEDISK - the data is kept in a host file (common) : ".($canfiledisk ? "available" : "UNAVAILABLE")."\n"; + print " * QCOWDISK - the data is kept in a host file (qcow) : ".($canqcowdisk ? "available" : "UNAVAILABLE")."\n"; print " * NETDISK - the data is accessed via the network (uncommon) : ".($cannetdisk ? "available" : "UNAVAILABLE")."\n"; print " * TMPDISK - the data is kept in memory and discarded (common) : ".($cantmpdisk ? "available" : "UNAVAILABLE")."\n"; while (1) { @@ -692,7 +896,7 @@ sub do_storage_backend { last if $#test==0; } - if ($type eq "filedisk" || $type eq "ramdisk") { + if ($type eq "filedisk" || $type eq "ramdisk" || $type eq "qcowdisk") { print "$type requires a file (.iso for example). Do you have one? [y] : "; if (get_user("y") eq "y") { while (1) { @@ -717,9 +921,11 @@ sub do_storage_backend { if ($what eq "cd") { $attach.=" V3VEE CDROM\n". " CDROM\n".$frontendblock; + $cr->{havecd}=1; } else { $attach.=" V3VEE HD\n". " HD\n".$frontendblock; + $cr->{havehd}=1; } $attach.=" \n"; @@ -727,9 +933,12 @@ sub do_storage_backend { add_device($cr,"RAMDISK","$frontend\_$loc", undef, " $frontend\_$loc\n".$attach); add_file($cr, "$frontend\_$loc", "$frontend\_$loc.dat"); - } else { + } elsif ($type eq "filedisk") { add_device($cr,"FILEDISK","$frontend\_$loc", $what eq "hd" ? "writable=\"1\"" : undef, " $frontend\_$loc.dat\n".$attach); + } else { + add_device($cr,"QCOWDISK","$frontend\_$loc", $what eq "hd" ? "writable=\"1\"" : undef, + " $frontend\_$loc.dat\n".$attach); } last; } else { @@ -813,7 +1022,7 @@ GENERIC2 ; } my @par = find_devices_by_class($cr,"SERIAL"); - if ($#par<0) { + if ($#par<0 && !defined($cr->{qemu_ui})) { $block .=< @@ -954,6 +1163,14 @@ sub extensions_setup { return $s; } +sub swapping_setup { + my $cr=shift; + if (defined($cr->{swapping}) && $cr->{swapping} eq "y") { + return " \n ".$cr->{swap_alloc}."\n ".$cr->{swap_file}."\n ".$cr->{swap_strat}."\n \n"; + } else { + return " \n"; + } +} sub telemetry_setup { my $cr=shift; return " ".$cr->{telemetry}."\n"; @@ -978,6 +1195,25 @@ sub file_setup { } } +sub bios_setup { + my $cr=shift; + + if (!defined($cr->{bios_custom}) || $cr->{bios_custom} eq "n") { + return " \n"; + } else { + my $s; + my $b; + $s = " \n"; + $s.= " \n" if defined($cr->{bios_custom_nobios}) && $cr->{bios_custom_nobios} eq "y"; + $s.= " \n" if defined($cr->{bios_custom_novgabios}) && $cr->{bios_custom_novgabios} eq "y"; + foreach $b (@{$cr->{bios_list}}) { + $s.= " {fileid}."\" address=\"".$b->{address}."\" />\n"; + } + $s.= " \n"; + return $s; + } +} + sub device_setup { my $cr=shift; my $cd; @@ -1080,3 +1316,38 @@ sub gen_image_file { 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); +}