86 lines
2.7 KiB
Bash
Executable File
86 lines
2.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
##########################################################################
|
|
# Copyright (c) 2009, ETH Zurich.
|
|
# All rights reserved.
|
|
#
|
|
# This file is distributed under the terms in the attached LICENSE file.
|
|
# If you do not find this file, copies can be found by writing to:
|
|
# ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
|
|
##########################################################################
|
|
|
|
#
|
|
# This script inserts a branch-link instruction as the first word in the
|
|
# kernel ELF file so it can self-load itself. This trickery allows the
|
|
# same kernel to load from ROM or RAM, and makes the RAW blob executable.
|
|
#
|
|
# This script should make you whince. Ultimately it should be replaced by
|
|
# a small program in the blessed scripting language.
|
|
#
|
|
if [ $# -ne 3 ] ; then
|
|
echo "Usage: <objdump_path> <kernel> <output_file>"
|
|
exit 1
|
|
fi
|
|
|
|
OBJDUMP=$1
|
|
KERNEL=$2
|
|
OUTPUT=$3
|
|
|
|
if [ ! -f ${KERNEL} ]; then
|
|
echo Failed to find kernel :- \"${KERNEL}\"
|
|
exit 1
|
|
fi
|
|
|
|
# check for required tools
|
|
if ! which tr sed dc dd > /dev/null; then
|
|
echo $0: missing one or more required tools > /dev/stderr
|
|
exit 1
|
|
fi
|
|
|
|
#
|
|
# Extract virtual start address, .text virtual address, .text file offset
|
|
# Set as shell variables ENTRY, SIZE, VTEXT, LTEXT, OFFSET
|
|
#
|
|
# The sed expression maps the address info from objdump into shelll variables.
|
|
#
|
|
# The use of tr is primarily to uppercase the hex digits to be presented to dc.
|
|
#
|
|
eval `"${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 }"`
|
|
|
|
if [ "${OFFSET}" = "" ] ; then
|
|
echo "Failed to extract addresses."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${ENTRY}" != "${VTEXT}" ] ; then
|
|
# Strictly we should just check entry is in text section.
|
|
echo "Entry address is not start of text section."
|
|
exit 1
|
|
fi
|
|
|
|
#
|
|
# Generate BL instruction (EB + pc_relative_offset / 4).
|
|
#
|
|
BL=`dc -e "16 o 16 i ${ENTRY} ${VTEXT} - ${OFFSET} + 8 - 4 / EB000000 + p"`
|
|
|
|
|
|
#
|
|
# 1. In case we compile or a big endian environment:
|
|
# Reverse order of string to get a big endian representation instead of a little endian one. This corresponds to inverting the stack for dc
|
|
#
|
|
# 2. Convert BL instruction from 8 digit hex representation into
|
|
# 32-bit binary word and append rest of kernel.
|
|
|
|
${OBJDUMP} -f ${KERNEL} | grep -q bigarm # Using return value for if statement
|
|
|
|
if [ $? -eq 0 ]; then
|
|
# We compile for big endian - reverse byte order
|
|
BL=${BL:6:2}${BL:4:2}${BL:2:2}${BL:0:2}
|
|
fi
|
|
|
|
|
|
dc -e "16o 16i ${BL} d 100 % P 100 / d 100 % P 100 / d 100 % P 100 / d 100 % P" > ${OUTPUT}
|
|
|
|
dd if=${KERNEL} of=${OUTPUT} skip=1 seek=1 bs=4 >/dev/null 2>&1
|
|
exit $?
|