3
base_d=$(dirname $(readlink -f "${0}"))
9
${0##*/} - Create QEMU or hardware capable ARMEL images
12
--type [raw|qcow2]) Image format type
13
--mlo) MLO firmware for ARM hardware
14
--uboot) u-boot binary
15
--rootfs) Image containing root file system to put into new image
16
--disk) Name of final image
19
Example: ${0##*/} --type qcow2 --mlo MLO -uboot u-boot.bin --rootfs mfs.img --disk new.img
23
bad_Usage() { Usage 1>&2; fail "$@"; }
25
debug() { error "$(date -R):" "$@"; }
27
error() { echo -e "$@" 1>&2; }
30
# done on exit or fail
32
# Unmount file-systems
33
[ -z "${rootfs_dm}" ] || { umount "${rootfs_dm}" 2> /dev/null; }
34
[ -z "${bootfs_dm}" ] || { umount "${bootfs_dm}" 2> /dev/null; }
35
[ -z "${copy_rootfs_dm}" ] || { umount "${copy_rootfs_dm}" 2> /dev/null; }
37
# Clean up the device mappings.
38
# Due to bugginess in kpartx on lucid, dmsetup is being used first to remove devices
39
# and then fallback to kpartx just in case.
40
[ -z "${copy_rootfs_loop}" ] || {
41
local loop_dev=$(echo $copy_rootfs_loop | awk -F\/ '{print$NF}')
42
find /dev/mapper -iname "${loop_dev}*" | xargs -n1 -I DEVICE dmsetup remove DEVICE ||
43
kpartx -d "${copy_rootfs_loop}" ||
44
echo "Failed to remove device mapper devices for ${copy_rootfs_loop}"
45
losetup -d "${copy_rootfs_loop}";
49
local loop_dev=$(echo ${loop} | awk -F\/ '{print$NF}')
50
find /dev/mapper -iname "${loop_dev}*" | xargs -n1 -I DEVICE dmsetup remove DEVICE ||
51
kpartx -d "${loop}" ||
52
echo "Failed to remove device mapper devices for ${loop}"
53
losetup -d "${loop}" ||
54
echo "Failed to remove loop device ${loop}"
57
# Clean up temporary directories
58
[ -z "${TEMPDIR}" ] || rm -rf "${TEMPDIR}"
59
[ -z "${mp_rootfs}" ] || rm -rf "${mp_rootfs}"
60
[ -z "${mp_uboot}" ] || rm -rf "${mp_uboot}"
65
error "$(date -R): $@";
72
which $1 > /dev/null >&1 ||
73
fail "Sorry, you need to have $1 installed"
77
fail "Unable to find required file $@"
81
long_opts="disk:,rootfs:,mlo:,uboot:,type:,label:"
82
getopt_out=$(getopt --name "${0##*/}" \
83
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
84
eval set -- "${getopt_out}" ||
87
# Basic control variables that are required
88
img="" # Base working image
89
mlo_firmware="" # MLO firmware file
90
uboot_firmware="" # u-boot firmware
91
stuff_img="" # Rootfs to stuff into image
92
img_type="" # Image format type
94
while [ $# -ne 0 ]; do
96
--disk) img="${2}.raw"; shift;;
97
--rootfs) stuff_img="${2}"; shift;;
98
--mlo) mlo_firmware="${2}"; shift;;
99
--uboot) uboot_firmware="${2}"; shift;;
100
--type) img_type="${2}"; shift;;
101
--label) img_label="${2}"; shift;;
108
[ -n "${mlo_firmware}" ] || need_file "${mlo_firmware} (identified as MLO firmware)"
109
[ -n "${uboot_firmware}" ] || need_file "${uboot_firmware} (identified as u-boot firmware)"
110
[ -n "${stuff_img}" ] || need_file "${stuff_img} (identified as root file system)"
111
[ -n "${img}" ] || fail "--disk <NAME> is required"
112
[ -n "${img_type}" ] || fail "--type <[raw|qcow2]> is required"
114
[ "${img_type}" = "qcow2" -o "${img_type}" = "raw" ] ||
115
fail "Valid types are raw or qcow2."
117
# Clean up the image name
118
final_img="${img//.raw/}"
120
mp_uboot=$(mktemp -d)
129
TEMPDIR=${TEMPDIR:-$(mktemp -d )}
130
uimage="${TEMPDIR}/uImage"
131
bootscr="${TEMPDIR}/boot.scr"
132
uinitrd="${TEMPDIR}/uInitrd"
133
kernel="${TEMPDIR}/vmlinuz"
134
initrd="${TEMPDIR}/initrd"
136
debug "IMAGE PARAMETERS: "
137
debug " Image with rootfs: ${stuff_img}"
138
debug " MLO Firmware: ${mlo_firmware}"
139
debug " u-boot Firmware: ${uboot_firmware}"
140
debug " Image Type: ${img_type}"
141
debug " Final Image: ${final_img}"
144
# Support multiple formats
146
file_name="${TEMPDIR}/$(echo $stuff_img | awk -F\/ '{print$NF}')"
147
if [ "$( file ${stuff_img} | awk '/Qemu Image/ {print$NF}' )" = "2" ]; then
148
debug "Converting ${stuff_img} to ${file_name}.raw "
149
qemu-img convert -O raw ${stuff_img} "${file_name}.raw" ||
150
fail "Unable to convert disk image"
151
working_stuff_img="${file_name}.raw"
152
elif [ "$( file ${stuff_img} | awk '/VMware/ {print$2}' )" = "VMware4" ]; then
153
debug "Converting ${stuff_img} to ${file_name}.raw "
154
vboxmanage clonehd --format RAW ${stuff_img} "${file_name}.raw" ||
155
fail "Unable to convert disk image"
156
working_stuff_img="${file_name}.raw"
158
working_stuff_img="${stuff_img}"
162
# Make the boot files
165
## DON'T CHANGE THESE VALUES! IT WON'T WORK!
166
cat << END >> ${TEMPDIR}/boot.cmd
167
setenv dvimode 1280x720MR-16@60
169
setenv bootcmd 'fatload mmc 0:1 0x80300000 uImage; fatload mmc 0:1 0x81600000 uInitrd; bootm 0x80300000 0x81600000'
170
setenv bootargs console=ttyO2 omapfb.mode=dvi root=LABEL=${rootfs_label:-cloudimg-rootfs} rw fixrtc
174
debug "Starting to build boot images"
175
debug "Making kernel image"
176
mkimage -A arm -O linux -T kernel -C none -a 0x80300000 -e 0x80300000 -n "Linux" -d "${kernel}" "${uimage}" ||
177
fail "Failed to create uImage"
179
debug "Making initrd image"
180
mkimage -A arm -O linux -T ramdisk -C none -a 0x81600000 -e 0x81600000 -n "Initrd" -d "${initrd}" "${uinitrd}" ||
181
fail "Failed to create uInitrd"
183
debug "Making boot.cmd image"
184
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "Ubuntu" -d "${TEMPDIR}/boot.cmd" "${bootscr}" ||
185
fail "Failed to create boot.scr"
187
[ -e "${uimage}" ] || fail "Failed to find ${uimage}"
188
[ -e "${uinitrd}" ] || fail "Failed to find ${uinitrd}"
189
[ -e "${bootscr}" ] || fail "Failed to find ${bootscr}"
191
debug "Finished making boot images"
196
debug "Creating disk image...may take a while"
198
dd if=/dev/zero of=${img} bs=1M count=2120
199
debug "Created ${img}"
200
} || fail "Destination disk image already exists, bailing"
202
sfdisk --no-reread --force -uM -H255 -S63 ${img} <<END_DISK
207
loop_raw="$(kpartx -v -a ${img} )" || fail "Failed to add image via kpartx"
208
debug "Setup raw destination disk"
209
echo -e "${loop_raw}"
214
#Extract information about loop
215
loop="$(echo -e ${loop_raw} | head -n1 | awk '{print$8}')" ||
216
fail "Unable to determine loop device"
217
bootfs_dm="/dev/mapper${loop///dev/}p1"
218
rootfs_dm="/dev/mapper${loop///dev/}p2"
220
debug "Boot partition setup on ${bootfs_dm}"
221
debug "Root partition setup on ${rootfs_dm}"
225
file_base="$(echo $1 | awk -F\/ '{print$NF}')"
226
debug "Copying ${file_base}"
227
cp $1 $2 || fail "failed to copy ${1} to ${2}"
228
[ -e "${2}" ] || fail "${file_base} is not found on destination file system"
232
# boot fs must be 32-bit vFAT
233
mkfs.msdos -F32 -v "${bootfs_dm}" 2> /dev/null ||
234
fail "Failed to create boot file system"
236
[ -e "${mp_uboot}" -o -z "${bootfs_dm}" ] && mount "${bootfs_dm}" "${mp_uboot}" ||
237
fail "Unable to mount uboot partition"
239
copy_or_fail "${mlo_firmware}" "${mp_uboot}/MLO"
240
copy_or_fail "${uboot_firmware}" "${mp_uboot}/u-boot.bin"
241
copy_or_fail "${uimage}" "${mp_uboot}/uImage"
242
copy_or_fail "${uinitrd}" "${mp_uboot}/uInitrd"
243
copy_or_fail "${bootscr}" "${mp_uboot}/boot.scr"
246
debug "Contents of u-boot device"
247
ls -lh1 "${mp_uboot}"
251
[ -e "${working_stuff_img}" ] ||
252
fail "Unable to find the working copy of root file system image"
254
# Set up image for extacting kernel and initrd
255
mp_rootfs=$(mktemp -d) ||
256
fail "Unable to create temp mont point for rootfs"
257
copy_root_raw=$(kpartx -a -v "${working_stuff_img}" ) ||
258
fail "Unable to map rootfs"
260
debug "Setup Source FS:"
261
echo -e "${copy_root_raw}"
263
# Determine devices of rootfs image and mount
264
copy_rootfs_loop=$(echo ${copy_root_raw} | head -n 1 | awk '{print$8}' ) ||
265
fail "Unable to determine copy_rootfs_loop"
266
# Assume that the last partition has the root file system
267
copy_rootfs_dm=$(echo ${copy_root_raw} | tail -n1 | awk '{print"/dev/mapper/"$3}' ) ||
268
fail "Unable to determine copy_rootfs_dm"
270
debug "Source rootfs loop devices is ${copy_rootfs_loop}"
271
debug "Source rootfs device mapper is ${copy_rootfs_dm}"
273
[ -n "${img_label}" ] &&
274
rootfs_label=${img_label} ||
276
rootfs_label=$(tune2fs -l ${copy_rootfs_dm} | awk '/Filesystem volume name/ {print$NF}') ||
277
fail "Unable to determine copy rootfs id"
280
[ -n "${rootfs_label}" ] ||
281
fail "root file system lacks a label, this is fatal"
283
mount "${copy_rootfs_dm}" "${mp_rootfs}" ||
284
fail "Failed to mount copy_rootfs"
286
# Extract the kernel and intrd after mounting
287
[ -d "${mp_rootfs}/boot" ] || fail "Unable to find boot directory within image"
288
cp -a "${mp_rootfs}/boot/" "${TEMPDIR}" ||
289
fail "Unable to copy boot directory to ${TEMPDIR}"
291
# Get the most recent kernel and initrd name
292
kernel=$(find ${TEMPDIR}/ -iname "vmlinuz*" | sort -rn | head -n1 )
293
initrd=$(find ${TEMPDIR}/ -iname "initrd*" | sort -rn | head -n1 )
295
[ -e "${kernel}" ] || fail "Did not find any kernel images"
296
[ -e "${initrd}" ] || fail "Did not find any initrd images"
298
debug "Using ${kernel} as kernel image"
299
debug "Using ${initrd} as initrd image"
302
debug "Copying source root file system to image"
303
dd if="${copy_rootfs_dm}" of="${rootfs_dm}" && debug "Finished copying rootfile system" ||
304
error "Potential problem copying rootfs image into parition"
309
if [ "${img_type}" = "qcow2" ]; then
310
debug "Converting ${img} to QCOW2 format"
311
qemu-img convert -c -O qcow2 ${img} ${final_img} && rm "${img}" ||
312
fail "Failed to convert image to qcow format"
314
mv "${img}" "${final_img}" ||
315
fail "Unable to write ${final} from ${img}"
318
[ -e "${final_img}" ] && debug "Final image emitted to ${final_img}" ||
319
fail "Final image ${final} is missing; FATAL"