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
17 v3_config_v3vee.pl sourced:
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 ($config{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");
197 # Note: do_storage *must* have placed an IDE named ide0 in order for this to work
199 do_device(\%config, $pdir, "V3_CONFIG_NVRAM", "NVRAM", "nvram", 1, undef, " <storage>ide0</storage>\n"); #must have
203 # Network interfaces (attached to PCI bus)
206 print "\nWe will now consider network interfaces.\n\n";
207 do_network(\%config, $pdir, $dir, $name, "pci0", "southbridge");
212 # Generic Catch-all Device
214 do_generic(\%config, $pdir);
217 open(PAL,">$dir/$name.pal") or die "Cannot open $dir/$name.pal\n";
221 print $target "<vm class=\"PC\">\n\n";
222 print $target file_setup(\%config), "\n";
223 print $target memory_setup(\%config), "\n";
224 print $target paging_setup(\%config), "\n";
225 print $target memmap_setup(\%config), "\n";
226 print $target numa_setup(\%config), "\n";
227 print $target core_setup(\%config), "\n";
228 print $target schedule_setup(\%config), "\n";
229 print $target perftune_setup(\%config), "\n";
230 print $target telemetry_setup(\%config), "\n";
231 print $target extensions_setup(\%config), "\n";
232 print $target device_setup(\%config), "\n";
233 print $target "</vm>\n";
237 print "\n\nYour guest is now ready in the directory $dir\n";
243 my ($ques, $default) = @_;
245 print $ques." [$default] : ";
247 return get_user($default);
251 my ($ques, $default, $yans, $nans) = @_;
255 print $ques." [$default] : ";
256 $ans = get_user($default);
258 if (substr($ans,0,1) eq 'y' || substr($ans,0,1) eq 'Y') {
280 %numa = get_numa_data();
282 $numvcores = $cr->{numcores};
284 print "NUMA configuration involves the following:\n";
285 print " 1. Definition of virtual NUMA nodes and their corresponding regions of guest physical memory\n";
286 print " 2. Mapping of virtual NUMA nodes to physical NUMA nodes\n";
287 print " 3. Mapping of virtual cores to virtual NUMA nodes\n";
288 print " 4. Mapping of virtual cores to physical cores\n";
289 print "Your guest contains ".$numvcores." virtual cores.\n";
290 print "This host contains ".$numa{numcores}." physical cores and ".$numa{numnodes}." physical nodes.\n";
291 print "How many physical NUMA nodes does your target hardware have? [".$numa{numnodes}."] ? ";
292 $numpnodes=get_user($numa{numnodes});
293 $canauto=0 if ($numpnodes > $numa{numnodes});
294 print "How many physical cores does your target hardware have? [".$numa{numcores}."] ? ";
295 $numpcores=get_user($numa{numcores});
296 $canauto=0 if ($numpcores > $numa{numcores});
298 print "How many virtual NUMA nodes do you want? (up to $numvcores) for auto) [2] : ";
299 $numvnodes=get_user("2");
300 } while ($numvnodes<=0 || $numvnodes>$numvcores);
301 $cr->{numnodes} = $numvnodes;
302 $pernode = int(($cr->{mem}*1024*1024)/$numvnodes);
303 $lastnode = $pernode + ($cr->{mem}*1024*1024)-$pernode*$numvnodes;
304 print "Your guest has ".$cr->{mem}." MB of RAM, which we have defined and mapped like this:\n";
305 for ($i=0;$i<$numvnodes;$i++) {
306 my $start=$i*$pernode;
307 my $end=(($i==($numvnodes-1)) ? $start+$lastnode : $start+$pernode);
308 my $pnode = $i % $numpnodes;
309 $vnodemap[$i]=$pnode;
310 $start=sprintf("0x%x",$start);
311 $end=sprintf("0x%x",$end);
312 print "vnode $i : GPA $start to GPA $end : pnode $pnode\n";
313 push @{$cr->{nodes}}, { start=>$start, end=>$end, vnode=>$i, pnode=>$pnode};
317 print "We can now automatically map virtual cores to virtual NUMA nodes and physical CPUs using strided assignment\n";
318 print "assuming *this host's* NUMA configuration. Or you can enter the assignments manually. \n";
319 print " Which would you prefer {auto,manual} [auto] ? : ";
320 $doauto=1 if (get_user("auto") eq "auto");
322 print "Automatic mapping of virtual cores to virtual NUMA nodes and physical CPUs is not possible\n";
323 print "given your host configuration. Please configure manually below.\n";
327 for ($i=0;$i<$numvcores;$i++) {
328 my $vnode = $i % $numvnodes;
329 my $pnode = $vnodemap[$vnode];
330 my $pcores = $numa{"node$pnode"}{cores};
331 my $numpcores_per_pnode = $#{$pcores}+1; # assumes identical number on each node...
332 my $pcore = $numa{"node$pnode"}{cores}->[int($i/$numpnodes) % $numpcores_per_pnode];
333 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
334 $cr->{"core$i"}{pcore} = $pcore;
335 $cr->{"core$i"}{vnode} = $vnode;
338 for ($i=0;$i<$numvcores;$i++) {
339 print "What is the virtual NUMA node for virtual core $i ? [] : ";
340 my $vnode = get_user("");
341 my $pnode = $vnodemap[$vnode];
342 print "That maps to physical NUMA node $pnode.\n";
343 print "What is the physical core for virtual core $i ? [] : ";
344 my $pcore = get_user("");
345 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
346 $cr->{"core$i"}{pcore} = $pcore;
347 $cr->{"core$i"}{vnode} = $vnode;
354 sub get_numa_data() {
360 open (N, "numactl --hardware |");
362 if ($line=~/^node\s+(\d+)\s+cpus:\s+(.*)$/) {
364 my @cpus = split(/\s+/,$2);
366 if ($node>$maxnode) { $maxnode=$node; }
367 foreach $cpu (@cpus) {
368 if ($cpu>$maxcpu) { $maxcpu=$cpu; }
370 $numa{"node$node"}{cores}=\@cpus;
373 $numa{numnodes}=$maxnode+1;
374 $numa{numcores}=$maxcpu+1;
379 my ($cr,$pdir,$feature, $class, $id, $hardfail, $optblob, $nestblob) =@_;
381 if (is_palacios_core_feature_enabled($pdir, $feature)) {
382 print "We will include a $class since your Palacios build has it enabled\n";
383 add_device(\%config, $class, $id, $optblob, $nestblob);
385 if (defined($hardfail) && $hardfail) {
386 print "Wow, your Palacios build doesn't have a $class... We can't live without that...\n";
389 print "Not configuring a $class since your Palacios build doesn't have it enabled\n";
394 sub do_consoles_and_ports {
395 my ($cr, $pdir) = @_;
397 my $cga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CGA");
398 my $curses = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CURSES_CONSOLE");
399 my $cons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CONSOLE");
400 my $cancga = $cga && $curses && $cons;
401 my $vga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VGA");
402 my $gcons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_GRAPHICS_CONSOLE");
403 my $canvga = $vga && $gcons;
404 my $serial = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_SERIAL_UART");
405 my $charstream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CHAR_STREAM");
406 my $stream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_STREAM");
407 my $canserial = $serial && $charstream && $stream;
408 my $virtioconsole = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_CONSOLE");
409 my $canvirtioconsole = $virtioconsole; # probably need to verify frontend
410 my $paragraph = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_PARAGRAPH");
411 my $canparagraph = $paragraph && $gcons;
413 print "Your Palacios configuration allows the following options:\n";
414 print " * CGA: classic 80x25 text-only PC console (common option): ".($cancga ? "available\n" : "NOT AVAILABLE\n");
415 print " * VGA: classic 640x480 graphical PC console (uncommon option): ".($canvga ? "available\n" : "NOT AVAILABLE\n");
416 print " * SERIAL: classic PC serial ports (common option): ".($canserial ? "available\n" : "NOT AVAILABLE\n");
417 print " * VIRTIO: Linux Virtio Console (uncommon option): ".($canvirtioconsole ? "available\n" : "NOT AVAILABLE\n");
418 print " * PARAGRAPH: Paravirtualized graphics card (uncommon option): ".($canparagraph ? "available\n" : "NOT AVAILABLE\n");
419 print "The CGA and VGA options are mutually exclusive\n";
420 print "THe VGA and PARAGRAPH options are mutually exclusive\n";
422 if (!($cancga || $canvga || $canserial || $canvirtioconsole)) {
423 print "Hmm... No console mechanism is enabled in your Palacios build...\n";
424 print " This is probably not what you want...\n";
429 print "Do you want to use CGA as a console? [y] : ";
430 if (get_user("y") eq "y") {
431 add_device(\%config, "CGA_VIDEO", "cga", "passthrough=\"disable\"");
432 add_device(\%config, "CURSES_CONSOLE", "console", undef,
433 " <frontend tag=\"cga\" />\n".
434 " <tty>user</tty>\n");
440 if ($canvga && !$didcga) {
441 print "Do you want to use VGA as a console? [n] : ";
442 if (get_user("n") eq "y") {
443 add_device(\%config, "VGA", "vga", "passthrough=\"disable\" hostframebuf=\"enable\"");
444 # there is no gconsole device
451 print "You can include serial ports whether you use them for a console or not\n";
452 print "Note that you must configure your guest to place its console onto a serial port\n";
453 print "for it to be visible\n";
454 print "Do you want to include the serial ports (COM1..4) ? [y] : ";
455 if (get_user("y") eq "y") {
456 add_device(\%config,"SERIAL","serial");
457 add_device(\%config,"CHAR_STREAM","stream1","name=\"com1\"", " <frontend tag=\"serial\" com_port=\"1\" />\n");
458 add_device(\%config,"CHAR_STREAM","stream2","name=\"com2\"", " <frontend tag=\"serial\" com_port=\"2\" />\n");
459 add_device(\%config,"CHAR_STREAM","stream3","name=\"com3\"", " <frontend tag=\"serial\" com_port=\"3\" />\n");
460 add_device(\%config,"CHAR_STREAM","stream4","name=\"com4\"", " <frontend tag=\"serial\" com_port=\"4\" />\n");
467 if ($canvirtioconsole) {
468 print "Do you want to add a VIRTIO console? [n] : ";
469 if (get_user("n") eq "y") {
470 add_device(\%config,"LNX_VIRTIO_CONSOLE","virtio-cons",undef," <bus>pci0</bus>\n");
471 print "NOTE: no backend for the VIRTIO console is currently configured\n";
477 if ($canparagraph && !$didvga) {
478 print "Do you want to add a PARAGRAPH graphics card? [n] : ";
479 if (get_user("n") eq "y") {
480 add_device(\%config, "PARAGRAPH", "paragraph", undef,
481 " <bus>pci0</bus>\n".
482 " <mode>gcons_mem</bus>\n");
487 if (!($didcga || $didvga || $didserial || $didvirtioconsole || $didparagraph)) {
488 print "You have configured your guest without any obvious way of interacting with it....\n";
489 print " This is probably not what you want...\n";
495 my ($cr,$pdir,$dir,$name, $pcibus)=@_;
496 my $canvnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET");
497 my $canbridge = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NIC_BRIDGE");
498 my $canoverlay = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET_NIC") && $canvnet;
499 my $canvirtio = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_NET");
500 my $canvirtiovnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_VNET"); # not sure...
501 my $canne2k = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NE2K");
502 my $canrtl8139 = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_RTL8139");
511 push @devs, "virtio" if $canvirtio;
512 push @devs, "rtl8139" if $canrtl8139;
513 push @devs, "ne2000" if $canne2k;
515 push @backends, "bridge" if $canbridge;
516 push @backends, "vnet" if $canoverlay;
519 print "You have no network device implementations enabled in your Palacios build, so we are skipping networking\n";
523 if ($#backends==-1) {
524 print "You have no network device backends enabled in your Palacios build, so we are skipping networking\n";
531 last if (!yn_question("Do you want to add ".($num==0 ? "a" : "another")." network device?","n",1,0));
532 print "This requires the addition of the frontend device (the NIC) and a backend device.\n";
533 print "Frontends in Palacios include:\n";
534 print " * Virtio NIC (paravirtualized - common) : ".($canvirtio? "available" : "UNAVAILABLE")."\n";
535 print " * RTL8139 NIC (uncommon) : ".($canrtl8139? "available" : "UNAVAILABLE")."\n";
536 print " * NE2000 NIC (uncommon) : ".($canne2k? "available" : "UNAVAILABLE")."\n";
537 print "Which frontend do you want to add? {".join(", ", @devs)."} : ";
538 $front = get_user("");
539 @test = grep { /^$front$/ } @devs;
541 print "Unknown frontend\n";
544 print "Backends in Palacios include:\n";
545 print " * Bridge (direct attach to host NIC - common) : ".($canbridge? "available" : "UNAVAILABLE")."\n";
546 print " * VNET overlay (uncommon) : ".($canoverlay ? "available" : "UNAVAILABLE")."\n";
547 print "Which backend do you want to add? {".join(", ", @backends)."} : ";
548 $back = get_user("");
549 @test = grep { /^$back/ } @backends;
551 print "Unknown backend\n";
555 print "What MAC address do you want your NIC to have? [$mac] : ";
557 if ($front eq "virtio") {
558 add_device($cr,"LNX_VIRTIO_NIC","net$num",undef,
559 " <bus>$pcibus</bus>\n".
560 " <mac>$mac</mac>\n".
561 " <model mode=\"guest-driven\" />\n");
562 print "The device is configured with default guest-driven operation\n";
564 if ($front eq "rtl8139") {
565 add_device($cr,"RTL8139","net$num",undef,
566 " <bus>$pcibus</bus>\n".
567 " <mac>$mac</mac>\n");
569 if ($front eq "ne2000") {
570 add_device($cr,"NE2000","net$num",undef,
571 " <bus>$pcibus</bus>\n".
572 " <mac>$mac</mac>\n");
575 if ($back eq "bridge") {
577 print "What is the name of the host NIC you want to bridge to? [eth0] : ";
578 $host=get_user("eth0");
579 add_device($cr,"NIC_BRIDGE","net$num-back",undef,
580 " <frontend tag=\"net$num\" />\n".
581 " <hostnic name=\"$host\" />\n");
584 if ($back eq "vnet") {
585 add_device($cr,"VNET_NIC","net$num-back",undef,
586 " <frontend tag=\"net$num\" />\n");
587 print "Important: In order to use the VNET overlay, you must also create routes at run-time via /proc/v3vee/vnet\n";
595 return sprintf("%02X:%02X:%02X:%02X:%02X:%02X",
606 my ($cr,$pdir,$dir,$name,$pcibus,$controller)=@_;
611 do_device($cr, $pdir, "V3_CONFIG_IDE", "IDE", "ide0",1,undef,
612 " <bus>$pcibus</bus>\n".
613 " <controller>$controller</controller>\n" ); # must have
614 print "You can attach up to four storage devices to the storage controller \"ide\"\n";
615 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_0",
616 " <bus_num>0</bus_num>\n".
617 " <drive_num>0</drive_num>\n");
618 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_1",
619 " <bus_num>0</bus_num>\n".
620 " <drive_num>1</drive_num>\n");
621 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_0",
622 " <bus_num>1</bus_num>\n".
623 " <drive_num>0</drive_num>\n");
624 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_1",
625 " <bus_num>1</bus_num>\n".
626 " <drive_num>1</drive_num>\n");
628 if (is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_BLOCK")) {
629 print "You can attach VIRTIO block devices. How many do you need? [0] : ";
630 my $num = get_user("0");
632 for ($i=0;$i<$num;$i++) {
633 add_device($cr,"LNX_VIRTIO_BLK","virtioblk$i",undef," <bus>$pcibus</bus>\n");
634 do_storage_backend($cr, $pdir, $dir, $name, "virtioblk$i", "data$i", "");
640 sub do_storage_backend {
641 my ($cr, $pdir, $dir, $name, $frontend, $loc, $frontendblock) = @_;
642 my ($canramdisk, $canfiledisk, $cannetdisk, $cantmpdisk);
643 my @devs=("cd","hd","nothing");
650 $canramdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_RAMDISK");
651 $canfiledisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_FILEDISK");
652 $cannetdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_NETDISK");
653 $cantmpdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_TMPDISK");
654 push @disks, "ramdisk" if $canramdisk;
655 push @disks, "filedisk" if $canramdisk;
656 push @disks, "netdisk" if $cannetdisk;
657 push @disks, "tmpdisk" if $cantmpdisk;
660 if (!$canramdisk && !$canfiledisk && !$cannetdisk && !$cantmpdisk) {
661 print "You have no storage implementations enabled in your Palacios build, so it is impossible\n";
662 print "to add anything to storage controller \"$frontend\" location \"$loc\"\n";
668 print "What do you want to attach to storage controller \"$frontend\" location \"$loc\"\n";
669 print " Your options are {".join(", ",@devs)."} [nothing] : ";
670 $what = get_user("nothing");
671 @test = grep { /^$what$/ } @devs;
673 if ($what eq "nothing") {
676 print "A storage device requires one of the following implementations\n";
677 print " * RAMDISK - the data is kept in memory (common) : ".($canramdisk ? "available" : "UNAVAILABLE")."\n";
678 print " * FILEDISK - the data is kept in a host file (common) : ".($canfiledisk ? "available" : "UNAVAILABLE")."\n";
679 print " * NETDISK - the data is accessed via the network (uncommon) : ".($cannetdisk ? "available" : "UNAVAILABLE")."\n";
680 print " * TMPDISK - the data is kept in memory and discarded (common) : ".($cantmpdisk ? "available" : "UNAVAILABLE")."\n";
681 print " * RAMDISK - the data is kept in memory (common) : ".($canramdisk ? "available" : "UNAVAILABLE")."\n";
683 print "Which option do you want for this device? {".join(", ",@disks)."} [] : ";
684 $type = get_user("");
685 my @test = grep {/^$type$/} @disks;
689 if ($type eq "filedisk" || $type eq "ramdisk") {
690 print "$type requires a file (.iso for example). Do you have one? [y] : ";
691 if (get_user("y") eq "y") {
693 print "What is its path? [] : ";
694 $file = get_user("");
696 print "$file does not exist\n";
699 if (system("cp $file $dir/$frontend\_$loc.dat")) {
700 print "Unable to copy $file\n";
706 print "We will make one. How big should it be in MB? [64] : ";
707 $size = get_user("64");
708 gen_image_file("$dir/$frontend\_$loc.dat",$size);
710 $attach=" <frontend tag=\"$frontend\">\n";
712 $attach.=" <model>V3VEE CDROM</model>\n".
713 " <type>CDROM</type>\n".$frontendblock;
715 $attach.=" <model>V3VEE HD</model>\n".
716 " <type>HD</type>\n".$frontendblock;
718 $attach.=" </frontend>\n";
720 if ($type eq "ramdisk") {
721 add_device($cr,"RAMDISK","$frontend\_$loc", undef,
722 " <file>$frontend\_$loc</file>\n".$attach);
723 add_file($cr, "$frontend\_$loc", "$frontend\_$loc.dat");
725 add_device($cr,"FILEDISK","$frontend\_$loc", $what eq "hd" ? "writable=\"1\"" : undef,
726 " <path>$frontend\_$loc.dat</path>\n".$attach);
730 print "$type is not currently supported\n";
742 <!-- DMA 1 registers -->
745 <mode>PRINT_AND_IGNORE</mode>
748 <!-- DMA 2 registers -->
751 <mode>PRINT_AND_IGNORE</mode>
754 <!-- DMA 1 page registers -->
757 <mode>PRINT_AND_IGNORE</mode>
760 <!-- DMA 2 page registers -->
763 <mode>PRINT_AND_IGNORE</mode>
766 <!-- DMA 1 Misc Registers -->
769 <mode>PRINT_AND_IGNORE</mode>
772 <!-- DMA 2 Misc Registers -->
775 <mode>PRINT_AND_IGNORE</mode>
781 <mode>PRINT_AND_IGNORE</mode>
787 <mode>PRINT_AND_IGNORE</mode>
793 <mode>PRINT_AND_IGNORE</mode>
797 my @dev = find_devices_by_class($cr,"PARALLEL");
801 <!-- Parallel Port -->
804 <mode>PRINT_AND_IGNORE</mode>
809 my @par = find_devices_by_class($cr,"SERIAL");
813 <!-- Serial COM 1 -->
816 <mode>PRINT_AND_IGNORE</mode>
819 <!-- Serial COM 2 -->
822 <mode>PRINT_AND_IGNORE</mode>
825 <!-- Serial COM 3 -->
828 <mode>PRINT_AND_IGNORE</mode>
831 <!-- Serial COM 4 -->
834 <mode>PRINT_AND_IGNORE</mode>
840 do_device($cr, $pdir, "V3_CONFIG_GENERIC", "GENERIC", "generic", 1, undef, $block);
844 my ($cr, $name, $file) = @_;
846 push @{$cr->{files}}, { name=>$name, file=>$file};
851 my ($cr, $class, $id, $optblob, $nestblob) = @_;
853 push @{$cr->{devices}}, { class=>$class, id=>$id, opt=>$optblob, nest=>$nestblob };
856 sub find_devices_by_class {
858 return grep { $_->{class} eq $c } @{$cr->{devices}};
866 if (!defined($cr->{numa})) {
869 $s.=" <mem_layout vnodes=\"".($#{$cr->{nodes}}+1)."\" >\n";
870 foreach $vnode (@{$cr->{nodes}}) {
871 $s.=" <region start_addr=\"".$vnode->{start}."\" end_addr=\"".$vnode->{end}."\" vnode=\"".$vnode->{vnode}."\" node=\"".$vnode->{pnode}."\" />\n";
873 $s.=" </mem_layout>\n";
884 $s.= " <cores count=\"".$cr->{numcores}."\">\n";
885 if (!defined($cr->{numa})) {
888 for ($i=0;$i<$cr->{numcores};$i++) {
889 $s.= " <core target_cpu=\"".$cr->{"core$i"}{pcore}."\" vnode=\"".$cr->{"core$i"}{vnode}."\" />\n";
901 return " <memory>".$cr->{mem}."</memory>\n";
908 $s.= " <paging mode=\"".$cr->{paging_mode}."\">\n";
909 $s.= " <large_pages>".$cr->{large_pages}."</large_pages>\n";
910 $s.= " <strategy>".$cr->{shadow_strategy}."</strategy>\n";
919 return $cr->{memmap_block};
925 return $cr->{schedule_hz_block};
932 if (defined($cr->{perftune_block})) {
934 $s.= $cr->{perftune_block};
935 $s.=" </perftune>\n";
940 sub extensions_setup {
943 if (defined($cr->{extensions_block})) {
944 $s.=" <extensions>\n";
945 $s.= $cr->{extensions_block};
946 $s.=" </extensions>\n";
951 sub telemetry_setup {
953 return " <telemetry>".$cr->{telemetry}."</telemetry>\n";
961 if (!defined($cr->{files})) {
962 return " <!-- this configuration contains no files -->\n";
967 foreach $cf (@{$cr->{files}}) {
968 $s.=" <file id=\"".$cf->{name}."\" filename=\"".$cf->{file}."\" />\n";
982 foreach $cd (@{$cr->{devices}}) {
983 $s.=" <device class=\"".$cd->{class}."\" id=\"".$cd->{id}."\"";
984 if (defined($cd->{opt})) {
987 if (!defined($cd->{nest})) {
1007 my $inp = <STDIN>; chomp($inp);
1016 sub get_kernel_feature {
1021 $x=`grep $feature= $dir/config-\`uname -r\``;
1026 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1034 sub get_palacios_core_feature {
1039 $x=`grep $feature= $dir/.config`;
1044 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1052 sub is_palacios_core_feature_enabled {
1053 my $out = get_palacios_core_feature(@_);
1054 return !defined($out) ? 0 : $out eq "y";
1062 $exp = log($x) /log(2);
1064 return $exp==int($exp);
1068 sub gen_image_file {
1069 my ($name, $size_mb) = @_;
1071 if (system("dd if=/dev/zero of=$name bs=1048576 count=$size_mb")) {