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 |