- print "warning: VMware GSX Server doesn't support --$debug\n"
- if $debug ne 'no-debug';
- print "warning: VMware GSX Server doesn't support --no-vga\n"
- if $vga eq 'none';
- print "warning: VMware GSX Server doesn't support --terminal\n"
- if $vga eq 'terminal';
- print "warning: VMware GSX Server doesn't support jitter\n"
- if defined $jitter;
-
- open (VMX, ">pintos.vmx") or die "pintos.vmx: create: $!\n";
- chmod 0777 & ~umask, "pintos.vmx";
- print VMX "#! /usr/bin/vmware -G\n";
- print VMX "config.version = 6\n";
- print VMX "guestOS = \"linux\"\n";
- print VMX "floppy0.present = FALSE\n";
-
- unlink ("pintos.out");
- print VMX "serial0.present = TRUE\n";
- print VMX "serial0.fileType = \"file\"\n";
- print VMX "serial0.fileName = \"pintos.out\"\n";
-
- if (! -e 'null.bin') {
- open (NULL, ">null.bin") or die "null.bin: create: $!\n";
- close (NULL);
- }
+ run_gsx ();
+ } else {
+ die "unknown simulator `$sim'\n";
+ }
+}
+
+# Runs Bochs.
+sub run_bochs {
+ # Select Bochs binary based on the chosen debugger.
+ my ($bin) = $debug eq 'monitor' ? 'bochs-dbg' : 'bochs';
+
+ # Write bochsrc.txt configuration file.
+ open (BOCHSRC, ">", "bochsrc.txt") or die "bochsrc.txt: create: $!\n";
+ print BOCHSRC <<EOF;
+romimage: file=\$BXSHARE/BIOS-bochs-latest, address=0xf0000
+vgaromimage: file=\$BXSHARE/VGABIOS-lgpl-latest
+boot: disk
+cpu: ips=1000000
+megs: $mem
+log: bochsout.txt
+panic: action=fatal
+EOF
+ print BOCHSRC "gdbstub: enabled=1\n" if $debug eq 'gdb';
+ print BOCHSRC "clock: sync=", $realtime ? 'realtime' : 'none',
+ " time0=0\n";
+ print_bochs_disk_line ("ata0-master", 0);
+ print_bochs_disk_line ("ata0-slave", 1);
+ if (defined ($disks_by_iface[2]{FILE_NAME})
+ || defined ($disks_by_iface[3]{FILE_NAME})) {
+ print BOCHSRC "ata1: enabled=1, ioaddr1=0x170, ",
+ "ioaddr2=0x370, irq=15\n";
+ print_bochs_disk_line ("ata1-master", 2);
+ print_bochs_disk_line ("ata1-slave", 3);
+ }
+ if ($vga ne 'terminal') {
+ print BOCHSRC "com1: enabled=1, mode=file, dev=/dev/stdout\n"
+ if $serial_out;
+ print BOCHSRC "display_library: nogui\n" if $vga eq 'none';
+ } else {
+ print BOCHSRC "display_library: term\n";
+ }
+ close (BOCHSRC);
+
+ # Compose Bochs command line.
+ my (@cmd) = ($bin, '-q');
+ push (@cmd, '-j', $jitter) if defined $jitter;
+
+ # Run Bochs.
+ print join (' ', @cmd), "\n";
+ my ($exit) = xsystem (@cmd);
+ if (WIFEXITED ($exit)) {
+ # Bochs exited normally.
+ # Ignore the exit code; Bochs normally exits with status 1,
+ # which is weird.
+ } elsif (WIFSIGNALED ($exit)) {
+ die "Bochs died with signal ", WTERMSIG ($exit), "\n";
+ } else {
+ die "Bochs died: code $exit\n";
+ }
+}
+
+# print_bochs_disk_line($device, $iface)
+#
+# If IDE interface $iface has a disk attached, prints a bochsrc.txt
+# line for attaching it to $device.
+sub print_bochs_disk_line {
+ my ($device, $iface) = @_;
+ my ($disk) = $disks_by_iface[$iface];
+ my ($file) = $disk->{FILE_NAME};
+ if (defined $file) {
+ my (%geom) = disk_geometry ($disk);
+ print BOCHSRC "$device: type=disk, path=$file, mode=flat, ";
+ print BOCHSRC "cylinders=$geom{C}, heads=$geom{H}, spt=$geom{S}, ";
+ print BOCHSRC "translation=none\n";
+ }
+}
+
+# Runs qemu.
+sub run_qemu {
+ print "warning: qemu doesn't support --terminal\n"
+ if $vga eq 'terminal';
+ print "warning: qemu doesn't support jitter\n"
+ if defined $jitter;
+ my (@cmd) = ('qemu');
+ for my $iface (0...3) {
+ my ($option) = ('-hda', '-hdb', '-hdc', '-hdd')[$iface];
+ push (@cmd, $option, $disks_by_iface[$iface]{FILE_NAME})
+ if defined $disks_by_iface[$iface]{FILE_NAME};
+ }
+ push (@cmd, '-m', $mem);
+ push (@cmd, '-nographic') if $vga eq 'none';
+ push (@cmd, '-serial', 'stdio') if $serial_out && $vga ne 'none';
+ push (@cmd, '-S') if $debug eq 'monitor';
+ push (@cmd, '-s', '-S') if $debug eq 'gdb';
+ push (@cmd, '-monitor', 'null') if $vga eq 'none' && $debug eq 'none';
+ run_command (@cmd);
+}