| # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| EAPI=4 |
| |
| # need to check out factory source for netboot_firmware_settings.py for now |
| CROS_WORKON_PROJECT="chromiumos/platform/factory" |
| CROS_WORKON_LOCALNAME="../platform/factory" |
| |
| inherit cros-debug cros-workon |
| |
| DESCRIPTION="ChromeOS firmware image builder" |
| HOMEPAGE="http://www.chromium.org" |
| LICENSE="GPL-2" |
| SLOT="0" |
| KEYWORDS="~*" |
| # TODO(sjg@chromium.org): Remove when x86 can build all boards |
| BOARDS="alex aplrvp auron bayleybay beltino bolt butterfly" |
| BOARDS="${BOARDS} chell cyan emeraldlake2 eve falco fizz fox" |
| BOARDS="${BOARDS} gizmo glados jecht kunimitsu link lumpy lumpy64 mario nasher panther" |
| BOARDS="${BOARDS} parrot peppy poppy pyro rambi reef samus sand sklrvp slippy snappy" |
| BOARDS="${BOARDS} squawks stout strago stumpy sumo" |
| IUSE="${BOARDS} +bmpblk cb_legacy_seabios cb_legacy_uboot" |
| IUSE="${IUSE} cros_ec exynos fsp" |
| IUSE="${IUSE} pd_sync tegra fastboot unibuild" |
| |
| REQUIRED_USE=" |
| ^^ ( ${BOARDS} arm mips ) |
| " |
| |
| DEPEND=" |
| exynos? ( sys-boot/exynos-pre-boot ) |
| tegra? ( virtual/tegra-bct ) |
| cros_ec? ( chromeos-base/chromeos-ec ) |
| pd_sync? ( chromeos-base/chromeos-ec ) |
| chromeos-base/vboot_reference |
| bmpblk? ( sys-boot/chromeos-bmpblk ) |
| cb_legacy_uboot? ( virtual/u-boot ) |
| cb_legacy_seabios? ( sys-boot/chromeos-seabios ) |
| sys-boot/coreboot |
| sys-boot/depthcharge |
| " |
| |
| # Directory where the generated files are looked for and placed. |
| CROS_FIRMWARE_IMAGE_DIR="/firmware" |
| CROS_FIRMWARE_ROOT="${ROOT%/}${CROS_FIRMWARE_IMAGE_DIR}" |
| |
| prepare_legacy_image() { |
| local legacy_var="$1" |
| if use cb_legacy_seabios; then |
| eval "${legacy_var}='${CROS_FIRMWARE_ROOT}/seabios.cbfs'" |
| elif use cb_legacy_uboot; then |
| local output="${T}/_u-boot.cbfs" |
| "${FILESDIR}/build_cb_legacy_uboot.sh" \ |
| "${CROS_FIRMWARE_ROOT}/u-boot" \ |
| "${CROS_FIRMWARE_ROOT}/dtb/${U_BOOT_FDT_USE}.dtb" \ |
| "${T}" "${output}" || |
| die "Failed to build legacy U-Boot." |
| eval "${legacy_var}='${output}'" |
| else |
| einfo "No legacy boot payloads specified." |
| fi |
| } |
| |
| do_cbfstool() { |
| local output |
| output=$(cbfstool "$@" 2>&1) |
| if [ $? != 0 ]; then |
| die "Failed cbfstool invocation: cbfstool $@\n${output}" |
| fi |
| printf "${output}" |
| } |
| |
| sign_region() { |
| local fw_image=$1 |
| local keydir=$2 |
| local slot=$3 |
| |
| local tmpfile=`mktemp` |
| local cbfs=FW_MAIN_${slot} |
| local vblock=VBLOCK_${slot} |
| |
| do_cbfstool ${fw_image} read -r ${cbfs} -f ${tmpfile} |
| local size=$(do_cbfstool ${fw_image} print -k -r ${cbfs} | \ |
| tail -1 | \ |
| sed "/(empty).*null/ s,^(empty)[[:space:]]\(0x[0-9a-f]*\)\tnull\t.*$,\1,") |
| size=$(printf "%d" ${size}) |
| |
| # If the last entry is called "(empty)" and of type "null", remove it from |
| # the section so it isn't part of the signed data, to improve boot speed |
| # if (as often happens) there's a large unused suffix. |
| if [ -n "${size}" ] && [ ${size} -gt 0 ]; then |
| head -c ${size} ${tmpfile} > ${tmpfile}.2 |
| mv ${tmpfile}.2 ${tmpfile} |
| do_cbfstool ${fw_image} write --force -u -i 0 \ |
| -r ${cbfs} -f ${tmpfile} |
| fi |
| |
| futility vbutil_firmware \ |
| --vblock ${tmpfile}.out \ |
| --keyblock ${keydir}/firmware.keyblock \ |
| --signprivate ${keydir}/firmware_data_key.vbprivk \ |
| --version 1 \ |
| --fv ${tmpfile} \ |
| --kernelkey ${keydir}/kernel_subkey.vbpubk \ |
| --flags 0 |
| |
| do_cbfstool ${fw_image} write -u -i 0 -r ${vblock} -f ${tmpfile}.out |
| |
| rm -f ${tmpfile} ${tmpfile}.out |
| } |
| |
| sign_image() { |
| local fw_image=$1 |
| local keydir=$2 |
| |
| sign_region "${fw_image}" "${keydir}" A |
| sign_region "${fw_image}" "${keydir}" B |
| } |
| |
| add_payloads() { |
| local fw_image=$1 |
| local ro_payload=$2 |
| local rw_payload=$3 |
| |
| do_cbfstool ${fw_image} add-payload \ |
| -f ${ro_payload} -n fallback/payload -c lzma |
| |
| do_cbfstool ${fw_image} add-payload \ |
| -f ${rw_payload} -n fallback/payload -c lzma -r FW_MAIN_A,FW_MAIN_B |
| } |
| |
| # Add payloads and sign the image. |
| # This takes the base image and creates a new signed one with the given |
| # payloads added to it. |
| # The image is placed in directory ${outdir} ("" for current directory). |
| # An image suffix is added is ${suffix} is non-empty (e.g. "dev", "net"). |
| # Args: |
| # $1: Image type (e,g. "" for standard image, "dev" for dev image) |
| # $2: Source image to start from. |
| # $3: Payload to add to read-only image portion |
| # $4: Payload to add to read-write image portion |
| build_image() { |
| local image_type=$1 |
| local src_image=$2 |
| local ro_payload=$3 |
| local rw_payload=$4 |
| local devkeys_dir="${ROOT%/}/usr/share/vboot/devkeys" |
| |
| [ -n "${image_type}" ] && image_type=".${image_type}" |
| local dst_image="${outdir}image${suffix}${image_type}.bin" |
| |
| einfo "Building image ${dst_image}" |
| cp ${src_image} ${dst_image} |
| add_payloads ${dst_image} ${ro_payload} ${rw_payload} |
| sign_image ${dst_image} "${devkeys_dir}" |
| } |
| |
| # Build firmware images for a given board |
| # Creates image*.bin for the following images: |
| # image.bin - production image (no serial console) |
| # image.serial.bin - production image with serial console enabled |
| # image.dev.bin - developer image with serial console enabled |
| # image.net.bin - netboot image with serial console enabled |
| # image.fastboot.bin - fastboot image with serial console enabled |
| # image.fastboot-prod.bin - fastboot image (no serial console) |
| # |
| # If $2 is set, then it uses "image-$2" instead of "image" and puts images in |
| # the $2 subdirectory. |
| # |
| # If outdir |
| # Args: |
| # $1: Directory containing the input files: |
| # coreboot.rom - coreboot ROM image containing various pieces |
| # coreboot.rom.serial - same, but with serial console enabled |
| # depthcharge/depthcharge.elf - depthcharge ELF payload |
| # depthcharge/dev.elf - developer version of depthcharge |
| # depthcharge/netboot.elf - netboot version of depthcharge |
| # depthcharge/fastboot.elf - fastboot version of depthcharge |
| # rocbfs/* - fonts, images and screens for recovery mode |
| # $2: Name of model to build, used for output files (empty if no model) |
| build_images() { |
| local froot="$1" |
| local model="$2" |
| local outdir |
| local suffix |
| |
| local coreboot_file="${froot}/coreboot.rom" |
| |
| if [ -n "${model}" ]; then |
| einfo "Building firmware images for ${model}" |
| outdir="${model}/" |
| mkdir "${outdir}" |
| suffix="-${model}" |
| fi |
| |
| cp ${coreboot_file} coreboot.rom |
| cp ${coreboot_file}.serial coreboot.rom.serial |
| coreboot_file=coreboot.rom |
| |
| for file in $(find compressed-assets -type f 2>/dev/null); do |
| for rom in ${coreboot_file}{,.serial}; do |
| do_cbfstool ${rom} add \ |
| -r COREBOOT \ |
| -f $file -n $(basename $file) -t raw \ |
| -c precompression |
| done |
| done |
| |
| local legacy_file="" |
| prepare_legacy_image legacy_file |
| if [ -n "${legacy_file}" ]; then |
| einfo "Using legacy boot payload: ${legacy_file}" |
| if [ -f "${legacy_file}.serial" ]; then |
| do_cbfstool ${coreboot_file}.serial write \ |
| -f ${legacy_file}.serial --force -r RW_LEGACY |
| do_cbfstool ${coreboot_file} write \ |
| -f ${legacy_file} --force -r RW_LEGACY |
| else |
| do_cbfstool ${coreboot_file}.serial write \ |
| -f ${legacy_file} --force -r RW_LEGACY |
| do_cbfstool ${coreboot_file} write \ |
| -f ${legacy_file} --force -r RW_LEGACY |
| fi |
| fi |
| |
| local depthcharge="${froot}/depthcharge/depthcharge.elf" |
| local depthcharge_dev="${froot}/depthcharge/dev.elf" |
| local netboot="${froot}/depthcharge/netboot.elf" |
| local fastboot="${froot}/depthcharge/fastboot.elf" |
| |
| build_image "" "${coreboot_file}" "${depthcharge}" "${depthcharge}" |
| |
| build_image serial "${coreboot_file}.serial" \ |
| "${depthcharge}" "${depthcharge}" |
| |
| build_image dev "${coreboot_file}.serial" \ |
| "${depthcharge_dev}" "${depthcharge_dev}" |
| |
| # Build a netboot image. |
| # |
| # The readonly payload is usually depthcharge and the read/write |
| # payload is usually netboot. This way the netboot image can be used |
| # to boot from USB through recovery mode if necessary. |
| build_image net "${coreboot_file}.serial" "${depthcharge}" "${netboot}" |
| |
| # Set convenient netboot parameter defaults for developers. |
| local bootfile="${PORTAGE_USERNAME}/${BOARD_USE}/vmlinuz" |
| local argsfile="${PORTAGE_USERNAME}/${BOARD_USE}/cmdline" |
| "${S}"/setup/netboot_firmware_settings.py \ |
| -i "${outdir}image${suffix}.net.bin" \ |
| --bootfile="${bootfile}" --argsfile="${argsfile}" && |
| "${S}"/setup/netboot_firmware_settings.py \ |
| -i "${outdir}image${suffix}.dev.bin" \ |
| --bootfile="${bootfile}" --argsfile="${argsfile}" || |
| die "failed to preset netboot parameter defaults." |
| einfo "Netboot configured to boot ${bootfile}, fetch kernel command" \ |
| "line from ${argsfile}, and use the DHCP-provided TFTP server IP." |
| |
| if use fastboot ; then |
| build_image fastboot "${coreboot_file}.serial" \ |
| "${fastboot}" "${depthcharge}" |
| |
| build_image fastboot-prod "${coreboot_file}" \ |
| "${fastboot}" "${depthcharge}" |
| fi |
| } |
| |
| src_compile() { |
| local froot="${CROS_FIRMWARE_ROOT}" |
| |
| einfo "Compressing static assets" |
| # files from rocbfs/ are installed in all images' RO CBFS |
| mkdir compressed-assets |
| find ${froot}/rocbfs -mindepth 1 -maxdepth 1 -printf "%P\0" 2>/dev/null | \ |
| xargs -0 -n 1 -P $(nproc) -I '{}' \ |
| cbfs-compression-tool compress ${froot}/rocbfs/'{}' \ |
| compressed-assets/'{}' LZMA |
| |
| if use unibuild; then |
| local model |
| |
| for model in ${FIRMWARE_UNIBUILD}; do |
| build_images "${froot}/${model}" "${model}" |
| done |
| else |
| build_images "${froot}" "" |
| fi |
| } |
| |
| src_install() { |
| insinto "${CROS_FIRMWARE_IMAGE_DIR}" |
| if use unibuild; then |
| local model |
| |
| for model in ${FIRMWARE_UNIBUILD}; do |
| doins "${model}"/image-${model}*.bin |
| done |
| else |
| doins image*.bin |
| fi |
| } |