From 3f97e0f53cd9592277f545331aa295564ecd39fc Mon Sep 17 00:00:00 2001 From: Robert Ricci <ricci@cs.utah.edu> Date: Tue, 5 Apr 2005 06:54:23 +0000 Subject: [PATCH] Import set-mote-id, with soome local changes, from the TinyOS source. --- mote/GNUmakefile.in | 2 +- mote/set-mote-id | 131 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100755 mote/set-mote-id diff --git a/mote/GNUmakefile.in b/mote/GNUmakefile.in index bd52eb7a6f..a8fd16c71e 100644 --- a/mote/GNUmakefile.in +++ b/mote/GNUmakefile.in @@ -11,7 +11,7 @@ SUBDIR = mote include $(OBJDIR)/Makeconf -BIN_SCRIPTS = tbuisp tbsgmotepower newmote +BIN_SCRIPTS = tbuisp tbsgmotepower newmote set-mote-id # # Force dependencies on the scripts so that they will be rerun through diff --git a/mote/set-mote-id b/mote/set-mote-id new file mode 100755 index 0000000000..0fcb3fb18c --- /dev/null +++ b/mote/set-mote-id @@ -0,0 +1,131 @@ +#!/usr/bin/perl -wT +# Copyright (c) 2002 Intel Corporation +# All rights reserved. +# Distributed under the Intel Open Source Licesnse +# From the TinyOS distribution +# Modified to run setuid for Emulab +# +# This program changes the mote ID of a TinyOS image. It is used to +# install a program for a specific mote. +use strict; + +# un-taint path +$ENV{'PATH'} = "/bin:/usr/bin:/usr/local/bin"; +delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; + +# default to backward compatability mode +my $G_compat = 1; +while( @ARGV && $ARGV[0] =~ /^-/ ) { + my $opt = shift @ARGV; + if( $opt eq "--srec" ) { $G_compat = 1; } + elsif( $opt eq "--exe" ) { $G_compat = 0; } + else { die "Unknown command line option $opt\n"; } +} + +# print usage if we have the wrong number of arguments +if( @ARGV < 3 ) { + if( $G_compat ) { + print "usage: set-mote-id [srec_in] [srec_out] [TOS_LOCAL_ADDRESS] ...\n"; + } else { + print "usage: set-mote-id [exe_in] [exe_out] [TOS_LOCAL_ADDRESS] ...\n"; + } + exit 0; +} + +# get the args and default variables set up +my $exein = shift @ARGV; +my $exeout = shift @ARGV; + +# +# Taint check filenames +# +if ($exein =~ /^([-\w\/.]+)$/) { + $exein = $1; +} else { + die("*** Tainted exein: $exein\n"); +} +if ($exeout =~ /^([-\w\/.]+)$/) { + $exeout = $1; +} else { + die("*** Tainted exeout: $exeout\n"); +} + +my %user_symbols = (); +for my $value (@ARGV) { + my $name = 'TOS_LOCAL_ADDRESS'; + ($name,$value) = ($1,$2) if $value =~ /^([^=]+)=(.*)/; + $value = hex $value if $value =~ /^0x/; + $user_symbols{$name} = $value; +} +my $segment_vma = undef; +my $segment_lma = undef; +my $segment_off = undef; + +# if in compatability mode, derive the names of the exes from the srecs +my $srecin = undef; +my $srecout = undef; +if( $G_compat ) { + $srecin = $exein; + $srecout = $exeout; + $exein =~ s/srec/exe/; + $exeout =~ s/srec/exe/; +} + +# find the data section +open( SECTS, "avr-objdump -h $exein |" ) + or die "Cannot extract section information: $!\n"; +while(<SECTS>) { + if( /^\s*\d+\s+\.data\s+\S+\s+(\S+)\s+(\S+)\s+(\S+)/ ) { + $segment_vma = hex $1; + $segment_lma = hex $2; + $segment_off = hex $3; + last; + } +} +close(SECTS); +die "Could not find data section in $exein, aborting.\n" + unless defined $segment_vma && defined $segment_lma && defined $segment_off; + +# build a hash of all data segment symbols to their address and size +my %exe_symbols = (); +open( SYMBOL, "avr-objdump -t $exein |" ) + or die "Cannot extract symbol information: $!\n"; +while(<SYMBOL>) { + if( /^(\S+)\s+\S+\s+\S+\s+\.data\s+(\S+)\s+(\S+)\s*$/ ) { + $exe_symbols{$3} = { addr => hex($1), size => hex($2) }; + } +} +close(SYMBOL); + +# slurp the input exe +open (FILE_IN, "<$exein") or die "Could not open $exein: $!\n"; +binmode FILE_IN; +my $exe = join("",<FILE_IN>); +close( FILE_IN ); + +# change the desired symbols at their file offsets +for my $symbol (sort keys %user_symbols) { + my $value = $user_symbols{$symbol}; + if( defined $exe_symbols{$symbol} ) { + my $addr = $exe_symbols{$symbol}->{addr}; + my $size = $exe_symbols{$symbol}->{size}; + my $filepos = $segment_off + ($addr - $segment_vma); + my $bytes = substr( pack("V", $value) . ("\000" x $size), 0, $size ); + substr( $exe, $filepos, $size ) = $bytes; + } else { + warn "Could not find symbol $symbol in $exein, ignoring symbol.\n"; + } +} + +# barf the output exe +open (FILE_OUT, ">$exeout") or die "Could not open $exeout: $!\n"; +binmode FILE_OUT; +print FILE_OUT $exe; +close( FILE_OUT ); + +# if in compatability mode, convert the output exe to the output srec +if( $G_compat ) { + my $cmd = "avr-objcopy --output-target=srec $exeout $srecout"; + system( $cmd ) == 0 or die "Command \"$cmd\" failed"; +} + -- GitLab