summaryrefslogtreecommitdiff
path: root/bootwrapper/makemap
diff options
context:
space:
mode:
Diffstat (limited to 'bootwrapper/makemap')
-rwxr-xr-xbootwrapper/makemap174
1 files changed, 174 insertions, 0 deletions
diff --git a/bootwrapper/makemap b/bootwrapper/makemap
new file mode 100755
index 0000000..47213c9
--- /dev/null
+++ b/bootwrapper/makemap
@@ -0,0 +1,174 @@
+#! /bin/env perl
+#
+# Copyright (c) 2011, ARM Limited. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with
+# or without modification, are permitted provided that the
+# following conditions are met:
+#
+# Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+#
+# Redistributions in binary form must reproduce the
+# above copyright notice, this list of conditions and
+# the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its
+# contributors may be used to endorse or promote products
+# derived from this software without specific prior written
+# permission.
+#
+
+use strict;
+
+use vars qw(
+ $image
+ $source
+ $obj
+ $map
+ $kernaddr
+ $sh
+ $mh
+ %chunksdone
+ @chunks
+);
+
+sub addchunk($$)
+{
+ my $file = shift;
+ my $addr = shift;
+ my $size = -s $file;
+ my $name = $file;
+ $name =~ s|^.*/([^/]+)$|$1|;
+
+ # Multiple contiguous sections are saved as one chunk, so in that case only process the first
+ if (!defined $chunksdone{$name})
+ {
+ print $sh <<EOF;
+ AREA |$name|, CODE, ALIGN=2
+ INCBIN $file
+EOF
+
+ print $mh <<EOF;
+$name $addr $size
+{
+ ${name}DATA $addr $size
+ {
+ $obj ($name)
+ }
+}
+EOF
+
+ $chunksdone{$name} = 1;
+ push @chunks, [ $addr, $size ];
+ }
+}
+
+sub num($)
+{
+ my $n = shift;
+ $n = oct $n if $n =~ /^0/;
+ return $n;
+}
+
+sub covered($)
+{
+ my $start = num(shift);
+
+ for (@chunks)
+ {
+# printf "Checking $start against chunk $_->[0] (%d), $_->[1] (%d), %d\n",num($_->[0]),num($_->[1]),num($_->[0])+num($_->[0]);
+ return 1 if $start >= num($_->[0]) && $start < num($_->[0])+num($_->[1]);
+ }
+ return 0;
+}
+
+($image=shift) && ($source = shift) or die "\
+Usage: $0 image source [ kernaddr ]
+ Creates source and map files to load the sections of \$image
+ \(if it is an ARM ELF file\), or the whole of \$image at \$kernaddr";
+
+$kernaddr=shift;
+$map="$source.map";
+$obj="$source.o";
+
+open $sh, ">$source.S" or die "Can't create '$source.S'";
+open $mh, ">$map" or die "Can't create '$map'";
+
+# Check if $image is an ELF file
+my $type=`file -L $image`;
+if ( $type =~ /ELF.*ARM/ )
+{
+# print "$image is an ELF file - splitting\n";
+ system("rm -rf $image.bin");
+ system("fromelf --bin $image -o $image.bin");
+ my $fromelfv=`fromelf --vsn`;
+ ($fromelfv=~/FromELF, (RVCT|)([\d\.]+)/) && ($2 >= 4.1) or die "fromelf version '$2' is too old - need 4.1 or greater";
+ my $desc = `fromelf --text $image`;
+ my $chunk;
+ my $chunkdone;
+ my %chunkdefined;
+ my $zichunk;
+
+ for my $line (split /\n/,$desc)
+ {
+ # Program header lines indicate what loadable chunks are present
+ # Handily, these refer to 'Virtual address' rather than 'Address'
+ $chunkdefined{$1} = 1 if $line =~ /^\s+Virtual address:\s+(0x[0-9a-fA-F]+)/;
+
+ # Section entries give the chunk name
+ if ($line =~ /^\*+\s+Section\s+#\d+\s+'([^']+)/)
+ {
+ # If there's only one chunk, fromelf creates a single file not a directory
+ $chunk = -d "$image.bin" ? "$image.bin/$1" : "$image.bin";
+ $zichunk = 0;
+ if ($line =~ / \(SHT_NOBITS\) /)
+ {
+ # We produce an explicit block of zeroes to cope with systems that don't auto-expand ZINIT areas
+ $chunk .= '.zi';
+ $zichunk = 1;
+ }
+ }
+
+ if ($zichunk && ($line =~ /^\s+Size\s*:\s+(\d+)\s+bytes/))
+ {
+ my $size = $1;
+ my $h;
+ open $h, ">$chunk" or die "Can't create ZI chunk '$chunk'";
+ binmode $h;
+ print $h chr(0) x $size;
+ close $h;
+ }
+ if ($line =~ /^\s+Address:\s+(0x[0-9a-fA-F]+)/ && ($zichunk || $chunkdefined{$1}))
+ {
+ # ZI data is already in the binary dump if it is followed by non-ZI data.
+ if ($zichunk && covered($1))
+ {
+ print "ZI data at $1 set by existing data; will not set explicitly\n";
+ $zichunk = 0;
+ # Remove .zi
+ $chunk = substr($chunk,0,-3);
+ }
+ else
+ {
+ # Multiple contiguous sections are saved as one chunk, so in that case only process the first
+ # Here we deal with the case where all the sections are contiguous
+ addchunk("$chunk",$1) if $zichunk || -d "$image.bin" || !$chunkdone;
+ $chunkdone = 1;
+ }
+ }
+
+ $kernaddr=$1 if $line =~ /^\s+Image Entry point:\s+(0x[0-9a-fA-F]+)/;
+ }
+}
+else
+{
+# print "$image being wrapped as plain binary to load at $kernaddr\n";
+ addchunk($image,$kernaddr);
+}
+
+die "No entry point in image or on command line" if !defined $kernaddr;
+
+print $sh " EXPORT ${source}_image\n${source}_image EQU $kernaddr\n END\n";