Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 #!/bin/bash | 1 #!/bin/bash | 
| 2 | 2 | 
| 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be | 
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. | 
| 6 | 6 | 
| 7 # Script to build a bootable keyfob-based chromeos system image from within | 7 # Script to build a bootable keyfob-based chromeos system image from within | 
| 8 # a chromiumos setup. This assumes that all needed packages have been built into | 8 # a chromiumos setup. This assumes that all needed packages have been built into | 
| 9 # the given target's root with binary packages turned on. This script will | 9 # the given target's root with binary packages turned on. This script will | 
| 10 # build the Chrome OS image using only pre-built binary packages. | 10 # build the Chrome OS image using only pre-built binary packages. | 
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 DEFINE_integer verity_depth 1 \ | 77 DEFINE_integer verity_depth 1 \ | 
| 78 "Kernel verified boot hash tree depth. Default: 1" | 78 "Kernel verified boot hash tree depth. Default: 1" | 
| 79 DEFINE_integer verity_max_ios -1 \ | 79 DEFINE_integer verity_max_ios -1 \ | 
| 80 "Number of outstanding I/O operations dm-verity caps at. Default: -1" | 80 "Number of outstanding I/O operations dm-verity caps at. Default: -1" | 
| 81 DEFINE_string verity_algorithm "sha1" \ | 81 DEFINE_string verity_algorithm "sha1" \ | 
| 82 "Cryptographic hash algorithm used for kernel vboot. Default : sha1" | 82 "Cryptographic hash algorithm used for kernel vboot. Default : sha1" | 
| 83 | 83 | 
| 84 DEFINE_string oem_customization "" \ | 84 DEFINE_string oem_customization "" \ | 
| 85 "Path to directory containing OEM partner partition contents" | 85 "Path to directory containing OEM partner partition contents" | 
| 86 | 86 | 
| 87 DEFINE_string base_image "" \ | |
| 88 "Path to base image for which this image will be derived from" | |
| 89 DEFINE_boolean zero_freespace ${FLAGS_FALSE} \ | |
| 
 
petkov
2010/12/10 18:33:30
any downside in defaulting this to TRUE?
 
 | |
| 90 "Zeroes the freespace to improve compression for delta updates" | |
| 91 | |
| 87 # Parse command line. | 92 # Parse command line. | 
| 88 FLAGS "$@" || exit 1 | 93 FLAGS "$@" || exit 1 | 
| 89 eval set -- "${FLAGS_ARGV}" | 94 eval set -- "${FLAGS_ARGV}" | 
| 90 | 95 | 
| 91 # Only now can we die on error. shflags functions leak non-zero error codes, | 96 # Only now can we die on error. shflags functions leak non-zero error codes, | 
| 92 # so will die prematurely if 'set -e' is specified before now. | 97 # so will die prematurely if 'set -e' is specified before now. | 
| 93 set -e | 98 set -e | 
| 94 | 99 | 
| 95 if [ -z "${FLAGS_board}" ] ; then | 100 if [ -z "${FLAGS_board}" ] ; then | 
| 96 error "--board is required." | 101 error "--board is required." | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 121 [ "${FLAGS_dev_install}" -eq "${FLAGS_TRUE}" ] ; then | 126 [ "${FLAGS_dev_install}" -eq "${FLAGS_TRUE}" ] ; then | 
| 122 die "Incompatible flags: --factory_install and --dev_install cannot be \ | 127 die "Incompatible flags: --factory_install and --dev_install cannot be \ | 
| 123 both set to True. Please specify one or none." | 128 both set to True. Please specify one or none." | 
| 124 fi | 129 fi | 
| 125 | 130 | 
| 126 INSTALL_MASK="" | 131 INSTALL_MASK="" | 
| 127 if [ "${FLAGS_installmask}" -eq "${FLAGS_TRUE}" ] ; then | 132 if [ "${FLAGS_installmask}" -eq "${FLAGS_TRUE}" ] ; then | 
| 128 INSTALL_MASK="${DEFAULT_INSTALL_MASK}" | 133 INSTALL_MASK="${DEFAULT_INSTALL_MASK}" | 
| 129 fi | 134 fi | 
| 130 | 135 | 
| 136 # Make sure base image exists before we go too far | |
| 137 if [ ! -z "${FLAGS_base_image}" ] && [ ! -f "${FLAGS_base_image}" ] ; then | |
| 
 
petkov
2010/12/10 18:33:30
if [ -n "${FLAGS_base_image}" ] ...
 
sosa
2010/12/10 19:28:10
-n instead of ! -z
 
 | |
| 138 die "Cannot find base image ${FLAGS_base_image}" | |
| 139 fi | |
| 140 | |
| 131 # Reduce the size of factory install shim. | 141 # Reduce the size of factory install shim. | 
| 132 if [ "${FLAGS_factory_install}" -eq "${FLAGS_TRUE}" ] || | 142 if [ "${FLAGS_factory_install}" -eq "${FLAGS_TRUE}" ] || | 
| 133 [ "${FLAGS_dev_install}" -eq "${FLAGS_TRUE}" ] ; then | 143 [ "${FLAGS_dev_install}" -eq "${FLAGS_TRUE}" ] ; then | 
| 134 # Disable --withdev flag when --*_install is set to True. Otherwise, the | 144 # Disable --withdev flag when --*_install is set to True. Otherwise, the | 
| 135 # dev image produced will be based on install shim, rather than a pristine | 145 # dev image produced will be based on install shim, rather than a pristine | 
| 136 # image | 146 # image | 
| 137 if [ "${FLAGS_withdev}" -eq "${FLAGS_TRUE}" ]; then | 147 if [ "${FLAGS_withdev}" -eq "${FLAGS_TRUE}" ]; then | 
| 138 info "Incompatible flags: --withdev and --dev_install or --factory_install \ | 148 info "Incompatible flags: --withdev and --dev_install or --factory_install \ | 
| 139 cannot be both set to True. Reset --withdev to False." | 149 cannot be both set to True. Reset --withdev to False." | 
| 140 FLAGS_withdev=${FLAGS_FALSE} | 150 FLAGS_withdev=${FLAGS_FALSE} | 
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 STATEFUL_FS_DIR="${OUTPUT_DIR}/stateful_partition" | 228 STATEFUL_FS_DIR="${OUTPUT_DIR}/stateful_partition" | 
| 219 | 229 | 
| 220 OEM_FS_IMG="${OUTPUT_DIR}/partner_partition.image" | 230 OEM_FS_IMG="${OUTPUT_DIR}/partner_partition.image" | 
| 221 OEM_FS_DIR="${OUTPUT_DIR}/partner_partition" | 231 OEM_FS_DIR="${OUTPUT_DIR}/partner_partition" | 
| 222 | 232 | 
| 223 ESP_FS_IMG=${OUTPUT_DIR}/esp.image | 233 ESP_FS_IMG=${OUTPUT_DIR}/esp.image | 
| 224 ESP_FS_DIR=${OUTPUT_DIR}/esp | 234 ESP_FS_DIR=${OUTPUT_DIR}/esp | 
| 225 | 235 | 
| 226 DEVKEYSDIR="/usr/share/vboot/devkeys" | 236 DEVKEYSDIR="/usr/share/vboot/devkeys" | 
| 227 | 237 | 
| 238 NEW_ROOT_FS=${OUTPUT_DIR}/new.image | |
| 239 NEW_ROOT_FS_DIR=/tmp/mnew | |
| 
 
sosa
2010/12/10 19:28:10
Create a temp dir ... why use the same one everyti
 
 | |
| 240 | |
| 228 LOOP_DEV= | 241 LOOP_DEV= | 
| 229 STATEFUL_LOOP_DEV= | 242 STATEFUL_LOOP_DEV= | 
| 230 OEM_LOOP_DEV= | 243 OEM_LOOP_DEV= | 
| 231 ESP_LOOP_DEV= | 244 ESP_LOOP_DEV= | 
| 245 NEW_ROOT_FS_LOOP_DEV= | |
| 232 | 246 | 
| 233 # ${DEV_IMAGE_ROOT} specifies the location of where developer packages will | 247 # ${DEV_IMAGE_ROOT} specifies the location of where developer packages will | 
| 234 # be installed on the stateful dir. On a Chromium OS system, this will | 248 # be installed on the stateful dir. On a Chromium OS system, this will | 
| 235 # translate to /usr/local. | 249 # translate to /usr/local. | 
| 236 DEV_IMAGE_ROOT="${STATEFUL_FS_DIR}/dev_image" | 250 DEV_IMAGE_ROOT="${STATEFUL_FS_DIR}/dev_image" | 
| 237 | 251 | 
| 238 # What cross-build are we targeting? | 252 # What cross-build are we targeting? | 
| 239 . "${BOARD_ROOT}/etc/make.conf.board_setup" | 253 . "${BOARD_ROOT}/etc/make.conf.board_setup" | 
| 240 LIBC_VERSION=${LIBC_VERSION:-"2.10.1-r1"} | 254 LIBC_VERSION=${LIBC_VERSION:-"2.10.1-r1"} | 
| 241 | 255 | 
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 # Clean out unused packages | 510 # Clean out unused packages | 
| 497 sudo INSTALL_MASK="${INSTALL_MASK}" ${EMERGE_BOARD_CMD} \ | 511 sudo INSTALL_MASK="${INSTALL_MASK}" ${EMERGE_BOARD_CMD} \ | 
| 498 --root="${ROOT_FS_DIR}" --root-deps=rdeps \ | 512 --root="${ROOT_FS_DIR}" --root-deps=rdeps \ | 
| 499 --usepkgonly --depclean ${EMERGE_JOBS} | 513 --usepkgonly --depclean ${EMERGE_JOBS} | 
| 500 | 514 | 
| 501 trap - EXIT | 515 trap - EXIT | 
| 502 ${SCRIPTS_DIR}/mount_gpt_image.sh -u -r "${ROOT_FS_DIR}" \ | 516 ${SCRIPTS_DIR}/mount_gpt_image.sh -u -r "${ROOT_FS_DIR}" \ | 
| 503 -s "${STATEFUL_FS_DIR}" -e "${ESP_FS_DIR}" | 517 -s "${STATEFUL_FS_DIR}" -e "${ESP_FS_DIR}" | 
| 504 } | 518 } | 
| 505 | 519 | 
| 520 zero_rootfs_freespace() { | |
| 521 # Disable die on error so dd can write until EOF | |
| 
 
sosa
2010/12/10 19:28:10
Make this more function-y .. i.e. use $1 $2 etc
 
 | |
| 522 set +e | |
| 
 
sosa
2010/12/10 19:28:10
Don't set +e / -e ... use || instead on the dd lin
 
 | |
| 523 | |
| 524 local rootfs_dir=$1 | |
| 525 echo "Zeroing freespace" | |
| 526 sudo dd if=/dev/zero of="${rootfs_dir}/filler" 2>/dev/null | |
| 527 sudo rm "${rootfs_dir}/filler" | |
| 528 | |
| 529 set -e | |
| 530 } | |
| 531 | |
| 532 align_rootfs_cleanup() { | |
| 533 # Disable die on error. | |
| 534 set +e | |
| 535 | |
| 536 if [ -n "${NEW_ROOT_FS_LOOP_DEV}" ] ; then | |
| 537 sudo umount -d "${NEW_ROOT_FS_DIR}" | |
| 538 sudo rmdir "${NEW_ROOT_FS_DIR}" | |
| 539 NEW_ROOT_FS_LOOP_DEV= | |
| 540 fi | |
| 541 | |
| 542 # Turn die on error back on. | |
| 543 set -e | |
| 544 } | |
| 545 | |
| 546 align_rootfs() { | |
| 547 | |
| 548 echo "Aligning rootfs on-disk file layout to base image" | |
| 
 
sosa
2010/12/10 19:28:10
info
 
 | |
| 549 | |
| 550 # Extract rootfs from base image to output directory. | |
| 551 local rootfs_offset=$(partoffset "${FLAGS_base_image}" 3) | |
| 552 local rootfs_count=$(partsize "${FLAGS_base_image}" 3) | |
| 553 dd if="${FLAGS_base_image}" of="${NEW_ROOT_FS}" bs=512 conv=fsync \ | |
| 554 skip=${rootfs_offset} count=${rootfs_count} &> /dev/null | |
| 555 enable_rw_mount "${NEW_ROOT_FS}" | |
| 
 
sosa
2010/12/10 19:28:10
Why is this necessary?  Can't rw just be set in th
 
 | |
| 556 | |
| 557 # Mount the new image. | |
| 558 NEW_ROOT_FS_LOOP_DEV=$(sudo losetup -f) | |
| 
 
sosa
2010/12/10 19:28:10
Not sure you even have to do this rather than moun
 
 | |
| 559 if [ -z "${NEW_ROOT_FS_LOOP_DEV}" ] ; then | |
| 560 echo "No free loop device. Free up a loop device or reboot. exiting. " | |
| 561 exit 1 | |
| 562 fi | |
| 563 | |
| 564 sudo mkdir -p "${NEW_ROOT_FS_DIR}" | |
| 565 sudo losetup "${NEW_ROOT_FS_LOOP_DEV}" "${NEW_ROOT_FS}" | |
| 566 sudo mount "${NEW_ROOT_FS_LOOP_DEV}" "${NEW_ROOT_FS_DIR}" | |
| 567 | |
| 568 trap "align_rootfs_cleanup" EXIT | |
| 569 | |
| 570 # Temporarily make immutable files mutable. | |
| 571 immutable_files=() | |
| 
 
sosa
2010/12/10 19:28:10
local?
 
 | |
| 572 NEW_ROOT_FS_DIR_ESCAPED=$(echo "${NEW_ROOT_FS_DIR}" | sed 's/\//\\\//g') | |
| 
 
sosa
2010/12/10 19:28:10
Why global?
 
sosa
2010/12/10 19:28:10
Use a diff seperater in your sed than / to make th
 
 | |
| 573 local enum_files_cmd='sudo find "${NEW_ROOT_FS_DIR}" -xdev -type f' | |
| 
 
sosa
2010/12/10 19:28:10
Why exclude directories and such?
 
 | |
| 574 eval $enum_files_cmd | sed "s/${NEW_ROOT_FS_DIR_ESCAPED}//" | \ | |
| 
 
sosa
2010/12/10 19:28:10
{}
 
 | |
| 575 while read -r FILE ; do | |
| 576 immutable=$(sudo lsattr "${NEW_ROOT_FS_DIR}$FILE" | cut -d' ' -f1 | \ | |
| 
 
sosa
2010/12/10 19:28:10
shouldn't there be spaces in the cut
 
 | |
| 577 grep -q i ; echo $?) | |
| 578 if [ $immutable -eq 0 ] ; then | |
| 
 
sosa
2010/12/10 19:28:10
{}
 
sosa
2010/12/10 19:28:10
No spaces before ; same elsewhere
 
 | |
| 579 immutable_files=("${immutable_files[@]}" "${NEW_ROOT_FS_DIR}$FILE") | |
| 580 sudo chattr -i "${NEW_ROOT_FS_DIR}$FILE" | |
| 
 
sosa
2010/12/10 19:28:10
Little confused ... you set this immmutable twice
 
 | |
| 581 fi | |
| 582 done | |
| 583 | |
| 584 # Copy files over top of base image files to preserve file layout as much | |
| 585 # as possible. | |
| 
 
sosa
2010/12/10 19:28:10
Layout?  maybe metadata is more accurate
 
 | |
| 586 sudo rsync -a -H -A -x --force --inplace \ | |
| 587 "${ROOT_FS_DIR}/" "${NEW_ROOT_FS_DIR}" | |
| 588 | |
| 589 for FILE in ${immutable_files[*]} ; do | |
| 590 sudo chattr -i "${NEW_ROOT_FS_DIR}$FILE" | |
| 591 done | |
| 592 | |
| 593 # Zero out free space, this makes it more compressible leading to a smaller | |
| 594 # delta update. | |
| 595 if [ "${FLAGS_zero_freespace}" -eq "${FLAGS_TRUE}" ] ; then | |
| 596 zero_rootfs_freespace "${NEW_ROOT_FS_DIR}" | |
| 597 fi | |
| 598 | |
| 599 sudo umount -d "${NEW_ROOT_FS_DIR}" | |
| 600 sudo rmdir "${NEW_ROOT_FS_DIR}" | |
| 601 | |
| 602 trap - EXIT | |
| 603 } | |
| 604 | |
| 506 create_base_image() { | 605 create_base_image() { | 
| 507 local image_name=$1 | 606 local image_name=$1 | 
| 508 | 607 | 
| 509 trap "cleanup && delete_prompt" EXIT | 608 trap "cleanup && delete_prompt" EXIT | 
| 510 | 609 | 
| 511 # Create and format the root file system. | 610 # Create and format the root file system. | 
| 512 | 611 | 
| 513 # Check for loop device before creating image. | 612 # Check for loop device before creating image. | 
| 514 LOOP_DEV=$(sudo losetup -f) | 613 LOOP_DEV=$(sudo losetup -f) | 
| 515 if [ -z "${LOOP_DEV}" ] ; then | 614 if [ -z "${LOOP_DEV}" ] ; then | 
| 516 echo "No free loop device. Free up a loop device or reboot. exiting. " | 615 echo "No free loop device. Free up a loop device or reboot. exiting. " | 
| 517 exit 1 | 616 exit 1 | 
| 518 fi | 617 fi | 
| 519 | 618 | 
| 520 # Create root file system disk image. | 619 # Create root file system disk image. | 
| 521 ROOT_SIZE_BYTES=$((1024 * 1024 * ${FLAGS_rootfs_size})) | 620 ROOT_SIZE_BYTES=$((1024 * 1024 * ${FLAGS_rootfs_size})) | 
| 522 | 621 | 
| 523 # Pad out for the hash tree. | 622 # Pad out for the hash tree. | 
| 524 ROOT_HASH_PAD=$((FLAGS_rootfs_hash_pad * 1024 * 1024)) | 623 ROOT_HASH_PAD=$((FLAGS_rootfs_hash_pad * 1024 * 1024)) | 
| 525 info "Padding the rootfs image by ${ROOT_HASH_PAD} bytes for hash data" | 624 info "Padding the rootfs image by ${ROOT_HASH_PAD} bytes for hash data" | 
| 526 | 625 | 
| 527 dd if=/dev/zero of="${ROOT_FS_IMG}" bs=1 count=1 \ | 626 dd if=/dev/zero of="${ROOT_FS_IMG}" bs=1 count=1 \ | 
| 528 seek=$((ROOT_SIZE_BYTES + ROOT_HASH_PAD - 1)) | 627 seek=$((ROOT_SIZE_BYTES + ROOT_HASH_PAD - 1)) | 
| 529 sudo losetup "${LOOP_DEV}" "${ROOT_FS_IMG}" | 628 sudo losetup "${LOOP_DEV}" "${ROOT_FS_IMG}" | 
| 530 # Specify a block size and block count to avoid using the hash pad. | 629 # Specify a block size and block count to avoid using the hash pad. | 
| 531 sudo mkfs.ext2 -b 4096 "${LOOP_DEV}" "$((ROOT_SIZE_BYTES / 4096))" | 630 sudo mkfs.ext2 -O ^has_journal -b 4096 "${LOOP_DEV}" "$((ROOT_SIZE_BYTES / 409 6))" | 
| 532 | 631 | 
| 533 # Tune and mount rootfs. | 632 # Tune and mount rootfs. | 
| 534 DISK_LABEL="C-ROOT" | 633 DISK_LABEL="C-ROOT" | 
| 535 # Disable checking and minimize metadata differences across builds | 634 # Disable checking and minimize metadata differences across builds | 
| 536 # and wasted reserved space. | 635 # and wasted reserved space. | 
| 537 sudo tune2fs -L "${DISK_LABEL}" \ | 636 sudo tune2fs -L "${DISK_LABEL}" \ | 
| 538 -U clear \ | 637 -U clear \ | 
| 539 -T 20091119110000 \ | 638 -T 20091119110000 \ | 
| 540 -c 0 \ | 639 -c 0 \ | 
| 541 -i 0 \ | 640 -i 0 \ | 
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 setup_symlinks_on_root "/usr/local" "/var" "${STATEFUL_FS_DIR}" | 775 setup_symlinks_on_root "/usr/local" "/var" "${STATEFUL_FS_DIR}" | 
| 677 | 776 | 
| 678 # cros_make_image_bootable will clobber vmlinuz.image for x86. | 777 # cros_make_image_bootable will clobber vmlinuz.image for x86. | 
| 679 # Until then, just copy the kernel to vmlinuz.image. It is | 778 # Until then, just copy the kernel to vmlinuz.image. It is | 
| 680 # expected in build_gpt.sh. | 779 # expected in build_gpt.sh. | 
| 681 cp "${ROOT_FS_DIR}/boot/vmlinuz" "${OUTPUT_DIR}/vmlinuz.image" | 780 cp "${ROOT_FS_DIR}/boot/vmlinuz" "${OUTPUT_DIR}/vmlinuz.image" | 
| 682 | 781 | 
| 683 # Create an empty esp image to be updated in by update_bootloaders.sh. | 782 # Create an empty esp image to be updated in by update_bootloaders.sh. | 
| 684 ${SCRIPTS_DIR}/create_esp.sh --to="${ESP_FS_IMG}" | 783 ${SCRIPTS_DIR}/create_esp.sh --to="${ESP_FS_IMG}" | 
| 685 | 784 | 
| 785 # Align the rootfs to the previous if there's a base image to align to | |
| 786 if [ -n "${FLAGS_base_image}" ] ; then | |
| 787 align_rootfs | |
| 788 fi | |
| 789 | |
| 686 cleanup | 790 cleanup | 
| 687 | 791 | 
| 792 # Copy new aligned image over to of rootfs.img | |
| 793 if [ -n "${FLAGS_base_image}" ] ; then | |
| 794 rm "${ROOT_FS_IMG}" | |
| 795 mv "${NEW_ROOT_FS}" "${ROOT_FS_IMG}" | |
| 796 fi | |
| 797 | |
| 688 trap delete_prompt EXIT | 798 trap delete_prompt EXIT | 
| 689 | 799 | 
| 690 # Create the GPT-formatted image. | 800 # Create the GPT-formatted image. | 
| 691 ${SCRIPTS_DIR}/build_gpt.sh \ | 801 ${SCRIPTS_DIR}/build_gpt.sh \ | 
| 692 --arch=${ARCH} \ | 802 --arch=${ARCH} \ | 
| 693 --board=${FLAGS_board} \ | 803 --board=${FLAGS_board} \ | 
| 694 --rootfs_partition_size=${FLAGS_rootfs_partition_size} \ | 804 --rootfs_partition_size=${FLAGS_rootfs_partition_size} \ | 
| 695 "${OUTPUT_DIR}" \ | 805 "${OUTPUT_DIR}" \ | 
| 696 "${OUTPUT_DIR}/${image_name}" | 806 "${OUTPUT_DIR}/${image_name}" | 
| 697 | 807 | 
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 792 echo "Developer image created as ${DEVELOPER_IMAGE_NAME}" | 902 echo "Developer image created as ${DEVELOPER_IMAGE_NAME}" | 
| 793 fi | 903 fi | 
| 794 | 904 | 
| 795 print_time_elapsed | 905 print_time_elapsed | 
| 796 | 906 | 
| 797 echo "To copy to USB keyfob, do something like:" | 907 echo "To copy to USB keyfob, do something like:" | 
| 798 echo " ./image_to_usb.sh --from=${OUTSIDE_OUTPUT_DIR} --to=/dev/sdX" | 908 echo " ./image_to_usb.sh --from=${OUTSIDE_OUTPUT_DIR} --to=/dev/sdX" | 
| 799 echo "To convert to VMWare image, INSIDE the chroot, do something like:" | 909 echo "To convert to VMWare image, INSIDE the chroot, do something like:" | 
| 800 echo " ./image_to_vm.sh --from=${OUTSIDE_OUTPUT_DIR} --board=${BOARD}" | 910 echo " ./image_to_vm.sh --from=${OUTSIDE_OUTPUT_DIR} --board=${BOARD}" | 
| 801 echo "from the scripts directory where you entered the chroot." | 911 echo "from the scripts directory where you entered the chroot." | 
| OLD | NEW |