-our ($mem) = 4;
-our ($serial_out) = 1;
-our (@disks) = ("os.dsk", "fs.dsk", "scratch.dsk", "swap.dsk");
-our ($sim);
-our ($debug);
-our ($vga);
-our ($jitter, $realtime);
-
-use Getopt::Long qw(:config require_order bundling);
-GetOptions ("sim=s" => sub { set_sim (@_) },
- "bochs" => sub { set_sim ("bochs") },
- "qemu" => sub { set_sim ("qemu") },
- "gsx" => sub { set_sim ("gsx") },
-
- "debug=s" => sub { set_debug (@_) },
- "no-debug" => sub { set_debug ("no-debug") },
- "monitor" => sub { set_debug ("monitor") },
- "gdb" => sub { set_debug ("gdb") },
-
- "run|get|put|make-disk" => \&cmd_option,
-
- "m|memory=i" => \$mem,
- "j|jitter=i" => sub { set_jitter (@_) },
- "r|realtime" => sub { set_realtime () },
-
- "v|no-vga" => sub { set_vga ('none'); },
- "s|no-serial" => sub { $serial_out = 0; },
- "t|terminal" => sub { set_vga ('terminal'); },
-
- "h|help" => sub { usage (0); },
-
- "0|os-disk|disk-0|hda=s" => \$disks[0],
- "1|fs-disk|disk-1|hdb=s" => \$disks[1],
- "2|scratch-disk|disk-2|hdc=s" => \$disks[2],
- "3|swap-disk|disk-3|hdd=s" => \$disks[3])
- or exit 1;
-
-$sim = "bochs" if !defined $sim;
-$debug = "no-debug" if !defined $debug;
-$vga = "window" if !defined $vga;
+exit 0;
+\f
+# Parses the command line.
+sub parse_command_line {
+ usage (0) if @ARGV == 0 || (@ARGV == 1 && $ARGV[0] eq '--help');
+
+ @kernel_args = @ARGV;
+ if (grep ($_ eq '--', @kernel_args)) {
+ @ARGV = ();
+ while ((my $arg = shift (@kernel_args)) ne '--') {
+ push (@ARGV, $arg);
+ }
+ GetOptions ("sim=s" => sub { set_sim (@_) },
+ "bochs" => sub { set_sim ("bochs") },
+ "qemu" => sub { set_sim ("qemu") },
+ "gsx" => sub { set_sim ("gsx") },
+
+ "debug=s" => sub { set_debug (@_) },
+ "no-debug" => sub { set_debug ("none") },
+ "monitor" => sub { set_debug ("monitor") },
+ "gdb" => sub { set_debug ("gdb") },
+
+ "m|memory=i" => \$mem,
+ "j|jitter=i" => sub { set_jitter (@_) },
+ "r|realtime" => sub { set_realtime () },
+ "T|timeout=i" => \$timeout,
+
+ "v|no-vga" => sub { set_vga ('none'); },
+ "s|no-serial" => sub { $serial_out = 0; },
+ "t|terminal" => sub { set_vga ('terminal'); },
+
+ "p|put-file=s" => sub { add_file (\@puts, $_[1]); },
+ "g|get-file=s" => sub { add_file (\@gets, $_[1]); },
+ "a|as=s" => sub { set_as ($_[1]); },
+
+ "h|help" => sub { usage (0); },
+
+ "os-disk=s" => \$disks{OS}{FILE_NAME},
+ "fs-disk=s" => \$disks{FS}{FILE_NAME},
+ "scratch-disk=s" => \$disks{SCRATCH}{FILE_NAME},
+ "swap-disk=s" => \$disks{SWAP}{FILE_NAME},
+
+ "0|disk-0|hda=s" => \$disks_by_iface[0]{FILE_NAME},
+ "1|disk-1|hdb=s" => \$disks_by_iface[1]{FILE_NAME},
+ "2|disk-2|hdc=s" => \$disks_by_iface[2]{FILE_NAME},
+ "3|disk-3|hdd=s" => \$disks_by_iface[3]{FILE_NAME})
+ or exit 1;
+ }
+
+ $sim = "bochs" if !defined $sim;
+ $debug = "none" if !defined $debug;
+ $vga = "window" if !defined $vga;
+
+ print "warning: -T or --timeout should not be used with --$debug\n"
+ if defined ($timeout) && $debug ne 'none';
+}
+
+# usage($exitcode).
+# Prints a usage message and exits with $exitcode.
+sub usage {
+ my ($exitcode) = @_;
+ $exitcode = 1 unless defined $exitcode;
+ print <<'EOF';
+pintos, a utility for running Pintos in a simulator
+Usage: pintos [OPTION...] -- [ARGUMENT...]
+where each OPTION is one of the following options
+ and each ARGUMENT is passed to Pintos kernel verbatim.
+Simulator selection:
+ --bochs (default) Use Bochs as simulator
+ --qemu Use qemu as simulator
+ --gsx Use VMware GSX Server 3.x as simulator
+Debugger selection:
+ --no-debug (default) No debugger
+ --monitor Debug with simulator's monitor
+ --gdb Debug with gdb
+Display options: (default is both VGA and serial)
+ -v, --no-vga No VGA display
+ -s, --no-serial No serial output
+ -t, --terminal Display VGA in terminal (Bochs only)
+Timing options: (Bochs only)
+ -j SEED Randomize timer interrupts
+ -r, --realtime Use realistic, not reproducible, timings
+ -T, --timeout=N Kill Pintos after N seconds CPU time or N*load_avg
+ seconds wall-clock time (whichever comes first)
+Configuration options:
+ -m, --mem=N Give Pintos N MB physical RAM (default: 4)
+File system commands (for `run' command):
+ -p, --put-file=HOSTFN Copy HOSTFN into VM, by default under same name
+ -g, --get-file=GUESTFN Copy GUESTFN out of VM, by default under same name
+ -a, --as=FILENAME Specifies guest (for -p) or host (for -g) file name
+Disk options: (name an existing FILE or specify SIZE in MB for a temp disk)
+ --os-disk=FILE Set OS disk file (default: os.dsk)
+ --fs-disk=FILE|SIZE Set FS disk file (default: fs.dsk)
+ --scratch-disk=FILE|SIZE Set scratch disk (default: scratch.dsk)
+ --swap-disk=FILE|SIZE Set swap disk file (default: swap.dsk)
+Other options:
+ -h, --help Display this help message.
+EOF
+ exit $exitcode;
+}