1#!/bin/sh 2# 3# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4# 5# SPDX-License-Identifier: GPL-2.0-only 6# 7 8set -eu 9 10PROGNAME=${0##*/} 11 12# We use the following exit status conventions: 13# 0: normal operation, successful, "true" 14# 1: expected failure, "false" 15# 2: usage error 16# 3: other error 17EXIT_STATUS=3 18 19# Emit diagnostic message. 20# @params: a set of strings comprising a human-intelligible message 21_print () { 22 echo "${PROGNAME:-(unknown program)}: $*" 23} 24 25# Emit error message to standard error. 26# @params: a set of strings comprising a human-intelligible message 27fail () { 28 _print "error: $*" >&2 29} 30 31# Report unrecoverable error and terminate script. 32# @params: a set of strings comprising a human-intelligible message 33# 34# Note: $EXIT_STATUS, if set in the invoking scope, determines the exit status 35# used by this function. 36die () { 37 _print "fatal error: $*" >&2 38 exit ${EXIT_STATUS:-3} 39} 40 41# Display a usage message. 42show_usage () { 43 cat <<EOF 44$PROGNAME: generate U-Boot payload for ARM platform 45 46Usage: 47 $PROGNAME OBJCOPY-TOOL ELF-FILE ARCHITECTURE OUTPUT-FILE 48 49$PROGNAME uses objcopy, readelf (both from GNU binutils), and mkimage 50(from the U-Boot tools) to extract the entry point (start symbol) of an 51ELF executable and wrap the object in a chain-loadable payload for use 52by the U-Boot boot loader. 53 54OBJCOPY-TOOL should be the path to a version of GNU objcopy appropriate 55for the (cross-)built ELF-FILE. ELF-FILE should be an ELF executable 56object. ARCHITECTURE must be either "arm" or "arm64". The image is 57written to OUTPUT-FILE. 58EOF 59} 60 61# Clean up temporary file. $TEMPFILE is defined before this function is called. 62cleanup () { 63 rm -f $TEMPFILE 64} 65 66# Output the start symbol from given ELF object. 67# 68# Note: This function is sensitive to the output format of "readelf". 69get_start_symbol() { 70 ELF_FILE=$1 71 72 if ! readelf -h "$ELF_FILE" > /dev/null 73 then 74 die "\"$ELF_FILE\" does not appear to be an ELF file" 75 fi 76 77 set -- $(readelf -s $ELF_FILE | grep -w _start) 78 echo $2 79} 80 81if [ $# -ne 4 ] 82then 83 fail "expected 4 arguments, got $#: \"$*\"" 84 show_usage >&2 85 exit 2 86fi 87 88OBJCOPY=$1 89ELF_FILE=$2 90ARCHITECTURE=$3 91OUTPUT=$4 92 93# Validate arguments. $ELF_FILE is validated by get_start_symbol(). We'll let 94# mkimage fail if $OUTPUT is not writable. 95 96if ! [ -x "$OBJCOPY" ] 97then 98 die "\"$OBJCOPY\" does not exist or is not executable" 99fi 100 101case "$ARCHITECTURE" in 102 (arm|arm64) 103 ;; 104 (*) 105 EXIT_STATUS=2 106 die "unrecognized (ARM) architecture \"$ARCHITECTURE\"" 107 ;; 108esac 109 110# $ARCHITECTURE is now known to be a safe string and no longer requires 111# quotation. 112 113TEMPFILE=$(mktemp) 114trap cleanup HUP INT QUIT TERM EXIT 115 116# Note: Because we are using a temporary file, the appending redirection is 117# important! Do not degenerate it to ">", which will unlink the destination 118# first and reintroduce the race that mktemp avoids. 119"$OBJCOPY" -O binary "$ELF_FILE" /dev/stdout >> $TEMPFILE 120START=$(get_start_symbol "$ELF_FILE") 121mkimage -A $ARCHITECTURE -O linux -T kernel -C none \ 122 -a $START -e $START -d $TEMPFILE "$OUTPUT" 123 124exit 0 125