5 my ($arg) = shift (@ARGV);
6 if ($arg eq '--bochs' || $arg eq '--bochs-dbg' || $arg eq '--bochs-gdb'
7 || $arg eq '--qemu' || $arg eq '--vmware') {
8 $sim = substr ($arg, 2);
9 } elsif ($arg eq 'run') {
12 } elsif ($arg eq 'make-disk') {
13 usage () if @ARGV != 2;
14 my ($file, $kb) = @ARGV;
15 usage () if $kb =~ /^\d+$/;
16 die "$file: already exists\n" if -e $file;
18 create_disk ($file, $kb);
20 } elsif ($arg eq 'put') {
21 usage () if @ARGV != 1 && @ARGV != 2;
22 my ($hostfn, $guestfn) = @ARGV;
23 $guestfn = $hostfn if !defined $guestfn;
25 # Create scratch disk from file.
26 die "$hostfn: $!\n" if ! -e $hostfn;
28 copy_pad ($hostfn, "scratch.dsk", 512);
31 run_vm ("-ci", $hostfn, $size, "-q");
33 } elsif ($arg eq 'get') {
34 usage () if @ARGV != 1 && @ARGV != 2;
35 my ($guestfn, $hostfn) = @ARGV;
36 $hostfn = $guestfn if !defined $hostfn;
37 die "$hostfn: already exists\n" if -e $file;
39 # Create scratch disk big enough for any file in the filesystem
40 # (modulo sparse files).
41 die "fs.dsk: $!\n" if ! -e "fs.dsk";
43 my ($scratch_size) = -s "scratch.dsk";
44 $scratch_size = 0 if !defined $scratch_size;
45 create_disk ("scratch.dsk", $fs_size / 1024 + 16)
46 if $scratch_size < $fs_size + 16384;
49 run_vm ("-co", $guestfn, $hostfn, "-q");
51 # Read out scratch disk.
52 open (SRC, "<scratch.dsk") or die "scratch.dsk: open: $!\n";
53 open (DST, ">$hostfn") or die "$hostfn: create: $!\n";
55 read (SRC, $input, 512) == 512 or die "scratch.dsk: read error\n";
56 my ($size) = unpack ("%V", $input);
57 $size != 0xffffffff or die "$guestfn: too big for scratch.dsk?";
58 read (SRC, $src, $size) == $src or die "scratch.dsk: read error\n";
59 print DST $src or die "$hostfn: write error\n";
70 $exitcode = 1 unless defined $exitcode;
71 print "pintos, a utility for invoking Pintos in a simulator\n";
72 print "Usage: pintos [OPTION...] COMMAND [ARG...]\n";
73 print "where COMMAND is one of the following:\n";
74 print " run [CMDLINE...] run a VM in the simulator\n";
75 print " make-disk FILE.DSK KB create FILE.DSK as empty KB-kB disk\n";
76 print " put HOSTFN [GUESTFN] copy HOSTFN into VM (as GUESTFN)\n";
77 print " get GUESTFN [HOSTFN] copy GUESTFN out of VM (to HOSTFN)\n";
78 print " help print this help message and exit\n";
79 print "Available options:\n";
80 print " --bochs Use Bochs as simulator (default)\n";
81 print " --bochs-dbg Use Bochs with debugger as simulator\n";
82 print " --bochs-gdb Use Bochs with gdb as simulator\n";
83 print " --qemu Use qemu as simulator\n";
84 print " --vmware Use VMware Workstation as simulator\n";
89 my ($src, $dst, $blocksize) = @_;
90 open (SRC, "<$src") or die "$src: open: $!\n";
91 open (DST, ">$dst") or die "$dst: create: $!\n";
94 while (read (SRC, $input, 4096)) {
95 $size += length ($input);
98 my ($rem) = $size % $blocksize;
99 print DST "\0" x ($blocksize - $rem) if $rem != 0;
105 my ($disk, $kb) = @_;
106 open (DISK, ">$disk") or die "$disk: create: $!\n";
107 for (my ($i) = 0; $i < $kb; $i++) {
108 print DISK "\0" x 1024;
114 my (@disks) = (undef, undef, undef, undef);
116 $disks[0] = "os.dsk";
117 $disks[1] = "fs.dsk" if -e "fs.dsk";
118 $disks[2] = "scratch.dsk" if -e "scratch.dsk";
119 $disks[3] = "swap.dsk" if -e "swap.dsk";
121 die "$disks[0]: can't find OS disk\n" if ! -e $disks[0];
122 write_cmd_line ($disks[0], @_);
124 if ($sim eq 'qemu') {
125 my (@cmd) = ('qemu');
126 push (@cmd, '-hda', $disks[0]) if defined $disks[0];
127 push (@cmd, '-hdb', $disks[1]) if defined $disks[1];
128 push (@cmd, '-hdc', $disks[2]) if defined $disks[2];
129 push (@cmd, '-hdd', $disks[3]) if defined $disks[3];
135 my ($disk, @args) = @_;
137 die "command line includes empty string" if grep (/^$/, @args);
138 $args = join ("\0", @args) . "\0\0";
139 die "command line exceeds 128 bytes" if length ($args) > 128;
140 $args .= "\0" x (128 - length ($args));
142 open (DISK, "+<$disk") or die "$disk: open: $!\n";
143 seek (DISK, 0x17e, 0) or die "$disk: seek: $!\n";
144 syswrite (DISK, $args) or die "$disk: write: $!\n";
145 close (DISK) or die "$disk: close: $!\n";