/usr/bin/redboot-install is in redboot-tools 0.7build2.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | #!/bin/bash
#
# redboot-install
# - a tool to create a bootable SD card on a babbage board
#
# Copyright (c) 2009 Canonical
# Authors: Oliver Grawert <ogra@canonical.com>
# Loïc Minier <loic.minier@canonical.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Required packages: redboot-imx51-babbage, redboot-tools, linux-imx51
#
# TODO
# - use safer -m flag of parted (needs a newer parted)
DEV=""
DIST="jaunty"
FLAVOUR="imx51"
BOARD="babbage"
HWITER="-TO2"
trap cleanup 0 1 2 3 6
cleanup()
{
if [ -d "${BUILDDIR}" ]; then
echo "cleaning up ..."
rm -rf $BUILDDIR
echo "done ..."
fi
exit 0
}
usage()
{
echo '
usage: redboot-install -d <device> [option]
required options:
-d --device <device>
Target device to write redboot setup to
additional options:
-h --help
This help
-k --kernel
Location of the vmlinuz/zImage file with full path
Defaults to: /boot/vmlinuz-$(uname -r)
-i --initrd
Location of the initrd.gz file with full path
Defaults to: /boot/initrd.img-$(uname -r)
-c --cmdline
Kernel commandline to use for booting
Defaults to: root=UUID=<uuid of current /> ro quiet
-n --nodev
Allow argument to -d to not be a blockdevice
(i.e. for use with an image file)
'
exit 0
}
checkparm()
{
if [ "$(echo $1|grep ^'\-')" ] || [ -z "$1" ];then
echo "E: Need an argument"
usage
fi
}
ALLOW_IMAGE=""
while [ ! -z "$1" ]; do
case $1 in
-h|--help)
usage
;;
-d|--device)
checkparm $2
DEV="$2"
;;
-k|--kernel)
checkparm $2
KERNEL_FIS_DATA="$2"
;;
-i|--initrd)
checkparm $2
INITRD_FIS_DATA="$2"
;;
-c|--cmdline)
checkparm $2
CMDLINE="$2"
;;
-n|--nodev)
ALLOW_IMAGE="1"
esac
shift
done
if [ ! -n "${DEV}" ];then
usage
fi
if [ ! -b "${DEV}" ] && [ -z "${ALLOW_IMAGE}" ];then
echo "E: no such device: $DEV"
exit 0
fi
if [ ! -w "${DEV}" ];then
echo "E: cannot write to: $DEV"
exit 0
fi
file_length() {
stat -c %s "$1"
}
BUILDDIR=$(mktemp -d)
CMDLINE="${CMDLINE:-ro quiet splash}"
KERNEL_FIS_DATA="${KERNEL_FIS_DATA:-/boot/vmlinuz-$(uname -r)}"
INITRD_FIS_DATA="${INITRD_FIS_DATA:-/boot/initrd.img-$(uname -r)}"
# pick an arbitrary large enough size multiple of 512 (sector size) and of
# 0x20000 (flash block size)
FIS_SIZE="$((16 * 1024 * 1024))"
hex2dec() {
printf "%d\n" "$1"
}
# create partition table
echo "initializing disk label (MBR and partition table)..."
parted -s "$DEV" mklabel msdos
echo "creating FIS partition..."
# 512 bytes is the smallest offset where the partition can start; note that the
# FIS starts on the first sector (LBA address 0 or offset 0); also note that
# parted END address is inclusive, so we substract 1 from FIS_SIZE
parted -s "$DEV" mkpart primary fat32 "512B" "$(($FIS_SIZE - 1))B"
# hackish way to set partition type to "Non-FS data" (0xda); neither parted
# not fdisk work well in all cases here; fdisk will complain about lack of
# number of cylinders, and parted doesn't take arbitrary ids
# partition table starts at 0x01BE, partition type is at +0x04
PART1_ID_OFFSET="$(hex2dec 0x1c2)"
printf '\xda' | dd conv=notrunc bs="$PART1_ID_OFFSET" of="$DEV" seek=1 2>/dev/null
# outputs actual partition start offset, end offset, and length, suffixed with
# B
get_part_data() {
local n="$1"
LANG=C parted -s "$DEV" unit B print | awk "/^ $n / { print \$2 \" \" \$3 \" \" \$4 }"
# safer version using parted -m; needs newer parted
#LANG=C parted -m -s "$DEV" unit B print | grep "^$n:" | cut -d: -f 2,3,4 --output-delimiter=" "
}
PART1_END_B="`(set -- $(get_part_data 1); echo "$2")`"
if [ "$((${PART1_END_B%B} + 1))" -lt "$FIS_SIZE" ]; then
echo "FIS partition ends at $PART1_END_B and doesn't leave enough room for FIS ${FIS_SIZE}B"
fi
REDBOOT_PKG="redboot-$FLAVOUR-$BOARD"
REDBOOT_DATA="/usr/lib/redboot/$FLAVOUR-${BOARD}${HWITER}_redboot.bin"
CONFIG_DATA="/usr/lib/redboot/$FLAVOUR-${BOARD}_fconfig.bin"
# the FIS config depends of the target board; offsets are converted to decimal
# for dd and "test"
FIS_DIR_OFFSET="$(hex2dec 0x40000)"
FIS_DIR_LENGTH="$(hex2dec 0x1F000)"
FIS_DIR_ADDR="$(hex2dec 0x40000)"
# where to actually write RedBoot
REDBOOT_OFFSET="$(hex2dec 0x400)"
# the address to write in the FIS entry; we could theoritically write 0x400
# here and decrease the entry length by the same amount, but eCos/RedBoot don't
# like writing at addresses not aligned to 0x20000, so avoid that; it's not
# clear whether the ROM loads 0x0 - 0x400 in memory, or whether the romupdate
# command is clever enough to avoid this issue on write, but it's not a problem
# because the romupdate command is a no-op when booting from SD
REDBOOT_FIS_OFFSET="$(hex2dec 0x0)"
REDBOOT_FIS_LENGTH="$(hex2dec 0x40000)"
CONFIG_FIS_OFFSET="$(hex2dec 0x5F000)"
CONFIG_FIS_LENGTH="$(hex2dec 0x1000)"
CONFIG_FIS_ADDR="$(hex2dec 0x5F000)"
KERNEL_FIS_OFFSET="$(hex2dec 0x60000)"
KERNEL_FIS_LENGTH="$(hex2dec 0x500000)"
KERNEL_FIS_ENTRY="$(hex2dec 0x100000)"
KERNEL_FIS_ADDR="$(hex2dec 0x100000)"
INITRD_FIS_OFFSET="$(hex2dec 0x560000)"
INITRD_FIS_LENGTH="$(hex2dec 0x940000)"
INITRD_FIS_ENTRY="$(hex2dec 0xFFFFFFFF)"
INITRD_FIS_ADDR="$(hex2dec 0x1000000)"
# wrapper to call the FIS command-line tool
fis_do() {
fis -d "$DEV" -o "$FIS_DIR_OFFSET" -s "$FIS_DIR_LENGTH" "$@"
}
# helper to write a file's data to the FIS at given offset; also checks the
# file is smaller than length before writing
# NB: this actually uses $offset memory, so don't use too large offsets
fis_write() {
local file="$1"
local offset="$2"
local max_length="$3"
if [ "$(file_length "$1")" -gt "$max_length" ]; then
echo "File $file is larger than maximum allowed size of $max_length"
fi
dd conv=notrunc bs="$offset" if="$file" of="$DEV" seek=1 2>/dev/null
}
echo "initializing fis directory..."
fis_do init
echo " 'RedBoot'"
fis_do create "RedBoot" \
-f "$REDBOOT_FIS_OFFSET" \
-l "$REDBOOT_FIS_LENGTH" \
-c "$REDBOOT_DATA"
fis_write "$REDBOOT_DATA" "$REDBOOT_OFFSET" "$REDBOOT_FIS_LENGTH"
echo " 'FIS directory'"
fis_do create "FIS directory" \
-f "$FIS_DIR_OFFSET" \
-l "$FIS_DIR_LENGTH" \
-r "$FIS_DIR_ADDR"
echo "writing bootloader configuration..."
# modified bootloader config
# TODO use mktemp
CONFIG_DATA_MODIFIED="fconfig.bin"
cp "$CONFIG_DATA" "$CONFIG_DATA_MODIFIED"
# set a config var to a value
fconfig_set() {
fconfig -s -w -d "$CONFIG_DATA_MODIFIED" -n "$1" -x "$2"
}
# launch boot script on boot
fconfig_set boot_script TRUE
# after 3 seconds
fconfig_set boot_script_timeout 3
# actual boot script
SCRIPT="fis load initrd\\"
SCRIPT="${SCRIPT}fis load kernel\\"
SCRIPT="${SCRIPT}exec -r $INITRD_FIS_ADDR -s $INITRD_FIS_LENGTH -c \"$CMDLINE\"\\"
fconfig_set boot_script_data "$SCRIPT"
# disable DHCP on boot
fconfig_set bootp FALSE
echo " 'RedBoot config'"
fis_do create "RedBoot config" \
-f "$CONFIG_FIS_OFFSET" \
-l "$CONFIG_FIS_LENGTH" \
-r "$CONFIG_FIS_ADDR" \
-c "$CONFIG_DATA_MODIFIED"
fis_write "$CONFIG_DATA_MODIFIED" "$CONFIG_FIS_OFFSET" "$CONFIG_FIS_LENGTH"
# purge extracted RedBoot and RedBoot config data
rm -rf usr
echo " 'kernel'"
fis_do create "kernel" \
-f "$KERNEL_FIS_OFFSET" \
-l "$KERNEL_FIS_LENGTH" \
-e "$KERNEL_FIS_ENTRY" \
-r "$KERNEL_FIS_ADDR" \
-c "$KERNEL_FIS_DATA"
fis_write "$KERNEL_FIS_DATA" "$KERNEL_FIS_OFFSET" "$KERNEL_FIS_LENGTH"
# pad initrd
INITRD_FIS_DATA_LENGTH="$(file_length "$INITRD_FIS_DATA")"
PADDED_INITRD_FIS_DATA="$INITRD_FIS_DATA.padded"
if [ "$INITRD_FIS_DATA_LENGTH" -gt "$INITRD_FIS_LENGTH" ]; then
echo "Initrd $INITRD_FIS_DATA too big for FIS initrd partition length ($INITRD_FIS_LENGTH)"
fi
PAD="$(expr "$INITRD_FIS_LENGTH" - "$INITRD_FIS_DATA_LENGTH")"
(
cat "$INITRD_FIS_DATA"
# pad with zeroes; this uses $PAD mem, not very elegant
dd if=/dev/zero bs="$PAD" count=1 2>/dev/null
) | dd of="$PADDED_INITRD_FIS_DATA" bs=4k 2>/dev/null
echo " 'initrd'"
fis_do create "initrd" \
-f "$INITRD_FIS_OFFSET" \
-l "$INITRD_FIS_LENGTH" \
-e "$INITRD_FIS_ENTRY" \
-r "$INITRD_FIS_ADDR" \
-c "$PADDED_INITRD_FIS_DATA"
fis_write "$PADDED_INITRD_FIS_DATA" "$INITRD_FIS_OFFSET" "$INITRD_FIS_LENGTH"
rm -f "$PADDED_INITRD_FIS_DATA"
|