}
else {
- # Slurp up the data, based on whether a header is present or not
+ # Slurp up the data, based on whether a header and/or data is present or not
if ($_->{'header'}) {
# Read the length, and grab the data based on the length.
$_->{'data'} = substr($firmware_buf, $_->{'offset'} + $_->{'header'}, $data_len);
}
}
+ elsif ($_->{'pseudo'} and not defined $_->{'file'} and
+ (substr($firmware_buf, $_->{'offset'}, $_->{'size'}) eq
+ (pack("C", 0xff) x $_->{'size'}))) {
+ $debug and printf("Skipping empty pseudo partition <%s>\n", $_->{'name'});
+ }
else {
# Grab the whole partition, using the maximum size.
sub layoutPartitions {
my(@partitions) = @_;
+ # Find the kernel partition, and save a pointer to it for later use
+ my $kernel;
+ map { ($_->{'name'} eq "Kernel") && ($kernel = $_); } @partitions;
+ $kernel or die "Couldn't find the kernel partition\n";
+
# Find the last variable size partition, and save a pointer to it for later use
my $lastdisk;
my $directory_offset;
$debug and printf("Pointer is 0x%08X\n", $pointer);
- # If this is the last variable size partition, then fill the rest of the space.
- if ($_->{'name'} eq $lastdisk->{'name'}) {
- $_->{'size'} = paddedSize($directory_offset + $flash_start - $pointer);
- $debug and printf("Padding last variable partition <%s> to 0x%08X bytes\n", $_->{'name'}, $_->{'size'});
- }
-
- # Handle requests for partition creation first.
- if (defined $_->{'size'} and not defined $_->{'data'} and ($_->{'name'} ne "FIS directory")) {
-
- # A zero size is a request to fill all available space.
- if ($_->{'size'} == 0) {
- # Grab the start of the FIS directory, and use all the space up to there.
- $_->{'size'} = paddedSize($directory_offset + $flash_start - $pointer);
-
- # Create an empty partition of the requested size.
- $_->{'data'} = padBytes("", $_->{'size'});
-
- $debug and printf("Creating empty partition <%s> of 0x%08X bytes\n", $_->{'name'}, $_->{'size'});
- }
-
- if (not defined $_->{'offset'}) {
- # Check to make sure that the requested size is not too large.
- if (($pointer + $_->{'size'}) > ($flash_start + $directory_offset)) {
- die "Ran out of flash space in <", $_->{'name'}, ">\n";
- }
- }
- else {
- # Check to make sure that the requested size is not too large.
- if (($_->{'offset'} + $_->{'size'}) > ($flash_start + $directory_offset)) {
- die "Ran out of flash space in <", $_->{'name'}, ">\n";
- }
+ # Determine the start and offset of the current partition.
+ if (defined $_->{'offset'}) {
+ $_->{'start'} = $flash_start + $_->{'offset'};
+ # Check for running past the defined start of the partition.
+ if (($pointer > $_->{'start'}) and not $_->{'pseudo'}) {
+ die sprintf("Ran out of flash space before <%s> - %s too large.\n", $_->{'name'},
+ sprintf("0x%05X bytes", ($pointer - $_->{'start'})));
}
}
- # Then handle known partitions, and allocate them.
- if (defined $_->{'size'}) {
-
- # Determine the start and offset of the current partition.
- if (defined $_->{'offset'}) {
- $_->{'start'} = $flash_start + $_->{'offset'};
- }
+ # If offset is not defined, then calculate it.
+ else {
+ $_->{'start'} = $pointer;
+ $_->{'offset'} = $_->{'start'} - $flash_start;
+ }
- # If offset is not defined, then calculate it.
- else {
- $_->{'start'} = $pointer;
- $_->{'offset'} = $_->{'start'} - $flash_start;
- }
+ my $size = defined $_->{'data'} ? length($_->{'data'}) : 0;
- my $size = defined $_->{'data'} ? length($_->{'data'}) : 0;
+ # Add skip regions for the partitions with headers.
+ if ($_->{'header'} > 0) {
+ # Define the skip region for the initial Sercomm header.
+ push(@{$_->{'skips'}},
+ { 'offset' => 0, 'size' => $_->{'header'}, 'data' => undef });
+ # Allow for the Sercomm header to be prepended to the data.
+ $size += $_->{'header'};
- # Add skip regions for the partitions with headers.
- if ($_->{'header'} > 0) {
- # Define the skip region for the initial Sercomm header.
- push(@{$_->{'skips'}},
- { 'offset' => 0, 'size' => $_->{'header'}, 'data' => undef });
- # Allow for the Sercomm header to be prepended to the data.
- $size += $_->{'header'};
- }
-
- # Determine if the partition requires a Sercomm skip region.
+ # Determine if the partition overlaps the ramdisk boundary.
if (($_->{'offset'} < $ramdisk_offset) and
(($_->{'offset'} + $size) > $ramdisk_offset)) {
# Define the skip region for the inline Sercomm header.
# Allow for the Sercomm header to be inserted in the data.
$size += 16;
}
+ }
- # Extend to another block if required.
- if ($size > $_->{'size'}) {
- $_->{'size'} = $size;
- printf("Extending partition <%s> to 0x%08X bytes\n", $_->{'name'}, $_->{'size'});
- }
+ # Partitions without headers cannot have skip regions.
+ elsif (($_->{'offset'} <= $ramdisk_offset) and
+ (($_->{'offset'} + $size) > $ramdisk_offset)) {
+ # Pad the kernel until it extends past the ramdisk offset.
+ push(@{$kernel->{'skips'}},
+ { 'offset' => ($ramdisk_offset - $kernel->{'offset'}), 'size' => 16,
+ 'data' => pack("N4", $block_size) });
+ $kernel->{'size'} = $ramdisk_offset - $kernel->{'offset'} + $block_size;
+ $kernel->{'data'} = padBytes($kernel->{'data'},
+ $kernel->{'size'} - $kernel->{'header'} - 16);
+ $_->{'offset'} = $ramdisk_offset + $block_size;
+ $_->{'start'} = $flash_start + $_->{'offset'};
+ $pointer = $_->{'start'};
+ $debug and printf("Extending kernel partition past ramdisk offset.\n");
+ }
- # Keep the user appraised ...
- $debug and printf("Allocated <%s> from 0x%08X to 0x%08X (%s / %s)\n",
- $_->{'name'}, $_->{'start'}, $_->{'start'} + $_->{'size'},
- ($size >= $block_size ?
- sprintf("%d blocks", numBlocks($size)) :
- sprintf("0x%05X bytes", $size)),
- ($_->{'size'} >= $block_size ?
- sprintf("%d blocks", numBlocks($_->{'size'})) :
- sprintf("0x%05X bytes", $_->{'size'})));
+ # If this is the last variable size partition, then fill the rest of the space.
+ if ($_->{'name'} eq $lastdisk->{'name'}) {
+ $_->{'size'} = paddedSize($directory_offset + $flash_start - $pointer);
+ $debug and printf("Padding last variable partition <%s> to 0x%08X bytes\n", $_->{'name'}, $_->{'size'});
+ }
+
+ die sprintf("Partition size not defined in <%s>.\n", $_->{'name'})
+ unless defined $_->{'size'};
- # Check to make sure we have not run out of room.
- if (($_->{'start'} + $_->{'size'}) > ($flash_start + $flash_len)) {
- die "Ran out of flash space in <", $_->{'name'}, ">\n";
+ # Extend to another block if required.
+ if ($size > $_->{'size'}) {
+ if ($_->{'name'} eq $lastdisk->{'name'}) {
+ die sprintf("Ran out of flash space in <%s> - %s too large.\n", $_->{'name'},
+ sprintf("0x%05X bytes", ($size - $_->{'size'})));
}
+ $_->{'size'} = $size;
+ printf("Extending partition <%s> to 0x%08X bytes\n", $_->{'name'}, $_->{'size'});
+ }
- $debug and printf("Moving pointer from 0x%08X to 0x%08X (0x%08X + 0x%08X)\n",
- $pointer, paddedSize($_->{'start'} + $_->{'size'}),
- $_->{'start'}, $_->{'size'});
+ # Keep the user appraised ...
+ $debug and printf("Allocated <%s> from 0x%08X to 0x%08X (%s / %s)\n",
+ $_->{'name'}, $_->{'start'}, $_->{'start'} + $_->{'size'},
+ ($size >= $block_size ?
+ sprintf("%d blocks", numBlocks($size)) :
+ sprintf("0x%05X bytes", $size)),
+ ($_->{'size'} >= $block_size ?
+ sprintf("%d blocks", numBlocks($_->{'size'})) :
+ sprintf("0x%05X bytes", $_->{'size'})));
+
+ # Check to make sure we have not run out of room.
+ if (($_->{'start'} + $_->{'size'}) > ($flash_start + $flash_len)) {
+ die "Ran out of flash space in <", $_->{'name'}, ">\n";
+ }
- # Move the pointer up, in preparation for the next partition.
- $pointer = paddedSize($_->{'start'} + $_->{'size'});
+ $debug and printf("Moving pointer from 0x%08X to 0x%08X (0x%08X + 0x%08X)\n",
+ $pointer, paddedSize($_->{'start'} + $_->{'size'}),
+ $_->{'start'}, $_->{'size'});
- }
+ # Move the pointer up, in preparation for the next partition.
+ $pointer = paddedSize($_->{'start'} + $_->{'size'});
} @partitions;
'offset'=>0x007f8000, 'size'=>0x00004000,
'variable'=>0, 'header'=>0, 'pseudo'=>1, 'data'=>undef, 'byteswap'=>0},
{'name'=>'Microcode', 'file'=>'NPE-B',
- 'offset'=>0x007fc000, 'size'=>0x00003ff0,
+ 'offset'=>0x007fc000, 'size'=>0x00003000,
'variable'=>0, 'header'=>16, 'pseudo'=>1, 'data'=>undef, 'byteswap'=>0},
{'name'=>'Trailer', 'file'=>'Trailer',
'offset'=>0x007ffff0, 'size'=>0x00000010,
if (defined $size) {
$entry{'size'} = $size * $block_size;
# Create an empty partition of the requested size.
- $entry{'data'} = padBytes("", $entry{'size'});
- if ($entry{'header'}) {
- $entry{'data'} = padBytes("", $entry{'size'} - $entry{'header'});
- }
+ $entry{'data'} = padBytes("", $entry{'size'} - $entry{'header'});
}
\%entry;