diff --git a/bin/cros_make_image_bootable b/bin/cros_make_image_bootable index 71adfe7c33..84a643115b 100755 --- a/bin/cros_make_image_bootable +++ b/bin/cros_make_image_bootable @@ -97,8 +97,12 @@ DEFINE_integer rootfs_hash_pad 8 \ DEFINE_string rootfs_hash "/tmp/rootfs.hash" \ "Path where the rootfs hash should be stored." +# TODO(taysom): when we turn on boot cache, both verification and +# bootcache should have their default be FLAGS_TRUE. DEFINE_boolean enable_rootfs_verification ${FLAGS_FALSE} \ - "Default all bootloaders to use kernel-based root fs integrity checking." + "Default all bootloaders to NOT use kernel-based root fs integrity checking." +DEFINE_boolean enable_bootcache ${FLAGS_FALSE} \ + "Default all bootloaders to NOT use bootcache." DEFINE_integer verity_error_behavior 3 \ "Kernel verified boot error behavior (0: I/O errors, 1: reboot, 2: nothing)" DEFINE_integer verity_max_ios -1 \ @@ -171,6 +175,10 @@ make_image_bootable() { if [[ ${FLAGS_enable_rootfs_verification} -eq ${FLAGS_TRUE} ]]; then enable_rootfs_verification_flag=--enable_rootfs_verification fi + local enable_bootcache_flag=--noenable_bootcache + if [[ ${FLAGS_enable_bootcache} -eq ${FLAGS_TRUE} ]]; then + enable_bootcache_flag=--enable_bootcache + fi trap "mount_gpt_cleanup" EXIT "${SCRIPTS_DIR}/mount_gpt_image.sh" --from "$(dirname "${image}")" \ @@ -231,6 +239,7 @@ make_image_bootable() { --verity_salt=${FLAGS_verity_salt} \ --keys_dir="${FLAGS_keys_dir}" \ ${enable_rootfs_verification_flag} \ + ${enable_bootcache_flag} \ ${use_dev_keys} # Check the size of kernel image and issue warning when image size is diff --git a/build_image b/build_image index 047c9ba82f..226c4ea907 100755 --- a/build_image +++ b/build_image @@ -17,6 +17,8 @@ DEFINE_string board "${DEFAULT_BOARD}" \ "The board to build an image for." DEFINE_string boot_args "noinitrd" \ "Additional boot arguments to pass to the commandline" +DEFINE_boolean enable_bootcache ${FLAGS_FALSE} \ + "Default all bootloaders to NOT use boot cache." DEFINE_boolean enable_rootfs_verification ${FLAGS_TRUE} \ "Default all bootloaders to use kernel-based root fs integrity checking." DEFINE_string output_root "${DEFAULT_BUILD_ROOT}/images" \ diff --git a/build_kernel_image.sh b/build_kernel_image.sh index 63917c9e3e..bf7c832ba2 100755 --- a/build_kernel_image.sh +++ b/build_kernel_image.sh @@ -47,6 +47,8 @@ DEFINE_string verity_salt "" \ "Salt to use for rootfs hash (Default: \"\")" DEFINE_boolean enable_rootfs_verification ${FLAGS_TRUE} \ "Enable kernel-based root fs integrity checking. (Default: true)" +DEFINE_boolean enable_bootcache ${FLAGS_FALSE} \ + "Enable boot cache to accelerate booting. (Default: false)" # Parse flags FLAGS "$@" || exit 1 @@ -55,7 +57,31 @@ eval set -- "${FLAGS_ARGV}" # Die on error switch_to_strict_mode -verity_args= +rootdigest() { + local digest + digest=${table#*root_hexdigest=} + echo ${digest% salt*} +} + +salt() { + local salt + salt=${table#*salt=} + echo ${salt%} +} + +hashstart() { + local hash + hash=${table#*hashstart=} + echo ${hash% alg*} +} + +# Estimate of sectors used by verity +# (num blocks) * 32 (bytes per hash) * 2 (overhead) / 512 (bytes per sector) +veritysize() { + echo $((root_fs_blocks * 32 * 2 / 512)) +} + +device_mapper_args= # Even with a rootfs_image, root= is not changed unless specified. if [[ -n "${FLAGS_rootfs_image}" && -n "${FLAGS_rootfs_hash}" ]]; then # Gets the number of blocks. 4096 byte blocks _are_ expected. @@ -94,12 +120,29 @@ if [[ -n "${FLAGS_rootfs_image}" && -n "${FLAGS_rootfs_hash}" ]]; then # Don't claim the root device unless verity is enabled. # Doing so will claim /dev/sdDP out from under the system. if [[ ${FLAGS_enable_rootfs_verification} -eq ${FLAGS_TRUE} ]]; then - base_root='%U+1' # kern_guid + 1 + if [[ ${FLAGS_enable_bootcache} -eq ${FLAGS_TRUE} ]]; then + base_root='254:0' # major:minor numbers for /dev/dm-0 + else + base_root='%U+1' # kern_guid + 1 + fi table=${table//HASH_DEV/${base_root}} table=${table//ROOT_DEV/${base_root}} fi - verity_args="dm=\"vroot none ro,${table}\"" - info "dm-verity configuration: ${verity_args}" + verity_dev="vroot none ro 1,${table}" + if [[ ${FLAGS_enable_bootcache} -eq ${FLAGS_TRUE} ]]; then + signature=$(rootdigest) + cachestart=$(($(hashstart) + $(veritysize))) + size_limit=512 + max_trace=20000 + max_pages=100000 + bootcache_args="%U+1 ${cachestart} ${signature} ${size_limit}" + bootcache_args="${bootcache_args} ${max_trace} ${max_pages}" + bootcache_dev="vboot none ro 1, 0 ${cachestart} bootcache ${bootcache_args}" + device_mapper_args="dm=\"2 ${bootcache_dev}, ${verity_dev}\"" + else + device_mapper_args="dm=\"1 ${verity_dev}\"" + fi + info "device mapper configuration: ${device_mapper_args}" fi mkdir -p "${FLAGS_working_dir}" @@ -111,8 +154,17 @@ mkdir -p "${FLAGS_working_dir}" dev_wait=0 root_dev="PARTUUID=%U/PARTNROFF=1" if [[ ${FLAGS_enable_rootfs_verification} -eq ${FLAGS_TRUE} ]]; then - root_dev=/dev/dm-0 dev_wait=1 + if [[ ${FLAGS_enable_bootcache} -eq ${FLAGS_TRUE} ]]; then + root_dev=/dev/dm-1 + else + root_dev=/dev/dm-0 + fi +else + if [[ ${FLAGS_enable_bootcache} -eq ${FLAGS_TRUE} ]]; then + echo "Having bootcache without verity is not supported" + exit 2 + fi fi cat < "${FLAGS_working_dir}/boot.config" @@ -122,7 +174,7 @@ ro dm_verity.error_behavior=${FLAGS_verity_error_behavior} dm_verity.max_bios=${FLAGS_verity_max_ios} dm_verity.dev_wait=${dev_wait} -${verity_args} +${device_mapper_args} ${FLAGS_boot_args} vt.global_cursor_default=0 kern_guid=%U diff --git a/build_library/build_image_util.sh b/build_library/build_image_util.sh index e35f2b25bf..523b3e3d9c 100755 --- a/build_library/build_image_util.sh +++ b/build_library/build_image_util.sh @@ -121,6 +121,10 @@ create_boot_desc() { if [[ ${FLAGS_enable_rootfs_verification} -eq ${FLAGS_TRUE} ]]; then enable_rootfs_verification_flag="--enable_rootfs_verification" fi + local enable_bootcache_flag="" + if [[ ${FLAGS_enable_bootcache} -eq ${FLAGS_TRUE} ]]; then + enable_bootcache_flag=--enable_bootcache + fi [ -z "${FLAGS_verity_salt}" ] && FLAGS_verity_salt=$(make_salt) cat < ${BUILD_DIR}/boot.desc @@ -133,6 +137,7 @@ create_boot_desc() { --nocleanup_dirs --verity_algorithm=sha1 ${enable_rootfs_verification_flag} + ${enable_bootcache_flag} EOF }