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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 "The target image file or device" | 44 "The target image file or device" |
45 DEFINE_boolean factory_install ${FLAGS_FALSE} \ | 45 DEFINE_boolean factory_install ${FLAGS_FALSE} \ |
46 "Build a smaller image to overlay the factory install shim on; this argument \ | 46 "Build a smaller image to overlay the factory install shim on; this argument \ |
47 is also required in image_to_usb." | 47 is also required in image_to_usb." |
48 DEFINE_string arm_extra_bootargs "" \ | 48 DEFINE_string arm_extra_bootargs "" \ |
49 "Additional command line options to pass to the ARM kernel." | 49 "Additional command line options to pass to the ARM kernel." |
50 DEFINE_integer rootfs_partition_size 1024 \ | 50 DEFINE_integer rootfs_partition_size 1024 \ |
51 "rootfs parition size in MBs." | 51 "rootfs parition size in MBs." |
52 DEFINE_integer rootfs_size 720 \ | 52 DEFINE_integer rootfs_size 720 \ |
53 "rootfs filesystem size in MBs." | 53 "rootfs filesystem size in MBs." |
| 54 # ceil(0.1 * rootfs_size) is a good minimum. |
| 55 DEFINE_integer rootfs_hash_pad 8 \ |
| 56 "MBs reserved at the end of the rootfs image." |
54 DEFINE_integer statefulfs_size 1024 \ | 57 DEFINE_integer statefulfs_size 1024 \ |
55 "stateful filesystem size in MBs." | 58 "stateful filesystem size in MBs." |
56 DEFINE_boolean preserve ${FLAGS_FALSE} \ | 59 DEFINE_boolean preserve ${FLAGS_FALSE} \ |
57 "Attempt to preserve the previous build image if one can be found (unstable, \ | 60 "Attempt to preserve the previous build image if one can be found (unstable, \ |
58 kernel/firmware not updated)" | 61 kernel/firmware not updated)" |
59 DEFINE_boolean fast ${FLAGS_FALSE} \ | 62 DEFINE_boolean fast ${FLAGS_FALSE} \ |
60 "Call many emerges in parallel (unstable)" | 63 "Call many emerges in parallel (unstable)" |
61 | 64 |
62 DEFINE_string usb_disk /dev/sdb3 \ | 65 DEFINE_string usb_disk /dev/sdb3 \ |
63 "Path syslinux should use to do a usb boot. Default: /dev/sdb3" | 66 "Path syslinux should use to do a usb boot. Default: /dev/sdb3" |
(...skipping 20 matching lines...) Expand all Loading... |
84 | 87 |
85 # Only now can we die on error. shflags functions leak non-zero error codes, | 88 # Only now can we die on error. shflags functions leak non-zero error codes, |
86 # so will die prematurely if 'set -e' is specified before now. | 89 # so will die prematurely if 'set -e' is specified before now. |
87 set -e | 90 set -e |
88 | 91 |
89 if [ -z "${FLAGS_board}" ] ; then | 92 if [ -z "${FLAGS_board}" ] ; then |
90 error "--board is required." | 93 error "--board is required." |
91 exit 1 | 94 exit 1 |
92 fi | 95 fi |
93 | 96 |
94 if [ "${FLAGS_rootfs_size}" -gt "${FLAGS_rootfs_partition_size}" ] ; then | 97 if [ "$((FLAGS_rootfs_size + FLAGS_rootfs_hash_pad))" -gt \ |
95 error "rootfs (${FLAGS_rootfs_size} MB) is bigger than partition (${FLAGS_root
fs_partition_size} MB)." | 98 "${FLAGS_rootfs_partition_size}" ] ; then |
| 99 error "rootfs ($((FLAGS_rootfs_size + FLAGS_rootfs_hash_pad)) MB) is \ |
| 100 bigger than partition (${FLAGS_rootfs_partition_size} MB)." |
96 exit 1 | 101 exit 1 |
97 fi | 102 fi |
98 | 103 |
99 EMERGE_BOARD_CMD="emerge-${FLAGS_board}" | 104 EMERGE_BOARD_CMD="emerge-${FLAGS_board}" |
100 if [ "${FLAGS_fast}" -eq "${FLAGS_TRUE}" ]; then | 105 if [ "${FLAGS_fast}" -eq "${FLAGS_TRUE}" ]; then |
101 echo "Using alternate emerge" | 106 echo "Using alternate emerge" |
102 EMERGE_BOARD_CMD="${SCRIPTS_DIR}/parallel_emerge --board=${FLAGS_board}" | 107 EMERGE_BOARD_CMD="${SCRIPTS_DIR}/parallel_emerge --board=${FLAGS_board}" |
103 fi | 108 fi |
104 | 109 |
105 # Determine build version. | 110 # Determine build version. |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 if [[ ${FLAGS_enable_rootfs_verification} -eq ${FLAGS_TRUE} ]]; then | 291 if [[ ${FLAGS_enable_rootfs_verification} -eq ${FLAGS_TRUE} ]]; then |
287 cros_root=/dev/dm-0 | 292 cros_root=/dev/dm-0 |
288 fi | 293 fi |
289 | 294 |
290 # TODO(wad) mount the root fs to LOOP_DEV from the image | 295 # TODO(wad) mount the root fs to LOOP_DEV from the image |
291 trap "mount_gpt_cleanup" EXIT | 296 trap "mount_gpt_cleanup" EXIT |
292 ${SCRIPTS_DIR}/mount_gpt_image.sh --from "${OUTPUT_DIR}" \ | 297 ${SCRIPTS_DIR}/mount_gpt_image.sh --from "${OUTPUT_DIR}" \ |
293 --image "${image_name}" -r "${ROOT_FS_DIR}" \ | 298 --image "${image_name}" -r "${ROOT_FS_DIR}" \ |
294 -s "${STATEFUL_FS_DIR}" | 299 -s "${STATEFUL_FS_DIR}" |
295 | 300 |
| 301 # The rootfs should never be mounted rw again after this point without |
| 302 # re-calling make_image_bootable. |
296 sudo mount -o remount,ro "${ROOT_FS_DIR}" | 303 sudo mount -o remount,ro "${ROOT_FS_DIR}" |
297 root_dev=$(mount | grep -- "${ROOT_FS_DIR}" | cut -f1 -d' ' | tail -1) | 304 root_dev=$(mount | grep -- "on ${ROOT_FS_DIR} type" | cut -f1 -d' ' | tail -1) |
298 | 305 |
299 DEVKEYSDIR="/usr/share/vboot/devkeys" | 306 DEVKEYSDIR="/usr/share/vboot/devkeys" |
300 | 307 |
301 # Builds the kernel partition image. The temporary files are kept around | 308 # Builds the kernel partition image. The temporary files are kept around |
302 # so that we can perform a load_kernel_test later on the final image. | 309 # so that we can perform a load_kernel_test later on the final image. |
303 ${SCRIPTS_DIR}/build_kernel_image.sh \ | 310 ${SCRIPTS_DIR}/build_kernel_image.sh \ |
304 --arch="${ARCH}" \ | 311 --arch="${ARCH}" \ |
305 --to="${OUTPUT_DIR}/vmlinuz.image" \ | 312 --to="${OUTPUT_DIR}/vmlinuz.image" \ |
306 --hd_vblock="${OUTPUT_DIR}/vmlinuz_hd.vblock" \ | 313 --hd_vblock="${OUTPUT_DIR}/vmlinuz_hd.vblock" \ |
307 --vmlinuz="${OUTPUT_DIR}/boot/vmlinuz" \ | 314 --vmlinuz="${OUTPUT_DIR}/boot/vmlinuz" \ |
308 --working_dir="${OUTPUT_DIR}" \ | 315 --working_dir="${OUTPUT_DIR}" \ |
309 --keep_work \ | 316 --keep_work \ |
310 --rootfs_image=${root_dev} \ | 317 --rootfs_image=${root_dev} \ |
311 --rootfs_hash=${OUTPUT_DIR}/rootfs.hash \ | 318 --rootfs_hash=${ROOT_FS_HASH} \ |
312 --verity_hash_alg=${FLAGS_verity_algorithm} \ | 319 --verity_hash_alg=${FLAGS_verity_algorithm} \ |
313 --verity_tree_depth=${FLAGS_verity_depth} \ | 320 --verity_tree_depth=${FLAGS_verity_depth} \ |
314 --verity_max_ios=${FLAGS_verity_max_ios} \ | 321 --verity_max_ios=${FLAGS_verity_max_ios} \ |
315 --verity_error_behavior=${FLAGS_verity_error_behavior} \ | 322 --verity_error_behavior=${FLAGS_verity_error_behavior} \ |
316 --root=${cros_root} \ | 323 --root=${cros_root} \ |
317 --keys_dir="${DEVKEYSDIR}" | 324 --keys_dir="${DEVKEYSDIR}" |
318 | 325 |
| 326 local rootfs_hash_size=$(stat -c '%s' ${ROOT_FS_HASH}) |
| 327 info "Appending rootfs.hash (${rootfs_hash_size} bytes) to the root fs" |
| 328 if [[ ${rootfs_hash_size} -gt $((FLAGS_rootfs_hash_pad * 1024 * 1024)) ]] |
| 329 then |
| 330 die "--rootfs_hash_pad reserves less than the needed ${rootfs_hash_size}" |
| 331 fi |
| 332 # Unfortunately, mount_gpt_image uses mount and not losetup to create the |
| 333 # loop devices. This means that they are not the correct size. We have to |
| 334 # write directly to the image to append the hash tree data. |
| 335 local hash_offset="$(partoffset ${OUTPUT_DIR}/${image_name} 3)" |
| 336 hash_offset=$((hash_offset + ((1024 * 1024 * ${FLAGS_rootfs_size}) / 512))) |
| 337 sudo dd bs=512 \ |
| 338 seek=${hash_offset} \ |
| 339 if="${ROOT_FS_HASH}" \ |
| 340 of="${OUTPUT_DIR}/${image_name}" \ |
| 341 conv=notrunc |
| 342 # We don't need to keep the file around anymore. |
| 343 sudo rm "${ROOT_FS_HASH}" |
| 344 |
319 # Move the verification block needed for the hard disk install to the | 345 # Move the verification block needed for the hard disk install to the |
320 # stateful partition. Mount stateful fs, copy file, and umount fs. | 346 # stateful partition. Mount stateful fs, copy file, and umount fs. |
321 # In original CL: http://codereview.chromium.org/2868044, this was done in | 347 # In original CL: http://codereview.chromium.org/2868044, this was done in |
322 # create_base_image(). However, it could break the build if it is a clean | 348 # create_base_image(). However, it could break the build if it is a clean |
323 # build because vmlinuz_hd.vblock hasn't been created by build_kernel_image.sh | 349 # build because vmlinuz_hd.vblock hasn't been created by build_kernel_image.sh |
324 if [[ "${ARCH}" = "x86" ]]; then | 350 if [[ "${ARCH}" = "x86" ]]; then |
325 sudo cp "${OUTPUT_DIR}/vmlinuz_hd.vblock" "${STATEFUL_FS_DIR}" | 351 sudo cp "${OUTPUT_DIR}/vmlinuz_hd.vblock" "${STATEFUL_FS_DIR}" |
326 fi | 352 fi |
327 | 353 |
328 # START_KERN_A is set by the first call to install the gpt. | 354 # START_KERN_A is set by the first call to install the gpt. |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 if [[ ${FLAGS_factory_install} -eq ${FLAGS_TRUE} ]] ; then | 529 if [[ ${FLAGS_factory_install} -eq ${FLAGS_TRUE} ]] ; then |
504 ROOT_SIZE_BYTES=$((1024 * 1024 * 300)) | 530 ROOT_SIZE_BYTES=$((1024 * 1024 * 300)) |
505 else | 531 else |
506 ROOT_SIZE_BYTES=$((1024 * 1024 * ${FLAGS_rootfs_size})) | 532 ROOT_SIZE_BYTES=$((1024 * 1024 * ${FLAGS_rootfs_size})) |
507 fi | 533 fi |
508 | 534 |
509 dd if=/dev/zero of="${ROOT_FS_IMG}" bs=1 count=1 seek=$((ROOT_SIZE_BYTES - 1)) | 535 dd if=/dev/zero of="${ROOT_FS_IMG}" bs=1 count=1 seek=$((ROOT_SIZE_BYTES - 1)) |
510 sudo losetup "${LOOP_DEV}" "${ROOT_FS_IMG}" | 536 sudo losetup "${LOOP_DEV}" "${ROOT_FS_IMG}" |
511 sudo mkfs.ext3 "${LOOP_DEV}" | 537 sudo mkfs.ext3 "${LOOP_DEV}" |
512 | 538 |
| 539 # Pad out 10% for the hash tree. This currently _exact_ for |
| 540 # default configuration. More space may be needed for different options. |
| 541 ROOT_HASH_PAD=$((FLAGS_rootfs_hash_pad * 1024 * 1024)) |
| 542 info "Padding the rootfs image by ${ROOT_HASH_PAD} bytes for hash data" |
| 543 dd if=/dev/zero of="${ROOT_FS_IMG}" bs=1 count=1 \ |
| 544 seek=$((ROOT_SIZE_BYTES + ROOT_HASH_PAD - 1)) |
| 545 # Update to reflect the new capacity in the loop device. |
| 546 sudo losetup -c "${LOOP_DEV}" |
| 547 |
513 # Tune and mount rootfs. | 548 # Tune and mount rootfs. |
| 549 # TODO(wad) rename the disk label to match the GPT since we |
| 550 # can't change it later. |
514 DISK_LABEL="C-KEYFOB" | 551 DISK_LABEL="C-KEYFOB" |
515 sudo tune2fs -L "${DISK_LABEL}" -U "${UUID}" -c 0 -i 0 "${LOOP_DEV}" | 552 sudo tune2fs -L "${DISK_LABEL}" -U "${UUID}" -c 0 -i 0 "${LOOP_DEV}" |
516 sudo mount "${LOOP_DEV}" "${ROOT_FS_DIR}" | 553 sudo mount "${LOOP_DEV}" "${ROOT_FS_DIR}" |
517 | 554 |
518 # Create stateful partition of the same size as the rootfs. | 555 # Create stateful partition of the same size as the rootfs. |
519 STATEFUL_LOOP_DEV=$(sudo losetup -f) | 556 STATEFUL_LOOP_DEV=$(sudo losetup -f) |
520 if [ -z "${STATEFUL_LOOP_DEV}" ] ; then | 557 if [ -z "${STATEFUL_LOOP_DEV}" ] ; then |
521 echo "No free loop device. Free up a loop device or reboot. exiting. " | 558 echo "No free loop device. Free up a loop device or reboot. exiting. " |
522 exit 1 | 559 exit 1 |
523 fi | 560 fi |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 echo "Developer image created as ${DEVELOPER_IMAGE_NAME}" | 768 echo "Developer image created as ${DEVELOPER_IMAGE_NAME}" |
732 fi | 769 fi |
733 | 770 |
734 print_time_elapsed | 771 print_time_elapsed |
735 | 772 |
736 echo "To copy to USB keyfob, OUTSIDE the chroot, do something like:" | 773 echo "To copy to USB keyfob, OUTSIDE the chroot, do something like:" |
737 echo " ./image_to_usb.sh --from=${OUTSIDE_OUTPUT_DIR} --to=/dev/sdX" | 774 echo " ./image_to_usb.sh --from=${OUTSIDE_OUTPUT_DIR} --to=/dev/sdX" |
738 echo "To convert to VMWare image, OUTSIDE the chroot, do something like:" | 775 echo "To convert to VMWare image, OUTSIDE the chroot, do something like:" |
739 echo " ./image_to_vm.sh --from=${OUTSIDE_OUTPUT_DIR}" | 776 echo " ./image_to_vm.sh --from=${OUTSIDE_OUTPUT_DIR}" |
740 echo "from the scripts directory where you entered the chroot." | 777 echo "from the scripts directory where you entered the chroot." |
OLD | NEW |