From: Peter Dinda Date: Thu, 11 Sep 2014 22:24:38 +0000 (-0500) Subject: Initial cut at handling configuration of qemu devices X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=b4e7d8dfa9d14865725acbc4fbac4a333bf5b769 Initial cut at handling configuration of qemu devices --- diff --git a/v3_config_guest.pl b/v3_config_guest.pl index 79a98ed..35aadc7 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} .= < @@ -118,6 +123,10 @@ if (is_palacios_core_feature_enabled($pdir, "V3_CONFIG_EXT_VMWARE")) { $config{extensions_block} .= " \n"; } + +do_bioses(\%config, $pdir, $dir); + + # # Basic debugging # @@ -171,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); + } +} + +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); + +} # @@ -242,6 +262,7 @@ $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"; @@ -257,6 +278,12 @@ 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"; @@ -415,7 +442,7 @@ sub do_swapping { 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"; @@ -424,8 +451,62 @@ sub do_swapping { $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) =@_; @@ -443,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) = @_; @@ -867,7 +1016,7 @@ GENERIC2 ; } my @par = find_devices_by_class($cr,"SERIAL"); - if ($#par<0) { + if ($#par<0 && !defined($cr->{qemu_ui})) { $block .=< @@ -1040,6 +1189,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; @@ -1142,3 +1310,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); +} diff --git a/v3_config_v3vee.pl b/v3_config_v3vee.pl index 33e8664..ae2a86f 100755 --- a/v3_config_v3vee.pl +++ b/v3_config_v3vee.pl @@ -89,11 +89,11 @@ print "What is your kernel's maximum contiguous page allocation size in bytes (t $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] : "; @@ -122,6 +122,27 @@ $devmem='y'; 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 <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`; @@ -203,7 +229,7 @@ print " Memory block size: $chunk MB\n"; 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) { @@ -213,7 +239,7 @@ 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++) {