1#!/bin/bash 2 3########################################################################## 4# Copyright (c) 2009, ETH Zurich. 5# All rights reserved. 6# 7# This file is distributed under the terms in the attached LICENSE file. 8# If you do not find this file, copies can be found by writing to: 9# ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 10########################################################################## 11 12# 13# This script inserts a branch-link instruction as the first word in the 14# kernel ELF file so it can self-load itself. This trickery allows the 15# same kernel to load from ROM or RAM, and makes the RAW blob executable. 16# 17# This script should make you whince. Ultimately it should be replaced by 18# a small program in the blessed scripting language. 19# 20if [ $# -ne 3 ] ; then 21 echo "Usage: <objdump_path> <kernel> <output_file>" 22 exit 1 23fi 24 25OBJDUMP=$1 26KERNEL=$2 27OUTPUT=$3 28 29if [ ! -f ${KERNEL} ]; then 30 echo Failed to find kernel :- \"${KERNEL}\" 31 exit 1 32fi 33 34# check for required tools 35if ! which tr sed dc dd > /dev/null; then 36 echo $0: missing one or more required tools > /dev/stderr 37 exit 1 38fi 39 40# 41# Extract virtual start address, .text virtual address, .text file offset 42# Set as shell variables ENTRY, SIZE, VTEXT, LTEXT, OFFSET 43# 44# The sed expression maps the address info from objdump into shelll variables. 45# 46# The use of tr is primarily to uppercase the hex digits to be presented to dc. 47# 48eval `"${OBJDUMP}" -x "${KERNEL}" | tr "[a-z]" "[A-Z]" | sed -n -e "/^START ADDRESS/ { s@.*0X\([0-9A-F]*\).*@ENTRY=\1;@; p }" -e "/TEXT/ { s@.*TEXT[ \t]*\([0-9A-F]*\)[ \t]*\([0-9A-F]*\)[ \t]*\([0-9A-F]*\)[ \t]*\([0-9A-F]*\).*@SIZE=\1 ; VTEXT=\2; LTEXT=\3; OFFSET=\4@; p; q }"` 49 50if [ "${OFFSET}" = "" ] ; then 51 echo "Failed to extract addresses." 52 exit 1 53fi 54 55if [ "${ENTRY}" != "${VTEXT}" ] ; then 56 # Strictly we should just check entry is in text section. 57 echo "Entry address is not start of text section." 58 exit 1 59fi 60 61# 62# Generate BL instruction (EB + pc_relative_offset / 4). 63# 64BL=`dc -e "16 o 16 i ${ENTRY} ${VTEXT} - ${OFFSET} + 8 - 4 / EB000000 + p"` 65 66 67# 68# 1. In case we compile or a big endian environment: 69# Reverse order of string to get a big endian representation instead of a little endian one. This corresponds to inverting the stack for dc 70# 71# 2. Convert BL instruction from 8 digit hex representation into 72# 32-bit binary word and append rest of kernel. 73 74${OBJDUMP} -f ${KERNEL} | grep -q bigarm # Using return value for if statement 75 76if [ $? -eq 0 ]; then 77 # We compile for big endian - reverse byte order 78 BL=${BL:6:2}${BL:4:2}${BL:2:2}${BL:0:2} 79fi 80 81 82dc -e "16o 16i ${BL} d 100 % P 100 / d 100 % P 100 / d 100 % P 100 / d 100 % P" > ${OUTPUT} 83 84dd if=${KERNEL} of=${OUTPUT} skip=1 seek=1 bs=4 >/dev/null 2>&1 85exit $? 86