3 # Copyright (c) 2012, Intel Corporation.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 # the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # Modification from mkefidisk.sh provided by the Yocto project by Dominig
21 # to install Automotive Grade Linux (AGL) on
22 # Intel platforms equipped with the Automotive Linux Boot (ABL)
25 # Relies on the Intel iasImage tool to pakage the Kernel and the initrd in ABL format
29 # - keep initrd if present
30 # - does not allocate swap
31 # - accept .hddimg, wic and wic.xz as sources
36 # Set to 1 to enable additional output
43 # 100 Mb for the boot partition
45 # min available space on TMP_DIR for uncompressing xz image in kB e.g. 5G (5000000)
47 # TMP_DIR directory use for holding image file for uncompression (e.g. /tmp or $HOME)
50 MRB_DEBUG_TTY="ttyS2,115200n8"
54 IAS_EXE="ias_image_app"
55 IAS_CMD_LINE=/tmp/iasCommandLine.cmd
59 debug "Syncing and unmounting devices"
60 # Unmount anything we mounted
61 unmount $ROOTFS_MNT || error "Failed to unmount $ROOTFS_MNT"
62 unmount $BOOTFS_MNT || error "Failed to unmount $BOOTFS_MNT"
63 unmount $HDDIMG_ROOTFS_MNT || error "Failed to unmount $HDDIMG_ROOTFS_MNT"
64 unmount $HDDIMG_MNT || error "Failed to unmount $HDDIMG_MNT"
65 if [ "$IMG_TYPE" = "DISK" ]; then
66 debug "de-attaching loop devices"
67 for LOOP_DEVICE in `losetup --list |grep $HDDIMG | cut -d" " -f1` ; do
68 losetup -d $LOOP_DEVICE 1>&3 2>&1 || error "Detaching $LOOP_DEVICE from $HDDIMG failled"
72 debug "Removing temporary files"
73 if [ -d "$TMPDIR" ]; then
74 rm -rf $TMPDIR || error "Failed to remove $TMPDIR"
76 [ -f "$TMP_DIR/TMP-AGL-wic-image.wic" ] || rm -f $TMP_DIR/TMP-AGL-wic-image.wic
79 trap 'die "Signal Received, Aborting..."' HUP INT TERM
86 RED="$(tput setaf 1)$(tput bold)"
87 GREEN="$(tput setaf 2)$(tput bold)"
88 YELLOW="$(tput setaf 3)$(tput bold)"
90 echo "${INFO}$1${CLEAR}"
94 echo "${RED}$1${CLEAR}"
97 WARNINGS=$((WARNINGS+1))
98 echo "${YELLOW}$1${CLEAR}"
101 echo "${GREEN}$1${CLEAR}"
109 if [ $DEBUG -eq 1 ]; then
115 echo "Install AGL on a removable device to boot ABL based computer"
116 echo "ABL on the target must accept non signed development Linux kernel"
117 echo "In particular is can create USB or SD bootable support for Intel MRB"
119 echo "Usage: $(basename $0) [-v] [-p path_to_iasImage_tool] HDDIMG REMOVABLE_DEVICE"
120 echo " -v: Verbose debug"
121 echo " path_to_iasImage_tool: path the iasImage tool provided by Intel."
122 echo " HDDIMG: The hddimg file to generate the efi disk from"
123 echo " Supported formats are .hddimg, .wic .wic.xz"
124 echo " REMOVABLE_DEVICE: The block device to write the image to, e.g. /dev/sdh"
126 echo " mkabl-agl.sh agl-demo-platform-intel-corei7-64.wic.xz /dev/sdd"
127 echo " mkabl-agl.sh agl-demo-platform-intel-corei7-64.hddimg /dev/sdd"
129 echo " assuming that iasImage is accessible via your default path"
136 echo " image: $(stat --printf '%N\n' $IMG)"
137 echo " size: $(stat -L --printf '%s bytes\n' $IMG)"
138 echo " modified: $(stat -L --printf '%y\n' $IMG)"
139 echo " type: $(file -L -b $IMG)"
147 info "Device details"
148 echo " device: $DEVICE"
149 if [ -f "/sys/class/block/$DEV/device/vendor" ]; then
150 echo " vendor: $(cat /sys/class/block/$DEV/device/vendor)"
152 echo " vendor: UNKOWN"
154 if [ -f "/sys/class/block/$DEV/device/model" ]; then
155 echo " model: $(cat /sys/class/block/$DEV/device/model)"
157 echo " model: UNKNOWN"
159 if [ -f "/sys/class/block/$DEV/size" ]; then
160 echo " size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes"
162 echo " size: UNKNOWN"
168 grep -q $DEVICE /proc/mounts
169 if [ $? -eq 0 ]; then
170 warn "$DEVICE listed in /proc/mounts, attempting to unmount"
171 umount $DEVICE* 2>/dev/null
172 ! grep -q $DEVICE /proc/mounts && info "Unmounted successfully"
179 if [ "$1" = "" ] ; then
182 grep -q $1 /proc/mounts
183 if [ $? -eq 0 ]; then
184 debug "Unmounting $1"
186 ! grep -q $1 /proc/mounts # check if unmounted successfully
193 # Parse and validate arguments
196 if [ "$1" = "-v" ] ; then
202 if [ "$1" = "-p" ] ; then
207 if [ $# -ne 2 ]; then
211 IAS_IMAGE_TOOL="$IAS_PATH$IAS_EXE"
212 debug "iasImage tool is: $IAS_IMAGE_TOOL"
213 which $IAS_IMAGE_TOOL > IAS_IMAGE_TOOL_PATH
214 if [ ! -x "$(command -v $IAS_IMAGE_TOOL)" ]; then
215 die "$IAS_IMAGE_TOOL not found pointed by the path via 'sudo; use -p option'"
221 LINK=$(readlink $DEVICE)
222 if [ $? -eq 0 ]; then
226 if [ ! -w "$DEVICE" ]; then
227 if [ ! -e "${DEVICE}" ] ; then
228 die "Device $DEVICE cannot be found"
230 die "Device $DEVICE is not writable (need to run under sudo?)"
234 if [ ! -e "$HDDIMG" ]; then
235 die "HDDIMG $HDDIMG does not exist"
237 HDDIMG_EXT=${HDDIMG##*.}
242 debug "Detected: uncompressed image type .hddimg"
247 debug "Detected: uncompressed image type .wic"
252 debug "Detected: xz compressed image type .wic"
253 command -v xz >/dev/null 2>&1 || { die "xz command is not available, pleaes install xz package"; }
254 TMP_SIZE=`df -k $TMP_DIR | awk '/[0-9]%/{print $(NF-2)}'`
255 if [ "$TMP_SIZE" -lt "$TMP_SIZE_MIN" ]; then
256 die "Available space on $TMP_DIR must be at least $TMP_SIZE_MIN kB"
258 printf "Starting decompression of the image. It may take some time ..."
259 xz --decompress --keep --format=auto --force --threads=0 --stdout > $TMP_DIR/TMP-AGL-wic-image.wic $HDDIMG|| \
260 die "xz command failled: xz --decompress --keep --format=auto --force --threads=0 --stdout > $TMP_DIR/TMP-AGL-wic-image.wic"
261 HDDIMG="$TMP_DIR/TMP-AGL-wic-image.wic"
262 echo "Image uncompressed, starting doing real work ..."
265 die "Unsupported image format: $HDDIMG_EXT Supported format are .hddimg .wic wic.xz"
269 # Ensure the hddimg is not mounted
271 debug "will now try to umount /detach previous images"
274 unmount "$HDDIMG" || die "Failed to unmount $HDDIMG"
277 [ `losetup --list |grep $HDDIMG | wc -l ` -gt 1 ] && die "Image mounted more than once, manual cleaning required see: losetup --list"
278 debug "ready to attach the wic image to aloop device"
279 LOOP_DEVICE=`losetup --find --show $HDDIMG` && ( losetup -d $LOOP_DEVICE 1>&3 2>&1 || die "Detaching $LOOP_DEVICE from $HDDIMG failled")
282 die "unknown image format $IMG_TYPE"
286 # Check if any $DEVICE partitions are mounted
288 unmount_device || die "Failed to unmount $DEVICE"
291 # Confirm device with user
293 image_details $HDDIMG
294 device_details $(basename $DEVICE)
295 echo -n "${INFO}Prepare ABL image on $DEVICE [y/N]?${CLEAR} "
297 if [ "$RESPONSE" != "y" ]; then
298 echo "Image creation aborted"
304 # Prepare the temporary working space
306 TMPDIR=$(mktemp -d mkabldisk-XXX) || die "Failed to create temporary mounting directory."
307 HDDIMG_MNT=$TMPDIR/hddimg
308 debug "TEMPDIR is: $TMPDIR"
309 HDDIMG_ROOTFS_MNT=$TMPDIR/hddimg_rootfs
310 ROOTFS_MNT=$TMPDIR/rootfs
311 BOOTFS_MNT=$TMPDIR/bootfs
312 mkdir $HDDIMG_MNT || die "Failed to create $HDDIMG_MNT"
313 mkdir $HDDIMG_ROOTFS_MNT || die "Failed to create $HDDIMG_ROOTFS_MNT"
314 mkdir $ROOTFS_MNT || die "Failed to create $ROOTFS_MNT"
315 mkdir $BOOTFS_MNT || die "Failed to create $BOOTFS_MNT"
321 DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
322 # If the device size is not reported there may not be a valid label
323 if [ "$DEVICE_SIZE" = "" ] ; then
324 parted -s $DEVICE mklabel msdos || die "Failed to create MSDOS partition table"
325 DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
327 ROOTFS_SIZE=$((DEVICE_SIZE-BOOT_SIZE))
328 ROOTFS_START=$((BOOT_SIZE))
329 ROOTFS_END=$((ROOTFS_START+ROOTFS_SIZE))
331 # MMC devices use a partition prefix character 'p'
333 if [ ! "${DEVICE#/dev/mmcblk}" = "${DEVICE}" ] || [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then
336 BOOTFS=$DEVICE${PART_PREFIX}1
337 ROOTFS=$DEVICE${PART_PREFIX}2
339 TARGET_PART_PREFIX=""
340 if [ ! "${TARGET_DEVICE#/dev/mmcblk}" = "${TARGET_DEVICE}" ]; then
341 TARGET_PART_PREFIX="p"
343 TARGET_ROOTFS=$TARGET_DEVICE${TARGET_PART_PREFIX}2
346 info "Boot partition size: $BOOT_SIZE MB ($BOOTFS)"
347 info "ROOTFS partition size: $ROOTFS_SIZE MB ($ROOTFS)"
350 # Use MSDOS by default as GPT cannot be reliably distributed in disk image form
351 # as it requires the backup table to be on the last block of the device, which
352 # of course varies from device to device.
354 info "Partitioning installation media ($DEVICE)"
356 debug "Deleting partition table on $DEVICE"
357 dd if=/dev/zero of=$DEVICE bs=512 count=2 1>&3 2>&1 || die "Failed to zero beginning of $DEVICE"
359 debug "Creating new partition table (MSDOS) on $DEVICE"
360 parted -s $DEVICE mklabel msdos 1>&3 2>&1 || die "Failed to create MSDOS partition table"
362 debug "Creating boot partition on $BOOTFS"
363 parted -s $DEVICE mkpart primary 0% $BOOT_SIZE 1>&3 2>&1 || die "Failed to create BOOT partition"
365 debug "Enabling boot flag on $BOOTFS"
366 parted -s $DEVICE set 1 boot on 1>&3 2>&1 || die "Failed to enable boot flag"
368 debug "Creating ROOTFS partition on $ROOTFS"
369 parted -s $DEVICE mkpart primary $ROOTFS_START $ROOTFS_END 1>&3 2>&1 || die "Failed to create ROOTFS partition"
371 # as blkid does not provide PARTUUID on Ubuntu LTS 14.04 we myst hack via fdisk
372 #ROOTFS_PARTUUID=$(blkid |grep -e "$ROOTFS" |sed -n 's/^.*PARTUUID=/PARTUUID=/p')
374 ROOTFS_DISKID=$(fdisk -l "$DEVICE" | grep -e "Disk identifier" | sed -n 's/^.*Disk identifier: 0x/PARTUUID=/p')
375 if [ $ROOTFS_DISKID = "" ]; then
376 die "Failed to read DISKID"
378 ROOTFS_PARTUUID="$ROOTFS_DISKID-02"
379 debug "PARTUUID for ROOTFS is $ROOTFS_PARTUUID"
381 if [ $DEBUG -eq 1 ]; then
382 parted -s $DEVICE print
387 # Check if any $DEVICE partitions are mounted after partitioning
389 unmount_device || die "Failed to unmount $DEVICE partitions"
393 # Format $DEVICE partitions
395 info "Formatting partitions"
396 debug "Formatting $BOOTFS as ext2"
397 mkfs.ext2 -F -F -L BOOT $BOOTFS 1>&3 2>&1 || die "Failed to format $BOOTFS"
399 debug "Formatting $ROOTFS as ext4"
400 mkfs.ext4 -F $ROOTFS -L "ROOT" 1>&3 2>&1 || die "Failed to format $ROOTFS"
403 # Mounting image file system on loop devices
408 debug "Mounting images and device in preparation for installation"
409 mount -o loop $HDDIMG $HDDIMG_MNT 1>&3 2>&1 || die "Failed to mount $HDDIMG"
410 mount -o loop $HDDIMG_MNT/rootfs.img $HDDIMG_ROOTFS_MNT 1>&3 2>&1 || die "Failed to mount rootfs.img"
413 debug "Attaching image and mounting partitions then device in preparation for installation"
414 LOOP_DEVICE=`losetup --find` || die "Failled to find an available loop device see: losetup --find"
415 losetup -P $LOOP_DEVICE $HDDIMG 1>&3 2>&1 || die "Attaching $LOOP_DEVICE from $HDDIMG failled"
416 mount "$LOOP_DEVICE"p2 $HDDIMG_ROOTFS_MNT 1>&3 2>&1 || die "Failed to mount $LOOP_DEVICEp1 on $HDDIMG_ROOTFS_MNT"
417 mount "$LOOP_DEVICE"p1 $HDDIMG_MNT 1>&3 2>&1 || die "Failed to mount $LOOP_DEVICEp2 on $HDDIMG_MNT"
420 die "unknown image format $IMG_TYPE"
424 mount $ROOTFS $ROOTFS_MNT 1>&3 2>&1 || die "Failed to mount $ROOTFS on $ROOTFS_MNT"
425 mount $BOOTFS $BOOTFS_MNT 1>&3 2>&1 || die "Failed to mount $BOOTFS on $BOOTFS_MNT"
427 info "Preparing boot partition"
428 # create the config file for iasImage
429 # Remove any existing root= kernel parameters and:
430 # o Add a root= parameter with the target rootfs
431 # o Specify ro so fsck can be run during boot
432 # o Specify rootwait in case the target media is an asyncronous block device
433 # such as MMC or USB disks
434 # o Specify "quiet" to minimize boot time when using slow serial consoles
436 # iasImage command line file creation
437 echo "root=$ROOTFS_PARTUUID" > $IAS_CMD_LINE
438 echo "console=$MRB_DEBUG_TTY" >> $IAS_CMD_LINE
439 echo "earlycon=uart8250,mmio32,0xfc000000,115200n8" >> $IAS_CMD_LINE
440 echo "rootwait" >> $IAS_CMD_LINE
441 echo "video=$MRB_HDMI" >> $IAS_CMD_LINE
442 echo "i915.enable_initial_modeset=1" >> $IAS_CMD_LINE
443 debug "temp config for iasImage is $IAS_CMD_LINE"
445 if [ -f $HDDIMG_MNT/vmlinuz ]; then
446 KERNEL_TYPE="vmlinuz"
447 debug "kernel is vmlinuz"
449 if [ -f $HDDIMG_MNT/bzimage ]; then
450 KERNEL_TYPE="bzimage"
451 debug "kernel is bzimage -> vmlinuz"
453 if [ -f $HDDIMG_MNT/microcode.cpio ]; then
454 die "initrd=microcode.cpio is not a supported configuration, change ycoto configuration or use an hddimg as source"
456 [ -z $KERNEL_TYPE ] && die "Linux kernel type in $HDDIMG is unsupported"
458 if [ -f $HDDIMG_MNT/initrd ];
460 info "creating ABL image with initramsfs"
461 debug "$IAS_IMAGE_TOOL -o $BOOTFS_MNT/iasImage -i 0x30000 $IAS_CMD_LINE $HDDIMG_MNT/$KERNEL_TYPE $HDDIMG_MNT/initrd"
462 $IAS_IMAGE_TOOL -o $BOOTFS_MNT/iasImage -i 0x30000 $IAS_CMD_LINE $HDDIMG_MNT/$KERNEL_TYPE $HDDIMG_MNT/initrd
464 info "creating ABL image without initramfs"
465 debug "$IAS_IMAGE_TOOL -o $BOOTFS_MNT/iasImage -i 0x30000 $IAS_CMD_LINE $HDDIMG_MNT/$KERNEL_TYPE"
466 $IAS_IMAGE_TOOL -o $BOOTFS_MNT/iasImage -i 0x30000 $IAS_CMD_LINE $HDDIMG_MNT/$KERNEL_TYPE
469 printf "Copying ROOTFS files ... "
470 command -v rsync >/dev/null 2>&1 # check if rsync exists
471 if [ $DEBUG -eq 1 ] && [ $? -eq 0 ]; then
472 rsync --info=progress2 -h -aHAXW --no-compress $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT 1>&3 2>&1 || die "Root FS copy failed"
474 cp -a $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT 1>&3 2>&1 || die "Root FS copy failed"
477 debug "removing any swap entry in /etc/fstab"
478 sed --in-place '/swap/d' $ROOTFS_MNT/etc/fstab
480 printf "flushing data on removable device. May take a while ... "
481 sync --file-system $ROOTFS_MNT
484 # We dont want udev to mount our root device while we're booting...
485 if [ -d $ROOTFS_MNT/etc/udev/ ] ; then
486 echo "$TARGET_DEVICE" >> $ROOTFS_MNT/etc/udev/mount.blacklist
490 # Call cleanup to unmount devices and images and remove the TMPDIR
494 if [ $WARNINGS -ne 0 ] && [ $ERRORS -eq 0 ]; then
495 echo "${YELLOW}Installation completed with warnings${CLEAR}"
496 echo "${YELLOW}Warnings: $WARNINGS${CLEAR}"
497 elif [ $ERRORS -ne 0 ]; then
498 echo "${RED}Installation encountered errors${CLEAR}"
499 echo "${RED}Errors: $ERRORS${CLEAR}"
500 echo "${YELLOW}Warnings: $WARNINGS${CLEAR}"
502 success "Installation completed successfully"