aos/tools/arm-mkbootelf.sh
Daniel Schwyn 6d444bf552 Main handout
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
2022-03-03 14:57:51 +01:00

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 $?