X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=blobdiff_plain;f=src%2Futils%2Fpintos-mkdisk;h=87b1563e69c517070e81ad32c36adfabdf6df2a5;hp=662b2e57d7eebccdac6ab1173702a8148a25af2a;hb=a03618133f7df0954802a470a4bee7674f7aed45;hpb=615bf3b3d2a8573ed6fb9ddc0055745e163ac999 diff --git a/src/utils/pintos-mkdisk b/src/utils/pintos-mkdisk index 662b2e5..87b1563 100755 --- a/src/utils/pintos-mkdisk +++ b/src/utils/pintos-mkdisk @@ -3,35 +3,132 @@ use strict; use warnings; use POSIX; -use Getopt::Long; +use Getopt::Long qw(:config bundling); use Fcntl 'SEEK_SET'; -GetOptions ("h|help" => sub { usage (0); }) +# Read Pintos.pm from the same directory as this program. +BEGIN { my $self = $0; $self =~ s%/+[^/]*$%%; require "$self/Pintos.pm"; } + +our ($disk_fn); # Output disk file name. +our (%parts); # Partitions. +our ($format); # "partitioned" (default) or "raw" +our (%geometry); # IDE disk geometry. +our ($align); # Align partitions on cylinders? +our ($loader_fn); # File name of loader. +our ($include_loader); # Include loader? +our (@kernel_args); # Kernel arguments. + +if (grep ($_ eq '--', @ARGV)) { + @kernel_args = @ARGV; + @ARGV = (); + while ((my $arg = shift (@kernel_args)) ne '--') { + push (@ARGV, $arg); + } +} + +GetOptions ("h|help" => sub { usage (0); }, + + "kernel=s" => \&set_part, + "filesys=s" => \&set_part, + "scratch=s" => \&set_part, + "swap=s" => \&set_part, + + "filesys-size=s" => \&set_part, + "scratch-size=s" => \&set_part, + "swap-size=s" => \&set_part, + + "kernel-from=s" => \&set_part, + "filesys-from=s" => \&set_part, + "scratch-from=s" => \&set_part, + "swap-from=s" => \&set_part, + + "format=s" => \$format, + "loader:s" => \&set_loader, + "no-loader" => \&set_no_loader, + "geometry=s" => \&set_geometry, + "align=s" => \&set_align) or exit 1; -usage (1) if @ARGV != 2; +usage (1) if @ARGV != 1; + +$disk_fn = $ARGV[0]; +die "$disk_fn: already exists\n" if -e $disk_fn; + +# Sets the loader to copy to the MBR. +sub set_loader { + die "can't specify both --loader and --no-loader\n" + if defined ($include_loader) && !$include_loader; + $include_loader = 1; + $loader_fn = $_[1] if $_[1] ne ''; +} + +# Disables copying a loader to the MBR. +sub set_no_loader { + die "can't specify both --loader and --no-loader\n" + if defined ($include_loader) && $include_loader; + $include_loader = 0; +} + +# Figure out whether to include a loader. +$include_loader = exists ($parts{KERNEL}) && $format eq 'partitioned' + if !defined ($include_loader); +die "can't write loader to raw disk\n" if $include_loader && $format eq 'raw'; +die "can't write command-line arguments without --loader or --kernel\n" + if @kernel_args && !$include_loader; +print STDERR "warning: --loader only makes sense without --kernel " + . "if this disk will be used to load a kernel from another disk\n" + if $include_loader && !exists ($parts{KERNEL}); + +# Open disk. +my ($disk_handle); +open ($disk_handle, '>', $disk_fn) or die "$disk_fn: create: $!\n"; -my ($disk, $mb) = @ARGV; -die "$disk: already exists\n" if -e $disk; -die "\"$mb\" is not a valid size in megabytes\n" - if $mb <= 0 || $mb > 1024 || $mb !~ /^\d+(\.\d+)?|\.\d+/; +# Read loader. +my ($loader); +$loader = read_loader ($loader_fn) if $include_loader; -my ($cyl_cnt) = ceil ($mb * 2); -my ($cyl_bytes) = 512 * 16 * 63; -my ($bytes) = $cyl_bytes * $cyl_cnt; +# Write disk. +my (%disk) = %parts; +$disk{DISK} = $disk_fn; +$disk{HANDLE} = $disk_handle; +$disk{ALIGN} = $align; +$disk{GEOMETRY} = %geometry; +$disk{FORMAT} = $format; +$disk{LOADER} = $loader; +$disk{ARGS} = \@kernel_args; +assemble_disk (%disk); -open (DISK, '>', $disk) or die "$disk: create: $!\n"; -sysseek (DISK, $bytes - 1, SEEK_SET) or die "$disk: seek: $!\n"; -syswrite (DISK, "\0", 1) == 1 or die "$disk: write: $!\n"; -close (DISK) or die "$disk: close: $!\n"; +# Done. +exit 0; sub usage { print <<'EOF'; pintos-mkdisk, a utility for creating Pintos virtual disks -Usage: pintos DISKFILE MB -where DISKFILE is the file to use for the disk - and MB is the disk size in (approximate) megabytes. -Options: - -h, --help Display this help message. +Usage: pintos-mkdisk [OPTIONS] DISK [-- ARGUMENT...] +where DISK is the virtual disk to create, + each ARGUMENT is inserted into the command line written to DISK, + and each OPTION is one of the following options. +Partition options: (where PARTITION is one of: kernel filesys scratch swap) + --PARTITION=FILE Use a copy of FILE for the given PARTITION + --PARTITION-size=SIZE Create an empty PARTITION of the given SIZE in MB + --PARTITION-from=DISK Use of a copy of the given PARTITION in DISK + (There is no --kernel-size option.) +Output disk options: + --format=partitioned Write partition table to output (default) + --format=raw Do not write partition table to output + (Pintos can only use partitioned disks.) +Partitioned format output options: + --loader[=FILE] Get bootstrap loader from FILE (default: loader.bin + if --kernel option is specified, empty otherwise) + --no-loader Do not include a bootstrap loader + --geometry=H,S Use H head, S sector geometry (default: 16, 63) + --geometry=zip Use 64 head, 32 sector geometry for USB-ZIP boot + per http://syslinux.zytor.com/usbkey.php + --align=bochs Round size to cylinder for Bochs support (default) + --align=full Align partition boundaries to cylinder boundary to + let fdisk guess correct geometry and quiet warnings + --align=none Don't align partitions at all, to save space +Other options: + -h, --help Display this help message. EOF - exit (@_); + exit ($_[0]); }