Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/bin/bash | 1 #!/bin/bash |
| 2 | 2 |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2010 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 # Helper script that generates the signed kernel image | 7 # Helper script that generates the signed kernel image |
| 8 | 8 |
| 9 # --- BEGIN COMMON.SH BOILERPLATE --- | 9 # --- BEGIN COMMON.SH BOILERPLATE --- |
| 10 # Load common CrOS utilities. Inside the chroot this file is installed in | 10 # Load common CrOS utilities. Inside the chroot this file is installed in |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 DEFINE_integer verity_error_behavior 2 \ | 62 DEFINE_integer verity_error_behavior 2 \ |
| 63 "Verified boot error behavior [0: I/O errors, 1: reboot, 2: nothing] \ | 63 "Verified boot error behavior [0: I/O errors, 1: reboot, 2: nothing] \ |
| 64 (Default: 2)" | 64 (Default: 2)" |
| 65 DEFINE_integer verity_tree_depth 1 \ | 65 DEFINE_integer verity_tree_depth 1 \ |
| 66 "Optional Verified boot hash tree depth. (Default: 1)" | 66 "Optional Verified boot hash tree depth. (Default: 1)" |
| 67 DEFINE_integer verity_max_ios 1024 \ | 67 DEFINE_integer verity_max_ios 1024 \ |
| 68 "Optional number of outstanding I/O operations. (Default: 1024)" | 68 "Optional number of outstanding I/O operations. (Default: 1024)" |
| 69 DEFINE_string verity_hash_alg "sha1" \ | 69 DEFINE_string verity_hash_alg "sha1" \ |
| 70 "Cryptographic hash algorithm used for dm-verity. (Default: sha1)" | 70 "Cryptographic hash algorithm used for dm-verity. (Default: sha1)" |
| 71 | 71 |
| 72 # TODO(clchiou): Remove this flag after arm verified boot is stable | |
| 73 DEFINE_boolean crosbug12352_arm_kernel_signing ${FLAGS_FALSE} \ | |
| 74 "Sign kernel partition for ARM images (temporary hack)." | |
| 75 | |
| 72 # Parse flags | 76 # Parse flags |
| 73 FLAGS "$@" || exit 1 | 77 FLAGS "$@" || exit 1 |
| 74 eval set -- "${FLAGS_ARGV}" | 78 eval set -- "${FLAGS_ARGV}" |
| 75 | 79 |
| 76 # Die on error | 80 # Die on error |
| 77 set -e | 81 set -e |
| 78 | 82 |
| 79 verity_args= | 83 verity_args= |
| 80 # Even with a rootfs_image, root= is not changed unless specified. | 84 # Even with a rootfs_image, root= is not changed unless specified. |
| 81 if [[ -n "${FLAGS_rootfs_image}" && -n "${FLAGS_rootfs_hash}" ]]; then | 85 if [[ -n "${FLAGS_rootfs_image}" && -n "${FLAGS_rootfs_hash}" ]]; then |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 dm_verity.error_behavior=${FLAGS_verity_error_behavior} | 140 dm_verity.error_behavior=${FLAGS_verity_error_behavior} |
| 137 dm_verity.max_bios=${FLAGS_verity_max_ios} | 141 dm_verity.max_bios=${FLAGS_verity_max_ios} |
| 138 dm_verity.dev_wait=${dev_wait} | 142 dm_verity.dev_wait=${dev_wait} |
| 139 ${verity_args} | 143 ${verity_args} |
| 140 ${FLAGS_boot_args} | 144 ${FLAGS_boot_args} |
| 141 EOF | 145 EOF |
| 142 | 146 |
| 143 WORK="${WORK} ${FLAGS_working_dir}/boot.config" | 147 WORK="${WORK} ${FLAGS_working_dir}/boot.config" |
| 144 info "Emitted cross-platform boot params to ${FLAGS_working_dir}/boot.config" | 148 info "Emitted cross-platform boot params to ${FLAGS_working_dir}/boot.config" |
| 145 | 149 |
| 146 # FIXME: At the moment, we're working on signed images for x86 only. ARM will | 150 mkdir -p ${FLAGS_working_dir} |
|
Will Drewry
2011/02/23 18:46:07
Wasn't this called on line 126?
Che-Liang Chiou
2011/02/24 02:34:11
Done.
| |
| 147 # support this before shipping, but at the moment they don't. | |
| 148 if [[ "${FLAGS_arch}" = "x86" ]]; then | 151 if [[ "${FLAGS_arch}" = "x86" ]]; then |
| 149 | |
| 150 # Legacy BIOS will use the kernel in the rootfs (via syslinux), as will | 152 # Legacy BIOS will use the kernel in the rootfs (via syslinux), as will |
| 151 # standard EFI BIOS (via grub, from the EFI System Partition). Chrome OS | 153 # standard EFI BIOS (via grub, from the EFI System Partition). Chrome OS |
| 152 # BIOS will use a separate signed kernel partition, which we'll create now. | 154 # BIOS will use a separate signed kernel partition, which we'll create now. |
| 153 # FIXME: remove serial output, debugging messages. | 155 # FIXME: remove serial output, debugging messages. |
| 154 mkdir -p ${FLAGS_working_dir} | |
| 155 cat <<EOF | cat - "${FLAGS_working_dir}/boot.config" \ | 156 cat <<EOF | cat - "${FLAGS_working_dir}/boot.config" \ |
| 156 > "${FLAGS_working_dir}/config.txt" | 157 > "${FLAGS_working_dir}/config.txt" |
| 157 console=tty2 | 158 console=tty2 |
| 158 init=/sbin/init | 159 init=/sbin/init |
| 159 add_efi_memmap | 160 add_efi_memmap |
| 160 boot=local | 161 boot=local |
| 161 noresume | 162 noresume |
| 162 noswap | 163 noswap |
| 163 i915.modeset=1 | 164 i915.modeset=1 |
| 164 cros_secure | 165 cros_secure |
| 165 kern_guid=%U | 166 kern_guid=%U |
| 166 tpm_tis.force=1 | 167 tpm_tis.force=1 |
| 167 tpm_tis.interrupts=0 | 168 tpm_tis.interrupts=0 |
| 168 EOF | 169 EOF |
| 169 WORK="${WORK} ${FLAGS_working_dir}/config.txt" | 170 WORK="${WORK} ${FLAGS_working_dir}/config.txt" |
| 170 | 171 |
| 172 bootloader_path="/lib64/bootstub/bootstub.efi" | |
| 173 kernel_image="${FLAGS_vmlinuz}" | |
| 174 | |
| 175 sign_the_kernel=${FLAGS_TRUE} | |
| 176 elif [[ "${FLAGS_arch}" = "arm" ]]; then | |
| 177 cp "${FLAGS_working_dir}/boot.config" "${FLAGS_working_dir}/config.txt" | |
| 178 WORK="${WORK} ${FLAGS_working_dir}/config.txt" | |
| 179 | |
| 180 kernel_script="${FLAGS_working_dir}/kernel.scr" | |
| 181 kernel_script_img="${FLAGS_working_dir}/kernel.scr.uimg" | |
| 182 | |
| 183 echo -n 'setenv bootargs ${bootargs} ' > "${kernel_script}" | |
| 184 tr '\n' ' ' < "${FLAGS_working_dir}/boot.config" >> "${kernel_script}" | |
| 185 echo >> "${kernel_script}" | |
| 186 | |
| 187 mkimage -A arm -O linux -T script -C none -a 0 -e 0 \ | |
| 188 -n kernel_script -d "${kernel_script}" "${kernel_script_img}" | |
| 189 | |
| 190 WORK="${WORK} ${kernel_script} ${kernel_script_img}" | |
| 191 | |
| 192 bootloader_path="${kernel_script_img}" | |
| 193 kernel_image="${FLAGS_vmlinuz/vmlinuz/vmlinux.uimg}" | |
| 194 | |
| 195 sign_the_kernel=${FLAGS_crosbug12352_arm_kernel_signing} | |
| 196 else | |
| 197 error "Unknown arch: ${FLAGS_arch}" | |
| 198 fi | |
| 199 | |
| 200 if [[ "${sign_the_kernel}" -eq "${FLAGS_TRUE}" ]]; then | |
| 171 # We sign the image with the recovery_key, because this is what goes onto the | 201 # We sign the image with the recovery_key, because this is what goes onto the |
| 172 # USB key. We can only boot from the USB drive in recovery mode. | 202 # USB key. We can only boot from the USB drive in recovery mode. |
| 173 # For dev install shim, we need to use the installer keyblock instead of | 203 # For dev install shim, we need to use the installer keyblock instead of |
| 174 # the recovery keyblock because of the difference in flags. | 204 # the recovery keyblock because of the difference in flags. |
| 175 if [ ${FLAGS_use_dev_keys} -eq ${FLAGS_TRUE} ]; then | 205 if [ ${FLAGS_use_dev_keys} -eq ${FLAGS_TRUE} ]; then |
| 176 USB_KEYBLOCK=installer_kernel.keyblock | 206 USB_KEYBLOCK=installer_kernel.keyblock |
| 177 info "DEBUG: use dev install signing key" | 207 info "DEBUG: use dev install signing key" |
| 178 else | 208 else |
| 179 USB_KEYBLOCK=recovery_kernel.keyblock | 209 USB_KEYBLOCK=recovery_kernel.keyblock |
| 180 info "DEBUG: use recovery signing key" | 210 info "DEBUG: use recovery signing key" |
| 181 fi | 211 fi |
| 182 | 212 |
| 183 # Create and sign the kernel blob | 213 # Create and sign the kernel blob |
| 184 vbutil_kernel \ | 214 vbutil_kernel \ |
| 185 --pack "${FLAGS_to}" \ | 215 --pack "${FLAGS_to}" \ |
| 186 --keyblock "${FLAGS_keys_dir}/${USB_KEYBLOCK}" \ | 216 --keyblock "${FLAGS_keys_dir}/${USB_KEYBLOCK}" \ |
| 187 --signprivate "${FLAGS_keys_dir}/recovery_kernel_data_key.vbprivk" \ | 217 --signprivate "${FLAGS_keys_dir}/recovery_kernel_data_key.vbprivk" \ |
| 188 --version 1 \ | 218 --version 1 \ |
| 189 --config "${FLAGS_working_dir}/config.txt" \ | 219 --config "${FLAGS_working_dir}/config.txt" \ |
| 190 --bootloader /lib64/bootstub/bootstub.efi \ | 220 --bootloader "${bootloader_path}" \ |
| 191 --vmlinuz "${FLAGS_vmlinuz}" | 221 --vmlinuz "${kernel_image}" \ |
| 222 --arch "${FLAGS_arch}" | |
| 192 | 223 |
| 193 # And verify it. | 224 # And verify it. |
| 194 vbutil_kernel \ | 225 vbutil_kernel \ |
| 195 --verify "${FLAGS_to}" \ | 226 --verify "${FLAGS_to}" \ |
| 196 --signpubkey "${FLAGS_keys_dir}/recovery_key.vbpubk" | 227 --signpubkey "${FLAGS_keys_dir}/recovery_key.vbpubk" |
| 197 | 228 |
| 198 | 229 |
| 199 # Now we re-sign the same image using the normal keys. This is the kernel | 230 # Now we re-sign the same image using the normal keys. This is the kernel |
| 200 # image that is put on the hard disk by the installer. Note: To save space on | 231 # image that is put on the hard disk by the installer. Note: To save space on |
| 201 # the USB image, we're only emitting the new verfication block, and the | 232 # the USB image, we're only emitting the new verfication block, and the |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 214 cat "${FLAGS_hd_vblock}" > $tempfile | 245 cat "${FLAGS_hd_vblock}" > $tempfile |
| 215 dd if="${FLAGS_to}" bs=65536 skip=1 >> $tempfile | 246 dd if="${FLAGS_to}" bs=65536 skip=1 >> $tempfile |
| 216 | 247 |
| 217 vbutil_kernel \ | 248 vbutil_kernel \ |
| 218 --verify $tempfile \ | 249 --verify $tempfile \ |
| 219 --signpubkey "${FLAGS_keys_dir}/kernel_subkey.vbpubk" | 250 --signpubkey "${FLAGS_keys_dir}/kernel_subkey.vbpubk" |
| 220 | 251 |
| 221 rm -f $tempfile | 252 rm -f $tempfile |
| 222 trap - EXIT | 253 trap - EXIT |
| 223 | 254 |
| 224 elif [[ "${FLAGS_arch}" = "arm" ]]; then | 255 else |
| 225 # FIXME: This stuff is unsigned, and will likely change with vboot_reference | 256 # FIXME: This stuff is unsigned. This part should be removed or made |
| 226 # but it doesn't technically have to. | 257 # non-default after ARM verified boot is stable. |
| 227 | |
| 228 kernel_script="${FLAGS_working_dir}/kernel.scr" | |
| 229 kernel_script_img="${FLAGS_working_dir}/kernel.scr.uimg" | |
| 230 # HACK: !! Kernel image construction requires some stuff from portage, not | |
| 231 # sure how to get that information here cleanly !! | |
| 232 kernel_image="${FLAGS_vmlinuz/vmlinuz/vmlinux.uimg}" | |
| 233 WORK="${WORK} ${kernel_script} ${kernel_script_img}" | |
| 234 | 258 |
| 235 kernel_size=$((($(stat -c %s "${kernel_image}") + 511) / 512)) | 259 kernel_size=$((($(stat -c %s "${kernel_image}") + 511) / 512)) |
| 236 script_size=16 | 260 script_size=16 |
| 237 | 261 |
| 238 # Build boot script image | 262 # Add more scripts to boot script image for loading kernel image |
| 239 echo -n 'setenv bootargs ${bootargs} ' > "${kernel_script}" | |
| 240 tr '\n' ' ' <"${FLAGS_working_dir}/boot.config" >> "${kernel_script}" | |
| 241 echo >> "${kernel_script}" | |
| 242 printf 'read ${devtype} ${devnum}:${kernelpart} ${loadaddr} %x %x\n' \ | 263 printf 'read ${devtype} ${devnum}:${kernelpart} ${loadaddr} %x %x\n' \ |
| 243 ${script_size} ${kernel_size} >> "${kernel_script}" | 264 ${script_size} ${kernel_size} >> "${kernel_script}" |
| 244 echo 'bootm ${loadaddr}' >> ${kernel_script} | 265 echo 'bootm ${loadaddr}' >> ${kernel_script} |
| 245 mkimage -A arm -O linux -T script -C none -a 0 -e 0 \ | 266 mkimage -A arm -O linux -T script -C none -a 0 -e 0 \ |
| 246 -n kernel_script -d "${kernel_script}" "${kernel_script_img}" | 267 -n kernel_script -d "${kernel_script}" "${kernel_script_img}" |
| 247 | 268 |
| 248 if [ $(stat -c %s "${kernel_script_img}") -gt $((512 * ${script_size})) ] | 269 if [ $(stat -c %s "${kernel_script_img}") -gt $((512 * ${script_size})) ] |
| 249 then | 270 then |
| 250 echo 'Kernel script too large for reserved space.' | 271 echo 'Kernel script too large for reserved space.' |
| 251 exit 1 | 272 exit 1 |
| 252 fi | 273 fi |
| 253 | 274 |
| 254 # Assemble image | 275 # Assemble image |
| 255 rm -f "${FLAGS_to}" | 276 rm -f "${FLAGS_to}" |
| 256 dd if="${kernel_script_img}" of="${FLAGS_to}" bs=512 count="${script_size}" | 277 dd if="${kernel_script_img}" of="${FLAGS_to}" bs=512 count="${script_size}" |
| 257 dd if="${kernel_image}" of="${FLAGS_to}" bs=512 seek="${script_size}" | 278 dd if="${kernel_image}" of="${FLAGS_to}" bs=512 seek="${script_size}" |
| 258 | 279 |
| 259 # TODO: HACK: Until the kernel partition contains a signed image, create a | 280 # TODO: HACK: Until the kernel partition contains a signed image, create a |
| 260 # phony hd.vblock to keep chromeos-install and cros_generate_update_payload | 281 # phony hd.vblock to keep chromeos-install and cros_generate_update_payload |
| 261 # working. | 282 # working. |
| 262 dd if="${FLAGS_to}" of="${FLAGS_hd_vblock}" bs=64K count=1 | 283 dd if="${FLAGS_to}" of="${FLAGS_hd_vblock}" bs=64K count=1 |
| 263 else | |
| 264 error "Unknown arch: ${FLAGS_arch}" | |
| 265 fi | 284 fi |
| 266 | 285 |
| 267 set +e # cleanup failure is a-ok | 286 set +e # cleanup failure is a-ok |
| 268 | 287 |
| 269 if [[ ${FLAGS_keep_work} -eq ${FLAGS_FALSE} ]]; then | 288 if [[ ${FLAGS_keep_work} -eq ${FLAGS_FALSE} ]]; then |
| 270 info "Cleaning up temporary files: ${WORK}" | 289 info "Cleaning up temporary files: ${WORK}" |
| 271 rm ${WORK} | 290 rm ${WORK} |
| 272 rmdir ${FLAGS_working_dir} | 291 rmdir ${FLAGS_working_dir} |
| 273 fi | 292 fi |
| 274 | 293 |
| 275 info "Kernel partition image emitted: ${FLAGS_to}" | 294 info "Kernel partition image emitted: ${FLAGS_to}" |
| 276 | 295 |
| 277 if [[ -f ${FLAGS_rootfs_hash} ]]; then | 296 if [[ -f ${FLAGS_rootfs_hash} ]]; then |
| 278 info "Root filesystem hash emitted: ${FLAGS_rootfs_hash}" | 297 info "Root filesystem hash emitted: ${FLAGS_rootfs_hash}" |
| 279 fi | 298 fi |
| OLD | NEW |