build_image: pull out kernel partition creation

Makes kernel partition creation standalone.  This is motivated
both by the ability to build test kernel partitions easily as well
the need to create all kernel command line configuration after the
rootfs has been completely created.

Instead of a massive overhaul, I'll do this refactor in pieces.

TEST=manually rebuilt the image
BUG=chromium-os:327

Review URL: http://codereview.chromium.org/2825021
This commit is contained in:
Will Drewry 2010-06-24 16:12:58 -05:00
parent 2561de0cbc
commit 69563b7349
2 changed files with 138 additions and 66 deletions

View File

@ -462,73 +462,18 @@ menuentry "Alternate USB Boot" {
} }
EOF EOF
# TODO(wad) add baseline syslinux files to ESP and install the syslinux loader
# FIXME: At the moment, we're working on signed images for x86 only. ARM will # Builds the kernel partition image. The temporary files are kept around
# support this before shipping, but at the moment they don't. # so that we can perform a load_kernel_test later on the final image.
if [[ "${ARCH}" = "x86" ]]; then # TODO(wad) add dm-verity boot args (--boot_args, --root)
${SCRIPTS_DIR}/build_kernel_image.sh \
# Legacy BIOS will use the kernel in the rootfs (via syslinux), as will --arch="${ARCH}" \
# standard EFI BIOS (via grub, from the EFI System Partition). Chrome OS --to="${OUTPUT_DIR}/vmlinuz.image" \
# BIOS will use a separate signed kernel partition, which we'll create now. --vmlinuz="${ROOT_FS_DIR}/boot/vmlinuz" \
# FIXME: remove serial output, debugging messages. --working_dir="${OUTPUT_DIR}" \
cat <<'EOF' > "${OUTPUT_DIR}/config.txt" --keep_work \
earlyprintk=serial,ttyS0,115200 --keys_dir="${SRC_ROOT}/platform/vboot_reference/tests/testkeys"
console=ttyS0,115200
init=/sbin/init
add_efi_memmap
gpt
boot=local
rootwait
root=/dev/sd%D%P
ro
noresume
noswap
i915.modeset=1
loglevel=7
cros_secure
EOF
# FIXME: We need to specify the real keys and certs here!
SIG_DIR="${SRC_ROOT}/platform/vboot_reference/tests/testkeys"
# Wrap the public keys with VbPublicKey headers.
vbutil_key --pack \
--in "${SIG_DIR}/key_rsa2048.keyb" \
--version 1 --algorithm 4 \
--out "${OUTPUT_DIR}/key_alg4.vbpubk"
vbutil_key --pack \
--in "${SIG_DIR}/key_rsa4096.keyb" \
--version 1 --algorithm 8 \
--out "${OUTPUT_DIR}/key_alg8.vbpubk"
vbutil_keyblock --pack "${OUTPUT_DIR}/data4_sign8.keyblock" \
--datapubkey "${OUTPUT_DIR}/key_alg4.vbpubk" \
--signprivate "${SIG_DIR}/key_rsa4096.pem" \
--algorithm 8 --flags 3
# Verify the keyblock.
vbutil_keyblock --unpack "${OUTPUT_DIR}/data4_sign8.keyblock" \
--signpubkey "${OUTPUT_DIR}/key_alg8.vbpubk"
# Sign the kernel:
vbutil_kernel --pack "${OUTPUT_DIR}/vmlinuz.image" \
--keyblock "${OUTPUT_DIR}/data4_sign8.keyblock" \
--signprivate "${SIG_DIR}/key_rsa2048.pem" \
--version 1 \
--config "${OUTPUT_DIR}/config.txt" \
--bootloader /lib64/bootstub/bootstub.efi \
--vmlinuz "${ROOT_FS_DIR}/boot/vmlinuz"
# And verify it.
vbutil_kernel --verify "${OUTPUT_DIR}/vmlinuz.image" \
--signpubkey "${OUTPUT_DIR}/key_alg8.vbpubk"
else
# FIXME: For now, ARM just uses the unsigned kernel by itself.
cp -f "${ROOT_FS_DIR}/boot/vmlinuz" "${OUTPUT_DIR}/vmlinuz.image"
fi
# Perform any customizations on the root file system that are needed. # Perform any customizations on the root file system that are needed.
"${SCRIPTS_DIR}/customize_rootfs" \ "${SCRIPTS_DIR}/customize_rootfs" \
@ -597,6 +542,7 @@ trap - EXIT
# FIXME: only signing things for x86 right now. # FIXME: only signing things for x86 right now.
if [[ "${ARCH}" = "x86" ]]; then if [[ "${ARCH}" = "x86" ]]; then
# Verify the final image. # Verify the final image.
# key_alg8.vbpubk is generated by build_kernel_image.sh --keep_work
load_kernel_test "${OUTPUT_IMG}" "${OUTPUT_DIR}/key_alg8.vbpubk" load_kernel_test "${OUTPUT_IMG}" "${OUTPUT_DIR}/key_alg8.vbpubk"
fi fi

126
build_kernel_image.sh Executable file
View File

@ -0,0 +1,126 @@
#!/bin/bash
# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Helper script that generates the signed kernel image
. "$(dirname "$0")/common.sh"
get_default_board
# Flags.
DEFINE_string arch "x86" \
"The boot architecture: arm or x86. (Default: x86)"
DEFINE_string to "/tmp/vmlinuz.image" \
"The path to the kernel image to be created. (Default: /tmp/vmlinuz.image)"
DEFINE_string vmlinuz "vmlinuz" \
"The path to the kernel (Default: vmlinuz)"
DEFINE_string working_dir "/tmp/vmlinuz.working" \
"Working directory for in-progress files. (Default: /tmp/vmlinuz.working)"
DEFINE_boolean keep_work ${FLAGS_FALSE} \
"Keep temporary files (*.keyblock, *.vbpubk). (Default: false)"
DEFINE_string keys_dir "${SRC_ROOT}/platform/vboot_reference/tests/testkeys" \
"Directory with the signing keys. (Defaults to test keys)"
# Note, to enable verified boot, the caller would pass:
# --boot_args='dm="... /dev/sd%D%P /dev/sd%D%P ..." \
# --root=/dev/dm-0
DEFINE_string boot_args "noinitrd" \
"Additional boot arguments to pass to the commandline (Default: noinitrd)"
DEFINE_string root "/dev/sd%D%P" \
"Expected device root (Default: root=/dev/sd%D%P)"
# Parse flags
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
# Die on error
set -e
# FIXME: At the moment, we're working on signed images for x86 only. ARM will
# support this before shipping, but at the moment they don't.
if [[ "${FLAGS_arch}" = "x86" ]]; then
# Legacy BIOS will use the kernel in the rootfs (via syslinux), as will
# standard EFI BIOS (via grub, from the EFI System Partition). Chrome OS
# BIOS will use a separate signed kernel partition, which we'll create now.
# FIXME: remove serial output, debugging messages.
mkdir -p ${FLAGS_working_dir}
cat <<EOF > "${FLAGS_working_dir}/config.txt"
earlyprintk=serial,ttyS0,115200
console=ttyS0,115200
init=/sbin/init
add_efi_memmap
boot=local
rootwait
root=${FLAGS_root}
ro
noresume
noswap
i915.modeset=1
loglevel=7
cros_secure
${FLAGS_boot_args}
EOF
WORK="${FLAGS_working_dir}/config.txt"
# Wrap the public keys with VbPublicKey headers.
vbutil_key \
--pack \
--in "${FLAGS_keys_dir}/key_rsa2048.keyb" \
--version 1 \
--algorithm 4 \
--out "${FLAGS_working_dir}/key_alg4.vbpubk"
WORK="${WORK} ${FLAGS_working_dir}/key_alg4.vbpubk"
vbutil_key \
--pack \
--in "${FLAGS_keys_dir}/key_rsa4096.keyb" \
--version 1 \
--algorithm 8 \
--out "${FLAGS_working_dir}/key_alg8.vbpubk"
WORK="${WORK} ${FLAGS_working_dir}/key_alg8.vbpubk"
vbutil_keyblock \
--pack "${FLAGS_working_dir}/data4_sign8.keyblock" \
--datapubkey "${FLAGS_working_dir}/key_alg4.vbpubk" \
--signprivate "${FLAGS_keys_dir}/key_rsa4096.pem" \
--algorithm 8 \
--flags 3
WORK="${WORK} ${FLAGS_working_dir}/data4_sign8.keyblock"
# Verify the keyblock.
vbutil_keyblock \
--unpack "${FLAGS_working_dir}/data4_sign8.keyblock" \
--signpubkey "${FLAGS_working_dir}/key_alg8.vbpubk"
# Sign the kernel:
vbutil_kernel \
--pack "${FLAGS_to}" \
--keyblock "${FLAGS_working_dir}/data4_sign8.keyblock" \
--signprivate "${FLAGS_keys_dir}/key_rsa2048.pem" \
--version 1 \
--config "${FLAGS_working_dir}/config.txt" \
--bootloader /lib64/bootstub/bootstub.efi \
--vmlinuz "${FLAGS_vmlinuz}"
# And verify it.
vbutil_kernel \
--verify "${FLAGS_to}" \
--signpubkey "${FLAGS_working_dir}/key_alg8.vbpubk"
else
# FIXME: For now, ARM just uses the unsigned kernel by itself.
cp -f "${FLAGS_vmlinuz}" "${FLAGS_to}"
fi
set +e # cleanup failure is a-ok
if [[ ${FLAGS_keep_work} -eq ${FLAGS_FALSE} ]]; then
echo "Cleaning up temporary files: ${WORK}"
rm ${WORK}
rmdir ${FLAGS_working_dir}
fi
echo "Kernel partition image emitted: ${FLAGS_to}"