6 Welcome. The purpose of this tool is to simplify the creation of
7 common forms of guests for the V3VEE environment on a Linux system.
8 These guests *should* work for any host embedding (e.g., Kitten) but
9 there may be hidden Linux assumptions.
11 The tool assumes you have already built Palacios, the Linux embedding,
12 and the Linux user-sapce tools. If you haven't done this, hit CTRL-C
13 now, configure and build Palacios, the user-space tools, and run
16 This tool also assumes that you have the environment produced by
21 What this tool builds is a directory that contains a guest
22 configuration file (the ".pal" file) and its dependent files. Note
23 that lots of additional functionality is possible beyond what can be
24 configured with this tool. The precise functionality depends on the
25 version and branch of Palacios, and what was configured into it when
26 it was built. To access such functionality, you need to write your
27 own .pal file, or use one generated by this tool as a basis.
29 Any .pal guest configuration file is instantiated as a VM in the
33 v3_create -b guest.pal name_of_guest
35 Any files (disk images) that your guest configuration depends on
36 must be accessible when v3_create is run.
38 Once the VM is instantiated, you can then launch it:
40 v3_launch /dev/v3-vmN (N is given by the v3_create command)
42 We will configure your guest via a sequence of questions.
47 $pdir = $ENV{PALACIOS_DIR};
49 if (!defined($pdir)) {
50 print "Please set PALACIOS_DIR (you probably have not sourced ENV) and try again\n";
54 $otherbios = get_palacios_core_feature($pdir,"V3_CONFIG_OTHERBIOS");
55 $otherbios = !defined($otherbios) ? 0 : $otherbios eq "y" ? 1: 0;
57 print "Your Palacios installation is set up for a custom BIOS. \n";
58 print "You probably do NOT want to use this tool... Continue ? [n] : ";
59 if (get_user("n") eq "n") { exit -1; }
64 print "What is the name of your guest? [$name] : ";
65 $name = get_user($name);
68 print "What is the directory into which we will put your guest? [$dir] : ";
69 $dir = get_user($dir);
71 print "Unable to create the directory\n";
75 $config{numcores} = quant_question("How many cores will your guest have?", 1);
77 $config{mem} = quant_question("How much memory should it have in MB?", 256);
79 if ($config{numcores}>1) {
80 print "Do you want to to produce a NUMA configuration and mapping for your guest? [n] : ";
81 if (get_user("n") eq "y") {
82 do_numa_config(\%config,$pdir);
87 print "We will give your guest the default performance tuning characteristics\n";
88 $config{perftune_block} .= <<PERFTUNE
90 <strategy>friendly</strategy>
91 <threshold>1000</threshold>
97 print "We will give your guest the default host scheduler interaction characteristics\n";
98 $config{schedule_hz_block} .= " <schedule_hz>100</schedule_hz>\n";
101 $config{telemetry} = yn_question("Do you want telemetry (information about guest exits) ?", "y", "enable", "disable");
104 $config{paging_mode} = yn_question("Do you want to use nested paging if possible on your hardware?\n This will often (but not always) perform faster than shadow paging. ", "y", "nested", "shadow");
106 $config{large_pages} = yn_question("Do you want to use large pages if possible on your hardware?\n This will often (but not always) perform faster. ", "n", "true", "false");
108 print "We will give your guest the default shadow paging strategy for when shadow paging is used.\n";
109 $config{shadow_strategy} = "VTLB";
112 $config{memmap_block} = " <!-- there are no passthrough memory regions, but you can add them using\n".
113 " the <memmap> syntax described in the manual -->\n";
115 if (is_palacios_core_feature_enabled($pdir, "V3_CONFIG_EXT_VMWARE")) {
116 print "We will include the VMware Personality Extension since your Palacios build has it enabled\n";
117 $config{extensions_block} .= " <extension name=\"VMWARE_IFACE\"></extension>\n";
123 do_device(\%config, $pdir, "V3_CONFIG_BOCHS_DEBUG", "BOCHS_DEBUG", "bios_debug");
124 do_device(\%config, $pdir, "V3_CONFIG_OS_DEBUG", "OS_DEBUG", "os_debug");
130 do_device(\%config, $pdir, "V3_CONFIG_PIC", "8259A", "PIC", 1); # must have
131 if ($config{numcores}==1 && is_palacios_core_feature_enabled($pdir,"V3_CONFIG_BOCHSBIOS")) {
132 print "This is a single core guest and your Palacios setup uses the legacy BOCHS BIOS.\n";
133 print " Do you want to have only the legacy (pre-APIC) interrupt controller logic? [n] :";
134 if (get_user("n") eq "y") {
138 do_device(\%config, $pdir, "V3_CONFIG_APIC", "LAPIC", "apic", 1); # must have
139 do_device(\%config, $pdir, "V3_CONFIG_IO_APIC", "IOAPIC", "ioapic", 1, undef, " <apic>apic</apic>\n");
143 # PCI buses and north/south bridge - all must haves
145 do_device(\%config, $pdir, "V3_CONFIG_PCI", "PCI", "pci0",1); # must have
146 do_device(\%config, $pdir, "V3_CONFIG_I440FX", "i440FX", "northbridge",1, undef, " <bus>pci0</bus>\n"); #must have
147 do_device(\%config, $pdir, "V3_CONFIG_PIIX3", "PIIX3", "southbridge",1, undef, " <bus>pci0</bus>\n"); #must have
150 # MPTABLE for legacy BIOS. Innocuous for SEABIOS or OTHERBIOS
153 if (is_palacios_core_feature_enabled($pdir,"V3_CONFIG_MPTABLE")) {
154 print "We will include a classic MPTABLE constructor to describe your machine to the guest\n";
155 add_device(\%config, "MPTABLE", "mptable");
157 if ($numcores>1 && is_palacios_core_feature_enabled($pdir,"V3_CONFIG_BOCHSBIOS")) {
158 print "This is a multicore guest, and your Palacios configuration uses the classic BOCHS BIOS\n".
159 "but does not have the MPTABLE constructor enabled... This guest will almost\n".
160 "certainly fail to work. Do you want to continue anyway? [n] :";
161 if (get_user("n") eq "n") {
171 do_device(\%config, $pdir, "V3_CONFIG_PIT", "8254_PIT", "PIT",1); # must have
174 # Keyboard and mouse (PS/2 controller)
176 do_device(\%config, $pdir, "V3_CONFIG_KEYBOARD", "KEYBOARD", "keyboard",1); #must have
180 # Displays, Consoles, Serial
182 print "\nWe will now consider consoles and serial ports.\n\n";
183 do_consoles_and_ports(\%config, $pdir);
187 # Storage controllers and devices (attached to PCI bus)
190 print "\nWe will now consider storage controllers and devices.\n\n";
191 do_storage(\%config, $pdir, $dir, $name, "pci0", "southbridge");
195 # Network interfaces (attached to PCI bus)
198 print "\nWe will now consider network interfaces.\n\n";
199 do_network(\%config, $pdir, $dir, $name, "pci0", "southbridge");
204 # Generic Catch-all Device
206 do_generic(\%config, $pdir);
209 open(PAL,">$dir/$name.pal") or die "Cannot open $dir/$name.pal\n";
213 print $target "<vm class=\"PC\">\n\n";
214 print $target file_setup(\%config), "\n";
215 print $target memory_setup(\%config), "\n";
216 print $target paging_setup(\%config), "\n";
217 print $target memmap_setup(\%config), "\n";
218 print $target numa_setup(\%config), "\n";
219 print $target core_setup(\%config), "\n";
220 print $target schedule_setup(\%config), "\n";
221 print $target perftune_setup(\%config), "\n";
222 print $target telemetry_setup(\%config), "\n";
223 print $target extensions_setup(\%config), "\n";
224 print $target device_setup(\%config), "\n";
225 print $target "</vm>\n";
229 print "\n\nYour guest is now ready in the directory $dir\n";
235 my ($ques, $default) = @_;
237 print $ques." [$default] : ";
239 return get_user($default);
243 my ($ques, $default, $yans, $nans) = @_;
247 print $ques." [$default] : ";
248 $ans = get_user($default);
250 if (substr($ans,0,1) eq 'y' || substr($ans,0,1) eq 'Y') {
272 %numa = get_numa_data();
274 $numvcores = $cr->{numcores};
276 print "NUMA configuration involves the following:\n";
277 print " 1. Definition of virtual NUMA nodes and their corresponding regions of guest physical memory\n";
278 print " 2. Mapping of virtual NUMA nodes to physical NUMA nodes\n";
279 print " 3. Mapping of virtual cores to virtual NUMA nodes\n";
280 print " 4. Mapping of virtual cores to physical cores\n";
281 print "Your guest contains ".$numvcores." virtual cores.\n";
282 print "This host contains ".$numa{numcores}." physical cores and ".$numa{numnodes}." physical nodes.\n";
283 print "How many physical NUMA nodes does your target hardware have? [".$numa{numnodes}."] ? ";
284 $numpnodes=get_user($numa{numnodes});
285 $canauto=0 if ($numpnodes > $numa{numnodes});
286 print "How many physical cores does your target hardware have? [".$numa{numcores}."] ? ";
287 $numpcores=get_user($numa{numcores});
288 $canauto=0 if ($numpcores > $numa{numcores});
290 print "How many virtual NUMA nodes do you want? (up to $numvcores) for auto) [2] : ";
291 $numvnodes=get_user("2");
292 } while ($numvnodes<=0 || $numvnodes>$numvcores);
293 $cr->{numnodes} = $numvnodes;
294 $pernode = int(($cr->{mem}*1024*1024)/$numvnodes);
295 $lastnode = $pernode + ($cr->{mem}*1024*1024)-$pernode*$numvnodes;
296 print "Your guest has ".$cr->{mem}." MB of RAM, which we have defined and mapped like this:\n";
297 for ($i=0;$i<$numvnodes;$i++) {
298 my $start=$i*$pernode;
299 my $end=(($i==($numvnodes-1)) ? $start+$lastnode : $start+$pernode);
300 my $pnode = $i % $numpnodes;
301 $vnodemap[$i]=$pnode;
302 $start=sprintf("0x%x",$start);
303 $end=sprintf("0x%x",$end);
304 print "vnode $i : GPA $start to GPA $end : pnode $pnode\n";
305 push @{$cr->{nodes}}, { start=>$start, end=>$end, vnode=>$i, pnode=>$pnode};
309 print "We can now automatically map virtual cores to virtual NUMA nodes and physical CPUs using strided assignment\n";
310 print "assuming *this host's* NUMA configuration. Or you can enter the assignments manually. \n";
311 print " Which would you prefer {auto,manual} [auto] ? : ";
312 $doauto=1 if (get_user("auto") eq "auto");
314 print "Automatic mapping of virtual cores to virtual NUMA nodes and physical CPUs is not possible\n";
315 print "given your host configuration. Please configure manually below.\n";
319 for ($i=0;$i<$numvcores;$i++) {
320 my $vnode = $i % $numvnodes;
321 my $pnode = $vnodemap[$vnode];
322 my $pcores = $numa{"node$pnode"}{cores};
323 my $numpcores_per_pnode = $#{$pcores}+1; # assumes identical number on each node...
324 my $pcore = $numa{"node$pnode"}{cores}->[int($i/$numpnodes) % $numpcores_per_pnode];
325 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
326 $cr->{"core$i"}{pcore} = $pcore;
327 $cr->{"core$i"}{vnode} = $vnode;
330 for ($i=0;$i<$numvcores;$i++) {
331 print "What is the virtual NUMA node for virtual core $i ? [] : ";
332 my $vnode = get_user("");
333 my $pnode = $vnodemap[$vnode];
334 print "That maps to physical NUMA node $pnode.\n";
335 print "What is the physical core for virtual core $i ? [] : ";
336 my $pcore = get_user("");
337 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
338 $cr->{"core$i"}{pcore} = $pcore;
339 $cr->{"core$i"}{vnode} = $vnode;
346 sub get_numa_data() {
352 open (N, "numactl --hardware |");
354 if ($line=~/^node\s+(\d+)\s+cpus:\s+(.*)$/) {
356 my @cpus = split(/\s+/,$2);
358 if ($node>$maxnode) { $maxnode=$node; }
359 foreach $cpu (@cpus) {
360 if ($cpu>$maxcpu) { $maxcpu=$cpu; }
362 $numa{"node$node"}{cores}=\@cpus;
365 $numa{numnodes}=$maxnode+1;
366 $numa{numcores}=$maxcpu+1;
371 my ($cr,$pdir,$feature, $class, $id, $hardfail, $optblob, $nestblob) =@_;
373 if (is_palacios_core_feature_enabled($pdir, $feature)) {
374 print "We will include a $class since your Palacios build has it enabled\n";
375 add_device(\%config, $class, $id, $optblob, $nestblob);
377 if (defined($hardfail) && $hardfail) {
378 print "Wow, your Palacios build doesn't have a $class... We can't live without that...\n";
381 print "Not configuring a $class since your Palacios build doesn't have it enabled\n";
386 sub do_consoles_and_ports {
387 my ($cr, $pdir) = @_;
389 my $cga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CGA");
390 my $curses = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CURSES_CONSOLE");
391 my $cons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CONSOLE");
392 my $cancga = $cga && $curses && $cons;
393 my $vga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VGA");
394 my $gcons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_GRAPHICS_CONSOLE");
395 my $canvga = $vga && $gcons;
396 my $serial = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_SERIAL_UART");
397 my $charstream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CHAR_STREAM");
398 my $stream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_STREAM");
399 my $canserial = $serial && $charstream && $stream;
400 my $virtioconsole = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_CONSOLE");
401 my $canvirtioconsole = $virtioconsole; # probably need to verify frontend
402 my $paragraph = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_PARAGRAPH");
403 my $canparagraph = $paragraph && $gcons;
405 print "Your Palacios configuration allows the following options:\n";
406 print " * CGA: classic 80x25 text-only PC console (common option): ".($cancga ? "available\n" : "NOT AVAILABLE\n");
407 print " * VGA: classic 640x480 graphical PC console (uncommon option): ".($canvga ? "available\n" : "NOT AVAILABLE\n");
408 print " * SERIAL: classic PC serial ports (common option): ".($canserial ? "available\n" : "NOT AVAILABLE\n");
409 print " * VIRTIO: Linux Virtio Console (uncommon option): ".($canvirtioconsole ? "available\n" : "NOT AVAILABLE\n");
410 print " * PARAGRAPH: Paravirtualized graphics card (uncommon option): ".($canparagraph ? "available\n" : "NOT AVAILABLE\n");
411 print "The CGA and VGA options are mutually exclusive\n";
412 print "THe VGA and PARAGRAPH options are mutually exclusive\n";
414 if (!($cancga || $canvga || $canserial || $canvirioconsole)) {
415 print "Hmm... No console mechanism is enabled in your Palacios build...\n";
416 print " This is probably not what you want...\n";
421 print "Do you want to use CGA as a console? [y] : ";
422 if (get_user("y") eq "y") {
423 add_device(\%config, "CGA_VIDEO", "cga", "passthrough=\"disable\"");
424 add_device(\%config, "CURSES_CONSOLE", "console", undef,
425 " <frontend tag=\"cga\" />\n".
426 " <tty>user</tty>\n");
432 if ($canvga && !$didcga) {
433 print "Do you want to use VGA as a console? [n] : ";
434 if (get_user("n") eq "y") {
435 add_device(\%config, "VGA", "vga", "passthrough=\"disable\" hostframebuf=\"enable\"");
436 # there is no gconsole device
443 print "You can include serial ports whether you use them for a console or not\n";
444 print "Note that you must configure your guest to place its console onto a serial port\n";
445 print "for it to be visible\n";
446 print "Do you want to include the serial ports (COM1..4) ? [y] : ";
447 if (get_user("y") eq "y") {
448 add_device(\%config,"SERIAL","serial");
449 add_device(\%config,"CHAR_STREAM","stream1","name=\"com1\"", " <frontend tag=\"serial\" com_port=\"1\" />\n");
450 add_device(\%config,"CHAR_STREAM","stream2","name=\"com2\"", " <frontend tag=\"serial\" com_port=\"2\" />\n");
451 add_device(\%config,"CHAR_STREAM","stream3","name=\"com3\"", " <frontend tag=\"serial\" com_port=\"3\" />\n");
452 add_device(\%config,"CHAR_STREAM","stream4","name=\"com4\"", " <frontend tag=\"serial\" com_port=\"4\" />\n");
459 if ($canvirtioconsole) {
460 print "Do you want to add a VIRTIO console? [n] : ";
461 if (get_user("n") eq "y") {
462 add_device(\%config,"LNX_VIRTIO_CONSOLE","virtio-cons",undef," <bus>pci0</bus>\n");
463 print "NOTE: no backend for the VIRTIO console is currently configured\n";
469 if ($canparagraph && !$didvga) {
470 print "Do you want to add a PARAGRAPH graphics card? [n] : ";
471 if (get_user("n") eq "y") {
472 add_device(\%config, "PARAGRAPH", "paragraph", undef,
473 " <bus>pci0</bus>\n".
474 " <mode>gcons_mem</bus>\n");
479 if (!($didcga || $didvga || $didserial || $didvirioconsole || $didparagraph)) {
480 print "You have configured your guest without any obvious way of interacting with it....\n";
481 print " This is probably not what you want...\n";
487 my ($cr,$pdir,$dir,$name, $pcibus)=@_;
488 my $canvnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET");
489 my $canbridge = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NIC_BRIDGE");
490 my $canoverlay = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET_NIC") && $canvnet;
491 my $canvirtio = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_NET");
492 my $canvirtiovnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_VNET"); # not sure...
493 my $canne2k = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NE2K");
494 my $canrtl8139 = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_RTL8139");
503 push @devs, "virtio" if $canvirtio;
504 push @devs, "rtl8139" if $canrtl8139;
505 push @devs, "ne2000" if $canne2k;
507 push @backends, "bridge" if $canbridge;
508 push @backends, "vnet" if $canoverlay;
511 print "You have no network device implementations enabled in your Palacios build, so we are skipping networking\n";
515 if ($#backends==-1) {
516 print "You have no network device backends enabled in your Palacios build, so we are skipping networking\n";
523 last if (!yn_question("Do you want to add ".($num==0 ? "a" : "another")." network device?","n",1,0));
524 print "This requires the addition of the frontend device (the NIC) and a backend device.\n";
525 print "Frontends in Palacios include:\n";
526 print " * Virtio NIC (paravirtualized - common) : ".($canvirtio? "available" : "UNAVAILABLE")."\n";
527 print " * RTL8139 NIC (uncommon) : ".($canrtl8139? "available" : "UNAVAILABLE")."\n";
528 print " * NE2000 NIC (uncommon) : ".($canne2k? "available" : "UNAVAILABLE")."\n";
529 print "Which frontend do you want to add? {".join(", ", @devs)."} : ";
530 $front = get_user("");
531 @test = grep { /^$front$/ } @devs;
533 print "Unknown frontend\n";
536 print "Backends in Palacios include:\n";
537 print " * Bridge (direct attach to host NIC - common) : ".($canbridge? "available" : "UNAVAILABLE")."\n";
538 print " * VNET overlay (uncommon) : ".($canoverlay ? "available" : "UNAVAILABLE")."\n";
539 print "Which backend do you want to add? {".join(", ", @backends)."} : ";
540 $back = get_user("");
541 @test = grep { /^$back/ } @backends;
543 print "Unknown backend\n";
547 print "What MAC address do you want your NIC to have? [$mac] : ";
549 if ($front eq "virtio") {
550 add_device($cr,"LNX_VIRTIO_NIC","net$num",undef,
551 " <bus>$pcibus</bus>\n".
552 " <mac>$mac</mac>\n".
553 " <model mode=\"guest-driven\" />\n");
554 print "The device is configured with default guest-driven operation\n";
556 if ($front eq "rtl8139") {
557 add_device($cr,"RTL8139","net$num",undef,
558 " <bus>$pcibus</bus>\n".
559 " <mac>$mac</mac>\n");
561 if ($front eq "ne2000") {
562 add_device($cr,"NE2000","net$num",undef,
563 " <bus>$pcibus</bus>\n".
564 " <mac>$mac</mac>\n");
567 if ($back eq "bridge") {
569 print "What is the name of the host NIC you want to bridge to? [eth0] : ";
570 $host=get_user("eth0");
571 add_device($cr,"NIC_BRIDGE","net$num-back",undef,
572 " <frontend tag=\"net$num\" />\n".
573 " <hostnic>$host</hostnic>\n");
576 if ($back eq "vnet") {
577 add_device($cr,"VNET_NIC","net$num-back",undef,
578 " <frontend tag=\"net$num\" />\n");
579 print "Important: In order to use the VNET overlay, you must also create routes at run-time via /proc/v3vee/vnet\n";
587 return sprintf("%02X:%02X:%02X:%02X:%02X:%02X",
598 my ($cr,$pdir,$dir,$name,$pcibus,$controller)=@_;
603 do_device($cr, $pdir, "V3_CONFIG_IDE", "IDE", "ide0",1,undef,
604 " <bus>$pcibus</bus>\n".
605 " <controller>$controller</controller>\n" ); # must have
606 print "You can attach up to four storage devices to the storage controller \"ide\"\n";
607 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_0",
608 " <bus_num>0</bus_num>\n".
609 " <drive_num>0</drive_num>\n");
610 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_1",
611 " <bus_num>0</bus_num>\n".
612 " <drive_num>1</drive_num>\n");
613 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_0",
614 " <bus_num>1</bus_num>\n".
615 " <drive_num>0</drive_num>\n");
616 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_1",
617 " <bus_num>1</bus_num>\n".
618 " <drive_num>1</drive_num>\n");
620 if (is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_BLOCK")) {
621 print "You can attach VIRTIO block devices. How many do you need? [0] : ";
622 my $num = get_user("0");
624 for ($i=0;$i<$num;$i++) {
625 add_device($cr,"LNX_VIRTIO_BLK","virtioblk$i",undef," <bus>$pcibus</bus>\n");
626 do_storage_backend($cr, $pdir, $dir, $name, "virtioblk$i", "data$i", "");
632 sub do_storage_backend {
633 my ($cr, $pdir, $dir, $name, $frontend, $loc, $frontendblock) = @_;
634 my ($canramdisk, $canfiledisk, $cannetdisk, $cantmpdisk);
635 my @devs=("cd","hd","nothing");
642 $canramdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_RAMDISK");
643 $canfiledisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_FILEDISK");
644 $cannetdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_NETDISK");
645 $cantmpdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_TMPDISK");
646 push @disks, "ramdisk" if $canramdisk;
647 push @disks, "filedisk" if $canramdisk;
648 push @disks, "netdisk" if $cannetdisk;
649 push @disks, "tmpdisk" if $cantmpdisk;
652 if (!$canramdisk && !$canfiledisk && !$cannetdisk && !$cantmpdisk) {
653 print "You have no storage implementations enabled in your Palacios build, so it is impossible\n";
654 print "to add anything to storage controller \"$frontend\" location \"$loc\"\n";
660 print "What do you want to attach to storage controller \"$frontend\" location \"$loc\"\n";
661 print " Your options are {".join(", ",@devs)."} [nothing] : ";
662 $what = get_user("nothing");
663 @test = grep { /^$what$/ } @devs;
665 if ($what eq "nothing") {
668 print "A storage device requires one of the following implementations\n";
669 print " * RAMDISK - the data is kept in memory (common) : ".($canramdisk ? "available" : "UNAVAILABLE")."\n";
670 print " * FILEDISK - the data is kept in a host file (common) : ".($canfiledisk ? "available" : "UNAVAILABLE")."\n";
671 print " * NETDISK - the data is accessed via the network (uncommon) : ".($cannetdisk ? "available" : "UNAVAILABLE")."\n";
672 print " * TMPDISK - the data is kept in memory and discarded (common) : ".($cantmpdisk ? "available" : "UNAVAILABLE")."\n";
673 print " * RAMDISK - the data is kept in memory (common) : ".($canramdisk ? "available" : "UNAVAILABLE")."\n";
675 print "Which option do you want for this device? {".join(", ",@disks)."} [] : ";
676 $type = get_user("");
677 my @test = grep {/^$type$/} @disks;
681 if ($type eq "filedisk" || $type eq "ramdisk") {
682 print "$type requires a file (.iso for example). Do you have one? [y] : ";
683 if (get_user("y") eq "y") {
685 print "What is its path? [] : ";
686 $file = get_user("");
688 print "$file does not exist\n";
691 if (system("cp $file $dir/$frontend\_$loc.dat")) {
692 print "Unable to copy $file\n";
698 print "We will make one. How big should it be in MB? [64] : ";
699 $size = get_user("64");
700 gen_image_file("$dir/$frontend\_$loc.dat",$size);
702 $attach=" <frontend tag=\"$frontend\">\n";
704 $attach.=" <model>V3VEE CDROM</model>\n".
705 " <type>CDROM</type>\n".$frontendblock;
707 $attach.=" <model>V3VEE HD</model>\n".
708 " <type>HD</type>\n".$frontendblock;
710 $attach.=" </frontend>\n";
712 if ($type eq "ramdisk") {
713 add_device($cr,"RAMDISK","$frontend\_$loc", undef,
714 " <file>$frontend\_$loc</file>\n".$attach);
715 add_file($cr, "$frontend\_$loc", "$frontend\_$loc.dat");
717 add_device($cr,"FILEDISK","$frontend\_$loc", $what eq "hd" ? "writable=\"1\"" : undef,
718 " <path>$frontend\_$loc.dat</path>\n".$attach);
722 print "$type is not currently supported\n";
734 <!-- DMA 1 registers -->
737 <mode>PRINT_AND_IGNORE</mode>
740 <!-- DMA 2 registers -->
743 <mode>PRINT_AND_IGNORE</mode>
746 <!-- DMA 1 page registers -->
749 <mode>PRINT_AND_IGNORE</mode>
752 <!-- DMA 2 page registers -->
755 <mode>PRINT_AND_IGNORE</mode>
758 <!-- DMA 1 Misc Registers -->
761 <mode>PRINT_AND_IGNORE</mode>
764 <!-- DMA 2 Misc Registers -->
767 <mode>PRINT_AND_IGNORE</mode>
773 <mode>PRINT_AND_IGNORE</mode>
779 <mode>PRINT_AND_IGNORE</mode>
785 <mode>PRINT_AND_IGNORE</mode>
789 my @dev = find_devices_by_class($cr,"PARALLEL");
793 <!-- Parallel Port -->
796 <mode>PRINT_AND_IGNORE</mode>
801 my @par = find_devices_by_class($cr,"SERIAL");
805 <!-- Serial COM 1 -->
808 <mode>PRINT_AND_IGNORE</mode>
811 <!-- Serial COM 2 -->
814 <mode>PRINT_AND_IGNORE</mode>
817 <!-- Serial COM 3 -->
820 <mode>PRINT_AND_IGNORE</mode>
823 <!-- Serial COM 4 -->
826 <mode>PRINT_AND_IGNORE</mode>
832 do_device($cr, $pdir, "V3_CONFIG_GENERIC", "GENERIC", "generic", 1, undef, $block);
836 my ($cr, $name, $file) = @_;
838 push @{$cr->{files}}, { name=>$name, file=>$file};
843 my ($cr, $class, $id, $optblob, $nestblob) = @_;
845 push @{$cr->{devices}}, { class=>$class, id=>$id, opt=>$optblob, nest=>$nestblob };
848 sub find_devices_by_class {
850 return grep { $_->{class} eq $c } @{$cr->{devices}};
858 if (!defined($cr->{numa})) {
861 $s.=" <mem_layout vnodes=\"".($#{$cr->{nodes}}+1)."\" >\n";
862 foreach $vnode (@{$cr->{nodes}}) {
863 $s.=" <region start_addr=\"".$vnode->{start}."\" end_addr=\"".$vnode->{end}."\" vnode=\"".$vnode->{vnode}."\" node=\"".$vnode->{pnode}."\" />\n";
865 $s.=" </mem_layout>\n";
876 $s.= " <cores count=\"".$cr->{numcores}."\">\n";
877 if (!defined($cr->{numa})) {
880 for ($i=0;$i<$cr->{numcores};$i++) {
881 $s.= " <core target_cpu=\"".$cr->{"core$i"}{pcore}."\" vnode=\"".$cr->{"core$i"}{vnode}."\" />\n";
893 return " <memory>".$cr->{mem}."</memory>\n";
900 $s.= " <paging mode=\"".$cr->{paging_mode}."\">\n";
901 $s.= " <large_pages>".$cr->{large_pages}."</large_pages>\n";
902 $s.= " <strategy>".$cr->{shadow_strategy}."</strategy>\n";
911 return $cr->{memmap_block};
917 return $cr->{schedule_hz_block};
924 if (defined($cr->{perftune_block})) {
926 $s.= $cr->{perftune_block};
927 $s.=" </perftune>\n";
932 sub extensions_setup {
935 if (defined($cr->{extensions_block})) {
936 $s.=" <extensions>\n";
937 $s.= $cr->{extensions_block};
938 $s.=" </extensions>\n";
943 sub telemetry_setup {
945 return " <telemetry>".$cr->{telemetry}."</telemetry>\n";
953 if (!defined($cr->{files})) {
954 return " <!-- this configuration contains no files -->\n";
959 foreach $cf (@{$cr->{files}}) {
960 $s.=" <file id=\"".$cf->{name}."\" filename=\"".$cf->{file}."\" />\n";
974 foreach $cd (@{$cr->{devices}}) {
975 $s.=" <device class=\"".$cd->{class}."\" id=\"".$cd->{id}."\"";
976 if (defined($cd->{opt})) {
979 if (!defined($cd->{nest})) {
999 my $inp = <STDIN>; chomp($inp);
1008 sub get_kernel_feature {
1013 $x=`grep $feature= $dir/config-\`uname -r\``;
1018 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1026 sub get_palacios_core_feature {
1031 $x=`grep $feature= $dir/.config`;
1036 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1044 sub is_palacios_core_feature_enabled {
1045 my $out = get_palacios_core_feature(@_);
1046 return !defined($out) ? 0 : $out eq "y";
1054 $exp = log($x) /log(2);
1056 return $exp==int($exp);
1060 sub gen_image_file {
1061 my ($name, $size_mb) = @_;
1063 if (system("dd if=/dev/zero of=$name bs=1048576 count=$size_mb")) {