1#!/bin/bash
2##########################################################################
3# Copyright (c) 2009-2015 ETH Zurich.
4# All rights reserved.
5#
6# This file is distributed under the terms in the attached LICENSE file.
7# If you do not find this file, copies can be found by writing to:
8# ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
9# Attn: Systems Group.
10#
11# Shell script for constructing a multiboot image for Pandaboard
12#
13##########################################################################
14
15SRC_DIR=
16BUILD_DIR=
17ARM_GCC=$(which arm-linux-gnueabi-gcc)
18ARM_OBJCOPY=$(which arm-linux-gnueabi-objcopy)
19MENU_LST=""
20DEFINES=""
21EXTRAS=""
22BASE_ADDR=""
23ARCH=armv7-a
24IMAGE="pandaboard_image"
25EXTRACFLAGS=""
26
27usage () { 
28    echo "Usage: $0 --srcdir <dir> --builddir <dir> --menu <menu.lst> [option].."
29    echo " where options are:"
30    echo "   --arch <ARM architecture>       (default: $ARCH)"
31    echo "   --gcc <gcc binary>              (default: $ARM_GCC)"
32    echo "   --objcopy <objcopy binary>      (default: $ARM_OBJCOPY)"
33    echo "   -D <define>"
34    echo "   --extra <additional file>"
35    echo "   --image <output image file>     (default: $IMAGE)"
36    echo "   --cflags <flags to pass to cc>  (default: -march=$ARCH $EXTRACFLAGS)"
37    exit 0
38}
39
40if [ $# == 0 ]; then usage ; fi
41
42while [ $# != 0 ]; do
43    case $1 in
44	"--help")
45	    usage
46	    exit 0
47	    ;;
48	"--srcdir")
49	    shift; SRC_DIR="$1"
50	    ;;
51	"--builddir")
52	    shift; BUILD_DIR="$1"
53	    ;;
54	"--baseaddr")
55	    shift; BASE_ADDR="$1"
56	    ;;
57	"--arch")
58	    shift; ARCH="$1"
59	    ;;
60	"--gcc")
61	    shift; ARM_GCC="$1"
62	    ;;
63	"--objcopy")
64	    shift; ARM_OBJCOPY="$1"
65	    ;;
66	"--menu")
67	    shift; MENU_LST="$1"
68	    ;;
69	"-D")
70	    shift; DEFINES="$DEFINES -D$1"
71	    ;;
72	"--extra")
73	    shift; EXTRAS="$EXTRAS $1"
74	    ;;
75	"--image")
76	    shift; IMAGE="$1"
77	    ;;
78	"--cflags")
79	    shift; EXTRACFLAGS="$1"
80	    ;;
81	*)
82	    echo "Unknown option $1 (try: --help)" >&2
83	    exit 1
84	    ;;
85    esac
86    shift
87done
88
89CFLAGS="-march=$ARCH $EXTRACFLAGS"
90BASEARCH=$(echo $ARCH | sed s/-.*//)
91if [ "$BASEARCH" == "armv8" ]
92then
93    BFDNAME="elf64-littleaarch64"
94    BFDARCH="aarch64"
95    BW=64
96    KARCH="aarch64"
97else
98    BFDNAME="elf32-littlearm"
99    BFDARCH="arm"
100    BW=32
101    KARCH="arm"
102fi
103
104if [ -z "$SRC_DIR" ] ; then
105    echo "No source directory defined." >&2; exit 1
106elif [ -z "$BUILD_DIR" ] ; then
107    echo "No build directory defined." >&2; exit 1
108elif [ -z "$ARM_GCC" ]; then
109    echo "No ARM GCC compiler defined." >&2; exit 1
110elif [ -z "$ARM_OBJCOPY" ]; then
111    echo "No ARM objcopy utility." >&2; exit 1
112elif [ -z "$MENU_LST" ]; then
113    echo "No boot menu list defined." >&2; exit 1
114elif [ -z "$BASE_ADDR" ]; then
115    echo "No kernel base address defined." >&2; exit 1
116fi
117
118TMP_DIR="$BUILD_DIR/molly_tmp_"`basename $IMAGE`
119
120# Dependencies:
121#  - tools/bin/arm_molly must be built
122#  - all modules mentioned in $MENU_LST must exist in $ARCH/sbin/
123#  - the menu.list file
124#
125# Outputs: 
126#  - $IMAGE : the image to be built
127
128TMP_LDSCRIPT="$TMP_DIR/molly_ld_script"
129TMP_MBIC="$TMP_DIR/panda_mbi.c"
130
131# Prefix prepended to each output file within the directory
132# $OUTPUT_PREFIX (for safety, this means we can clean the directory
133# by removing everything with this prefix)
134TMP_PREFIX=tmp_molly
135
136echo "Cleaning temporary directory $TMP_DIR"
137rm -rf "$TMP_DIR"
138mkdir -p "$TMP_DIR"
139
140echo "Generating the list of of binaries to translate"
141BINS=$(awk '/^kernel/ || /^module/ {print $2}' $MENU_LST | uniq)
142# For each binary generate an object file in the output directory.
143# The flags to objcopy cause it to place the binary image of the input
144# file into an .rodataIDX section in the generated object file where
145# IDX is a counter incremented for each binary.  
146echo "Translating data files ($BFDNAME,$BFDARCH)"
147IDX=1
148for BIN in $BINS; do
149  UNDERSCORED=${BIN//-/_}
150  SLASH=${UNDERSCORED////_}
151  BIN_OUT="$TMP_DIR/${TMP_PREFIX}_$SLASH"
152  echo ' ' $BIN '->' $BIN_OUT
153  $ARM_OBJCOPY -I binary -O $BFDNAME -B $BFDARCH \
154    --rename-section .data=.rodata$IDX,alloc,load,readonly,data,contents \
155    .$BIN $BIN_OUT
156  IDX=$(($IDX+1))
157  if [ $IDX = 20 ]; then
158      echo Error: linker script cannot handle $IDX modules
159      exit 1
160  fi
161done
162
163echo "Creating appropriate linker script"
164cpp -P -DBASE_ADDR=$BASE_ADDR \
165       "$SRC_DIR/tools/arm_molly/molly_ld_script${BW}.in" \
166       "$TMP_LDSCRIPT"
167
168echo "Building a C file to link into a single image for the 2nd-stage bootloader"
169"$BUILD_DIR/tools/bin/arm_molly" "$MENU_LST" "$TMP_MBIC" "-$BW"
170
171echo "Compiling the complete boot image into a single executable"
172$ARM_GCC -std=c99 -g -fPIC -pie -Wl,-N -fno-builtin \
173	-nostdlib $CFLAGS -fno-unwind-tables \
174	-T$TMP_LDSCRIPT \
175	-I$SRC_DIR/include \
176	-I$SRC_DIR/include/arch/$KARCH \
177	-I./$BASEARCH/include \
178	-I$SRC_DIR/include/oldc \
179	-I$SRC_DIR/include/c \
180	$SRC_DIR/tools/arm_molly/molly_boot${BW}.S \
181	$SRC_DIR/tools/arm_molly/molly_init${BW}.c \
182	$SRC_DIR/tools/arm_molly/lib.c \
183	$TMP_MBIC \
184	$SRC_DIR/lib/elf/elf${BW}.c \
185	$TMP_DIR/${TMP_PREFIX}* \
186    $EXTRAS \
187	-o $IMAGE
188
189echo "OK - boot image $IMAGE is built."
190echo "If this is a pandaboard image, you can now:"
191echo "usbboot $IMAGE"
192