diff options
Diffstat (limited to 'perl-install/partition_table_mac.pm')
-rw-r--r-- | perl-install/partition_table_mac.pm | 378 |
1 files changed, 0 insertions, 378 deletions
diff --git a/perl-install/partition_table_mac.pm b/perl-install/partition_table_mac.pm deleted file mode 100644 index d1f65a6db..000000000 --- a/perl-install/partition_table_mac.pm +++ /dev/null @@ -1,378 +0,0 @@ -package partition_table_mac; # $Id$ - -use diagnostics; -#use strict; - fixed other PPC code to comply, but program bails on empty partition table - sbenedict -use vars qw(@ISA $freepart_device $bootstrap_part $freepart_start $freepart_size $freepart_part $macos_part); - -@ISA = qw(partition_table_raw); - -use common; -use partition_table_raw; -use partition_table; -use c; - -my %typeToDos = ( - "Apple_partition_map" => 0x401, - "Apple_Bootstrap" => 0x401, - "Apple_Driver43" => 0x401, - "Apple_Driver_IOKit" => 0x401, - "Apple_Patches" => 0x401, - "Apple_HFS" => 0x402, - "Apple_UNIX_SVR2" => 0x83, - "Apple_Free" => 0x0, -); -my %typeFromDos = reverse %typeToDos; - - -my ($bz_format, $bz_fields) = list2kv( - n => 'bzSig', - n => 'bzBlkSize', - N => 'bzBlkCnt', - n => 'bzDevType', - n => 'bzDevID', - N => 'bzReserved', - n => 'bzDrvrCnt', -); -$bz_format = join '', @$bz_format; - - -my ($dd_format, $dd_fields) = list2kv( - N => 'ddBlock', - n => 'ddSize', - n => 'ddType', -); -$dd_format = join '', @$dd_format; - - -my ($p_format, $p_fields) = list2kv( - n => 'pSig', - n => 'pSigPad', - N => 'pMapEntry', - N => 'pPBlockStart', - N => 'pPBlocks', - - a32 => 'pName', - a32 => 'pType', - - N => 'pLBlockStart', - N => 'pLBlocks', - N => 'pFlags', - N => 'pBootBlock', - N => 'pBootBytes', - - N => 'pAddrs1', - N => 'pAddrs2', - N => 'pAddrs3', - N => 'pAddrs4', - N => 'pChecksum', - - a16 => 'pProcID', - a128 => 'pBootArgs', - a248 => 'pReserved', -); -$p_format = join '', @$p_format; - -my $magic = 0x4552; -my $pmagic = 0x504D; - -sub first_usable_sector { 1 } - -sub adjustStart($$) { - my ($hd, $part) = @_; - my $end = $part->{start} + $part->{size}; - my $partmap_end = $hd->{primary}{raw}[0]{size}; - - if ($part->{start} <= $partmap_end) { - $part->{start} = $partmap_end + 1; - $part->{size} = $end - $part->{start}; - } -} - -sub adjustEnd($$) { - my ($hd, $part) = @_; -} - -sub read($$) { - my ($hd, $sector) = @_; - my $tmp; - - local *F; partition_table_raw::openit($hd, *F) or die "failed to open device"; - c::lseek_sector(fileno(F), $sector, 0) or die "reading of partition in sector $sector failed"; - - sysread F, $tmp, psizeof($bz_format) or die "error while reading bz \(Block Zero\) in sector $sector"; - my %info; @info{@$bz_fields} = unpack $bz_format, $tmp; - my $i; - - foreach $i (0 .. $info{bzDrvrCnt}-1) { - sysread F, $tmp, psizeof($dd_format) or die "error while reading driver data in sector $sector"; - my %dd; @dd{@$dd_fields} = unpack $dd_format, $tmp; - push @{$info{ddMap}}, \%dd; - } - - #- check magic number - $info{bzSig} == $magic or die "bad magic number"; - - my $numparts; - c::lseek_sector(fileno(F), $sector, 516) or die "reading of partition in sector $sector failed"; - sysread F, $tmp, 4 or die "error while reading partition info in sector $sector"; - $numparts = unpack "N", $tmp; - - my $partmapsize; - c::lseek_sector(fileno(F), $sector, 524) or die "reading of partition in sector $sector failed"; - sysread F, $tmp, 4 or die "error while reading partition info in sector $sector"; - $partmapsize = ((unpack "N", $tmp) * $info{bzBlkSize}) / psizeof($p_format); - - c::lseek_sector(fileno(F), $sector, 512) or die "reading of partition in sector $sector failed"; - - my @pt; - for ($i=0;$i<$partmapsize;$i++) { - my $part; - sysread F, $part, psizeof($p_format) or die "error while reading partition info in sector $sector"; - - push @pt, map { - my %h; @h{@$p_fields} = unpack $p_format, $part; - if ($i < $numparts && $h{pSig} eq $pmagic) { - - $h{size} = ($h{pPBlocks} * $info{bzBlkSize}) / 512; - $h{start} = ($h{pPBlockStart} * $info{bzBlkSize}) / 512; - - if ($h{pType} =~ /^Apple_UNIX_SVR2/i) { - $h{pName} =~ /swap/i ? ($h{type} = 0x82) : ($h{type} = 0x83); - } elsif ($h{pType} =~ /^Apple_Free/i) { - #- need to locate a 1MB partition to setup a bootstrap on - if (defined $freepart_start && $freepart_size >= 1) { - #- already found a suitable partition - } else { - $freepart_start = $h{start}; - $freepart_size = $h{size}/2048; - $freepart_device = $hd; - $freepart_part = "/dev/" . $hd->{device} . ($i+1); - log::l("free apple partition found on drive /dev/$freepart_device->{device}, block $freepart_start, size $freepart_size"); - } - $h{type} = 0x0; - $h{pName} = 'Extra'; - } elsif ($h{pType} =~ /^Apple_HFS/i) { - $h{type} = 0x402; - if (defined $macos_part) { - #- swag at identifying MacOS - 1st HFS partition - } else { - $macos_part = "/dev/" . $hd->{device} . ($i+1); - log::l("found MacOS at partition $macos_part"); - } - } elsif ($h{pType} =~ /^Apple_Partition_Map/i) { - $h{type} = 0x401; - $h{isMap} = 1; - } elsif ($h{pType} =~ /^Apple_Bootstrap/i) { - $h{type} = 0x401; - $h{isBoot} = 1; - if (defined $bootstrap_part) { - #found a bootstrap already - use it, but log the find - log::l("found another apple bootstrap at partition /dev/$hd->{device}" . ($i+1)); - } else { - $bootstrap_part = "/dev/" . $hd->{device} . ($i+1); - log::l("found apple bootstrap at partition $bootstrap_part"); - } - } else { - $h{type} = 0x401; - $h{isDriver} = 1; - }; - - # Let's see if this partition is a driver. - foreach (@{$info{ddMap}}) { - $_->{ddBlock} == $h{pPBlockStart} and $h{isDriver} = 1; - } - - } - \%h; - } [ $part ]; - }; - - [ @pt ], \%info; -} - -sub write($$$;$) { - my ($hd, $sector, $pt, $info) = @_; - - #- handle testing for writing partition table on file only! - local *F; - if ($::testing) { - my $file = "/tmp/partition_table_$hd->{device}"; - open F, ">$file" or die "error opening test file $file"; - } else { - partition_table_raw::openit($hd, *F, 2) or die "error opening device $hd->{device} for writing"; - c::lseek_sector(fileno(F), $sector, 0) or return 0; - } - - # Find the partition map. - my @partstowrite; - my $part = $pt->[0]; - (defined $part->{isMap}) or die "the first partition is not the partition map"; - push @partstowrite, $part; - - # Now go thru the partitions, sort and fill gaps. - my $last; - while ($part) { - $last = $part; - $part = &partition_table::next($hd, $part); - $part or last; - - if ($last->{start} + $last->{size} < $part->{start}) { - #There is a gap between partitions. Fill it and move on. - push @partstowrite, { - type => 0x0, - start => $last->{start} + $last->{size}, - size => $part->{start} - ($last->{start} + $last->{size}), - }; - } - push @partstowrite, $part; - }; - - # now, fill a gap at the end if there is one. - if ($last->{start} + $last->{size} < $hd->{totalsectors}) { - push @partstowrite, { - type => 0x0, - start => $last->{start} + $last->{size}, - size => $hd->{totalsectors} - ($last->{start} + $last->{size}), - }; - } - - # Since we didn't create any new drivers, let's try and match up our driver records with out partitons and see if any are missing. - $info->{bzDrvrCnt} = 0; - my @ddstowrite; - my $dd; - foreach $dd (@{$info->{ddMap}}) { - foreach (@partstowrite) { - if ($dd->{ddBlock} == $_->{pPBlockStart}) { - push @ddstowrite, $dd; - $info->{bzDrvrCnt}++; - last; - } - } - } - - # Now let's write our first block. - syswrite F, pack($bz_format, @$info{@$bz_fields}), psizeof($bz_format) or return 0; - - # ...and now the driver information. - foreach (@ddstowrite) { - syswrite F, pack($dd_format, @$_{@$dd_fields}), psizeof($dd_format) or return 0; - } - # zero the rest of the data in the first block. - foreach ( 1 .. (494 - ((@ddstowrite) * 8))) { - syswrite F, "\0", 1 or return 0; - } - #c::lseek_sector(fileno(F), $sector, 512) or return 0; - # Now, we iterate thru the partstowrite and write them. - foreach (@partstowrite) { - if (!defined $_->{pSig}) { - # The values we need to write to disk are not defined. Let's make them up. - $_->{pSig} = $pmagic; - $_->{pSigPad} = 0; - $_->{pPBlockStart} = ($_->{start} * 512) / $info->{bzBlkSize}; - $_->{pPBlocks} = ($_->{size} * 512) / $info->{bzBlkSize}; - $_->{pLBlockStart} = 0; - $_->{pLBlocks} = $_->{pPBlocks}; - $_->{pBootBlock} = 0; - $_->{pBootBytes} = 0; - $_->{pAddrs1} = 0; - $_->{pAddrs2} = 0; - $_->{pAddrs3} = 0; - $_->{pAddrs4} = 0; - $_->{pChecksum} = 0; - $_->{pProcID} = "\0"; - $_->{pBootArgs} = "\0"; - $_->{pReserved} = "\0"; - - if ($_->{type} == 0x402) { - $_->{pType} = "Apple_HFS"; - $_->{pName} = "MacOS"; - $_->{pFlags} = 0x4000037F; - } elsif ($_->{type} == 0x401 && $_->{start} == 1) { - $_->{pType} = "Apple_Partition_Map"; - $_->{pName} = "Apple"; - $_->{pFlags} = 0x33; - } elsif ($_->{type} == 0x401) { - $_->{pType} = "Apple_Bootstrap"; - $_->{pName} = "bootstrap"; - $_->{pFlags} = 0x33; - $_->{isBoot} = 1; - log::l("writing a bootstrap at /dev/$_->{device}"); - $install_steps_interactive::new_bootstrap = 1 if !(defined $partition_table_mac::bootstrap_part); - $bootstrap_part = "/dev/" . $_->{device}; - } elsif ($_->{type} == 0x82) { - $_->{pType} = "Apple_UNIX_SVR2"; - $_->{pName} = "swap"; - $_->{pFlags} = 0x33; - } elsif ($_->{type} == 0x83) { - $_->{pType} = "Apple_UNIX_SVR2"; - $_->{pName} = "Linux Native"; - $_->{pFlags} = 0x33; - } elsif ($_->{type} == 0x0) { - $_->{pType} = "Apple_Free"; - $_->{pName} = "Extra"; - $_->{pFlags} = 0x31; - } - }; - $_->{pMapEntry} = @partstowrite; - syswrite F, pack($p_format, @$_{@$p_fields}), psizeof($p_format) or return 0; - } - - common::sync(); - - 1; -} - -sub info { - my ($hd) = @_; - - # - Build the first block of the drive. - - my $info = { - bzSig => $magic, - bzBlkSize => 512, - bzBlkCnt => $hd->{totalsectors}, - bzDevType => 0, - bzDevID => 0, - bzReserved => 0, - bzDrvrCnt => 0, - }; - - $info; -} - -sub clear_raw { - my ($hd) = @_; - my @oldraw = @{$hd->{primary}{raw}}; - my $pt = { raw => [ ({}) x 63 ], info => info($hd) }; - - #- handle special case for partition 1 which is the partition map. - $pt->{raw}[0] = { - type => 0x401, - start => 1, - size => 63, - isMap => 1, - }; -# $pt->{raw}[1] = { -# type => 0x0, -# start => 64, -# size => $hd->{totalsectors} - 64, -# isMap => 0, -# }; - push @{$pt->{normal}}, $pt->{raw}[0]; -# push @{$pt->{normal}}, $pt->{raw}[1]; - - #- Recover any Apple Drivers, if any. - my $i = 1; - foreach (@oldraw) { - if (defined $_->{isDriver}) { - $pt->{raw}[$i] = $_; - push @{$pt->{normal}}, $pt->{raw}[$i]; - $i++; - } - }; - @{$pt->{info}{ddMap}} = @{$hd->{primary}{info}{ddMap}}; - - $pt; -} - -1; |