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 BOOTFS_PARTUUID="$ROOTFS_DISKID-01"
379 ROOTFS_PARTUUID="$ROOTFS_DISKID-02"
380 debug "PARTUUID for ROOTFS is $ROOTFS_PARTUUID"
382 if [ $DEBUG -eq 1 ]; then
383 parted -s $DEVICE print
388 # Check if any $DEVICE partitions are mounted after partitioning
390 unmount_device || die "Failed to unmount $DEVICE partitions"
394 # Format $DEVICE partitions
396 info "Formatting partitions"
397 debug "Formatting $BOOTFS as ext2"
398 mkfs.ext2 -F -F -L BOOT $BOOTFS 1>&3 2>&1 || die "Failed to format $BOOTFS"
400 debug "Formatting $ROOTFS as ext4"
401 mkfs.ext4 -F $ROOTFS -L "ROOT" 1>&3 2>&1 || die "Failed to format $ROOTFS"
404 # Mounting image file system on loop devices
409 debug "Mounting images and device in preparation for installation"
410 mount -o loop $HDDIMG $HDDIMG_MNT 1>&3 2>&1 || die "Failed to mount $HDDIMG"
411 mount -o loop $HDDIMG_MNT/rootfs.img $HDDIMG_ROOTFS_MNT 1>&3 2>&1 || die "Failed to mount rootfs.img"
414 debug "Attaching image and mounting partitions then device in preparation for installation"
415 LOOP_DEVICE=`losetup --find` || die "Failled to find an available loop device see: losetup --find"
416 losetup -P $LOOP_DEVICE $HDDIMG 1>&3 2>&1 || die "Attaching $LOOP_DEVICE from $HDDIMG failled"
417 mount "$LOOP_DEVICE"p2 $HDDIMG_ROOTFS_MNT 1>&3 2>&1 || die "Failed to mount $LOOP_DEVICEp1 on $HDDIMG_ROOTFS_MNT"
418 mount "$LOOP_DEVICE"p1 $HDDIMG_MNT 1>&3 2>&1 || die "Failed to mount $LOOP_DEVICEp2 on $HDDIMG_MNT"
421 die "unknown image format $IMG_TYPE"
425 mount $ROOTFS $ROOTFS_MNT 1>&3 2>&1 || die "Failed to mount $ROOTFS on $ROOTFS_MNT"
426 mount $BOOTFS $BOOTFS_MNT 1>&3 2>&1 || die "Failed to mount $BOOTFS on $BOOTFS_MNT"
428 info "Preparing boot partition"
429 # create the config file for iasImage
430 # Remove any existing root= kernel parameters and:
431 # o Add a root= parameter with the target rootfs
432 # o Specify ro so fsck can be run during boot
433 # o Specify rootwait in case the target media is an asyncronous block device
434 # such as MMC or USB disks
435 # o Specify "quiet" to minimize boot time when using slow serial consoles
437 # iasImage command line file creation
438 echo "root=$ROOTFS_PARTUUID" > $IAS_CMD_LINE
439 echo "console=$MRB_DEBUG_TTY" >> $IAS_CMD_LINE
440 echo "earlycon=uart8250,mmio32,0xfc000000,115200n8" >> $IAS_CMD_LINE
441 echo "rootwait" >> $IAS_CMD_LINE
442 echo "video=$MRB_HDMI" >> $IAS_CMD_LINE
443 echo "i915.enable_initial_modeset=1" >> $IAS_CMD_LINE
444 debug "temp config for iasImage is $IAS_CMD_LINE"
446 if [ -f $HDDIMG_MNT/vmlinuz ]; then
447 KERNEL_TYPE="vmlinuz"
448 debug "kernel is vmlinuz"
450 if [ -f $HDDIMG_MNT/bzimage ]; then
451 KERNEL_TYPE="bzimage"
452 debug "kernel is bzimage -> vmlinuz"
454 if [ -f $HDDIMG_MNT/microcode.cpio ]; then
455 warn "initrd=microcode.cpio is not a supported configuration, microcode.cpio has been ignored"
457 [ -z $KERNEL_TYPE ] && die "Linux kernel type in $HDDIMG is unsupported"
459 if [ -f $HDDIMG_MNT/initrd ];
461 info "creating ABL image with initramsfs"
462 debug "$IAS_IMAGE_TOOL -o $BOOTFS_MNT/iasImage -i 0x30000 $IAS_CMD_LINE $HDDIMG_MNT/$KERNEL_TYPE $HDDIMG_MNT/initrd"
463 $IAS_IMAGE_TOOL -o $BOOTFS_MNT/iasImage -i 0x30000 $IAS_CMD_LINE $HDDIMG_MNT/$KERNEL_TYPE $HDDIMG_MNT/initrd
465 info "creating ABL image without initramfs"
466 debug "$IAS_IMAGE_TOOL -o $BOOTFS_MNT/iasImage -i 0x30000 $IAS_CMD_LINE $HDDIMG_MNT/$KERNEL_TYPE"
467 $IAS_IMAGE_TOOL -o $BOOTFS_MNT/iasImage -i 0x30000 $IAS_CMD_LINE $HDDIMG_MNT/$KERNEL_TYPE
470 printf "Copying ROOTFS files ... "
471 command -v rsync >/dev/null 2>&1 # check if rsync exists
472 if [ $DEBUG -eq 1 ] && [ $? -eq 0 ]; then
473 rsync --info=progress2 -h -aHAXW --no-compress $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT 1>&3 2>&1 || die "Root FS copy failed"
475 cp -a $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT 1>&3 2>&1 || die "Root FS copy failed"
478 debug "removing any swap entry in /etc/fstab"
479 sed --in-place '/swap/d' $ROOTFS_MNT/etc/fstab
480 debug "fixing PARTUUID for /boot"
481 sed --in-place -e "s#PARTUUID=[0-9a-z-]\+\t/boot#${BOOTFS_PARTUUID}\t/boot#" $ROOTFS_MNT/etc/fstab
483 printf "flushing data on removable device. May take a while ... "
484 sync --file-system $ROOTFS_MNT
487 # We dont want udev to mount our root device while we're booting...
488 if [ -d $ROOTFS_MNT/etc/udev/ ] ; then
489 echo "$TARGET_DEVICE" >> $ROOTFS_MNT/etc/udev/mount.blacklist
493 # Call cleanup to unmount devices and images and remove the TMPDIR
497 if [ $WARNINGS -ne 0 ] && [ $ERRORS -eq 0 ]; then
498 echo "${YELLOW}Installation completed with warnings${CLEAR}"
499 echo "${YELLOW}Warnings: $WARNINGS${CLEAR}"
500 elif [ $ERRORS -ne 0 ]; then
501 echo "${RED}Installation encountered errors${CLEAR}"
502 echo "${RED}Errors: $ERRORS${CLEAR}"
503 echo "${YELLOW}Warnings: $WARNINGS${CLEAR}"
505 success "Installation completed successfully"