blob: 5373c9ce46b07d366e035b9dc0a685fbd3995e28 [file] [log] [blame]
#
# Copyright (c) 2010-2011 Nest, Inc.
# All rights reserved.
#
# This document is the property of Nest Labs. It is considered
# confidential and proprietary information.
#
# This document may not be reproduced or transmitted in any form,
# in whole or in part, without the express written permission of
# Nest Labs.
#
# Description:
# This file is the makefile for the Universal Bootloader, u-boot.
#
.NOTPARALLEL:
include pre.mak
PackageRoot := .
PackageSeparator :=
PackageVersion :=
PackageSourceDir := $(UBootPackageName)$(PackageSeparator)$(PackageVersion)
PackageBuildMakefile = $(call GenerateBuildPaths,include/config.mk)
CleanPaths += $(PackageLicenseFile)
CP = cp
DD = dd
LN = ln
TAR = tar
MKDIR = mkdir
CHMOD = chmod
PRINTF = printf
PUSHD = pushd
POPD = popd
FSL_HAB_SIGN = $(BuildRoot)/build/scripts/fsl_hab_sign.sh
FSL_CST = $(BuildRoot)/build/tools/host/i686-pc-linux-gnu/bin/freescale-cst
MAKE_FIT = $(UsbLoaderImxSourcesPath)/scripts/make_fit.sh
#
# Build and result paths for staging targets
#
UBootResultBinDir := $(call GenerateResultPaths,,bin)
UBootResultSbinDir := $(call GenerateResultPaths,,sbin)
UBootPrintEnvBuildPath := $(call GenerateBuildPaths,tools/env/fw_printenv)
UBootPrintEnvResultPath := $(call GenerateResultPaths,,sbin/fw_printenv)
UBootSetEnvResultPath := $(call GenerateResultPaths,,sbin/fw_setenv)
UBootMkimageBuildPath := $(call GenerateBuildPaths,tools/mkimage)
UBootMkimageResultPath := $(call GenerateResultPaths,,bin/mkimage)
LinuxItbBuildPaths = $(call GenerateBuildPaths,$(LinuxItbResultFile))
LinuxItbResultPaths = $(call GenerateResultPaths,,$(LinuxItbResultFile))
LinuxDtbResultPaths = $(addprefix $(LinuxResultsPath)/,$(LinuxDtbFiles))
ifneq ($(words $(LinuxDtbFiles)), $(words $(LinuxDtbNames)))
$(error The number of DTB files and DTB names for use in the ITB do not match: $(words $(LinuxDtbFiles)) != $(words $(LinuxDtbNames)))
else
# We need to join the list of DTB files and names for make_fit.sh, so it can generate a FIT with all of the DTB files.
# GNU make doesn't do this well (the join function leaves no spaces between the pairs to be joined); this is the most readable solution I could find.
i=0
dtb_list=
$(foreach dtbName, $(LinuxDtbNames), \
$(eval i = $(shell expr $(i) + 1)) \
$(eval dtb_list += $(abspath $(word $(i),$(LinuxDtbResultPaths))) $(dtbName)) \
)
endif
zImageFile := zImage
zImageResultPath := $(addprefix $(LinuxResultsPath)/,$(zImageFile))
UnsignedUBootBuildPath := $(call GenerateBuildPaths,$(UBootImageFile))
#
# If UBootSignedImageFile AND UBootSignedSDPImageFile are defined, we need to do
# an extra step and sign UBootImageFile to produce signed binaries.
#
# There are three different ways we can generate this signed binary:
# 1) Copy a signed image from within the Git repo* [ Default behavior if the appropriate signed image folder is present ]
# 2) Copy an unsigned image from the build folder* [ Fallback behavior if the appropriate signed image folder is not present (deleted or not yet present) ]
# 3) Sign it locally using the private keys [ Force this by passing 'SIGN_BOOTLOADER=true' on make cmdline ]
#
# *Also generates a signing .tgz archive in the u-boot results folder that can be unpacked on an offline
# signing workstation that has the necessary signing keys and used to sign the image. It contains:
# 1) The code signing binary: freescale-cst
# 2) The code signing helper script: fsl_hab_sign.sh
# 3) The unsigned u-boot image
# 4) A top-level signing script that defines the input and output filenames, for documentation purposes, and so that we are consistent.
#
ifneq "$(and $(UBootSignedImageFile),$(UBootSignedSDPImageFile))" ""
SignedUBootResultPath = $(call GenerateResultPaths,,$(UBootSignedImageFile))
SignedSDPUBootResultPath= $(call GenerateResultPaths,,$(UBootSignedSDPImageFile))
BuildResults = $(SignedUBootResultPath) $(SignedSDPUBootResultPath) $(LinuxItbResultPaths)
# Generate a signing .tgz archive
UBootSigningArchiveResultPath = $(call GenerateResultPaths,,u-boot-unsigned-$(GeneratedBuildLabel).tgz)
define SIGNING_SCRIPT
#!/bin/bash
set -e
# Check the input args
if [ $${#} -ne 2 ]; then
name=`basename $${0}`
echo "Usage: $${name} <password file> <key dir>"
exit 1
elif [ ! -f $${1} ]; then
echo "Password file not found: $${1}"
exit 1
elif [ ! -d $${2} ]; then
echo "Key dir not found: $${2}"
exit 1
fi
./$(notdir $(FSL_HAB_SIGN)) --passin $${1} --keypath $${2} $(basename $(UBootImageFile))-$(GeneratedBuildLabel)$(suffix $(UBootImageFile)) $(basename $(UBootSignedImageFile))-$(GeneratedBuildLabel)$(suffix $(UBootSignedImageFile))
./$(notdir $(FSL_HAB_SIGN)) --sdp --passin $${1} --keypath $${2} $(basename $(UBootImageFile))-$(GeneratedBuildLabel)$(suffix $(UBootImageFile)) $(basename $(UBootSignedImageFile))-sdp-$(GeneratedBuildLabel)$(suffix $(UBootSignedImageFile))
echo "Done, no errors"
endef
export SIGNING_SCRIPT
GenerateUBootSigningArchive = $(eval TMPDIR := $(shell mktemp -d)) \
$(MKDIR) -p $(TMPDIR)/$(BuildProduct)/$(BuildConfig) && \
$(CP) $(FSL_HAB_SIGN) $(TMPDIR)/$(BuildProduct)/$(BuildConfig) && \
$(CP) $(FSL_CST) $(TMPDIR)/$(BuildProduct)/$(BuildConfig) && \
$(CP) $(1) $(TMPDIR)/$(BuildProduct)/$(BuildConfig)/$(basename $(UBootImageFile))-$(GeneratedBuildLabel)$(suffix $(UBootImageFile)) && \
$(PRINTF) "$$SIGNING_SCRIPT" > $(TMPDIR)/$(BuildProduct)/$(BuildConfig)/sign.sh && \
$(CHMOD) u+x $(TMPDIR)/$(BuildProduct)/$(BuildConfig)/sign.sh && \
$(PUSHD) $(TMPDIR) && sha256sum $(BuildProduct)/$(BuildConfig)/* > $(BuildProduct)/$(BuildConfig)/SHA256SUMS && $(POPD) && \
$(TAR) -czf $(UBootSigningArchiveResultPath) --directory $(TMPDIR) $(BuildProduct) && \
$(RM) -rf $(TMPDIR)
ifdef SIGN_BOOTLOADER
# This is option (3) above
# This option also copies the signed result, places it into the signed u-boot images folder with a name that reflects the
# build label (tag, last commit hash, etc) and updates the symlinks to it so that it is ready to commit into the repo.
GenerateSignedResult = $(Echo) "Signing result \"$(call GenerateBuildRootEllipsedPath,$2)\" locally" && \
$(FSL_HAB_SIGN) $(3) $(1) $(2) && \
$(CP) $(2) $(UBootSignedImagesFolder)/$(basename $(notdir $(2)))$(GeneratedBuildLabel)$(suffix $(2)) && \
$(LN) -fs $(basename $(notdir $(2)))$(GeneratedBuildLabel)$(suffix $(2)) $(UBootSignedImagesFolder)/$(notdir $(2))
else ifneq ($(wildcard $(UBootSignedImagesFolder)),)
# This is option (1) above
GenerateSignedResult = $(Echo) "Copying signed result \"$(call GenerateBuildRootEllipsedPath,$2)\" from repo ($(UBootSignedImagesFolder)/$(notdir $(2)))" && \
$(call GenerateUBootSigningArchive,$(1)) && \
$(CP) $(UBootSignedImagesFolder)/$(notdir $(2)) $(2)
else
# This is option (2) above
#
# Note that setting CONFIG_SECURE_BOOT in the U-boot config causes a 'CSF 0x2000' command to be
# added to the mkimage config, which causes the CSF field in the the IVT header to be nonzero,
# and increases the length of the image given in the header by 0x2000 Bytes. If cases such as this,
# where we don't actually do the signing and append the CSF data, we need to zero the field and
# append 0x2000 Bytes of zeros, so that the boot ROM won't die trying to read it.
GenerateSignedResult = $(Echo) "Copying result \"$(call GenerateBuildRootEllipsedPath,$2)\" without signing" && \
$(call GenerateUBootSigningArchive,$(1)) && \
$(CP) $(1) $(2) && \
$(DD) if=/dev/zero of=$(2) seek=24 bs=1 count=4 conv=notrunc > /dev/null 2>&1 && \
$(DD) if=/dev/zero of=$(2) bs=$$((0x2000)) count=1 conv=notrunc oflag=append > /dev/null 2>&1
endif
else
UnsignedUBootResultPath = $(call GenerateResultPaths,,$(UBootImageFile))
BuildResults = $(UnsignedUBootResultPath)
endif
NestBuildDefines := NEST_BUILD_CONFIG_$(call ToUpper,$(BuildConfig)) NEST_BUILD_CONFIG=\\\"$(BuildConfig)\\\"
NestBuildDefineFlags := $(call ToolGenerateDefineArgument,$(NestBuildDefines))
# The diamond1 and j49 u-boot builds require the HOSTCC and HOSTSTRIP flags to point to the cross-toolchain so that
# fw_printenv/fw_setenv will be built for the target arch. Doing this with the newer (2014.04) diamond3 and flintstone
# builds causes the host tools to be cross-compiled, and is unnecessary, which is more in line with what seems logical.
ifeq ($(UBootPackageName),u-boot)
toolHostCCFlags = HOSTCC="$(CC)" HOSTSTRIP=$(STRIP)
else
toolHostCCFlags =
endif
SOURCEDIRS = $(PackageSourceDir)
$(PackageSourceDir)_RULE_TARGET = $(BuildDirectory)/configure
all: $(PackageDefaultGoal)
# Generate the package license contents.
$(PackageSourceDir)/COPYING: source
$(PackageLicenseFile): $(PackageSourceDir)/COPYING
$(copy-result)
# Prepare the sources.
.PHONY: source
$(BuildDirectory)/source: | $(PackageSourceDir) $(BuildDirectory)
$(Verbose)touch $@
# Patch the sources, if necessary.
.PHONY: patch
$(BuildDirectory)/patch: $(BuildDirectory)/source
$(Verbose)touch $@
# U-Boot has no way of explicitly setting CC, LD, OBJCOPY, et al and
# instead relies on the value of CROSS_COMPILE. Consequently, we have
# to ensure that 'ToolBinDir' is in 'PATH' so that the kernel build
# infrastructure can find $(CROSS_COMPILE)gcc, $(CROSS_COMPILE)ld, et
# al.
$(BuildDirectory)/configure $(BuildDirectory)/build $(BuildDirectory)/stage: PATH := $(PATH):$(ToolBinDir)
$(BuildDirectory)/configure $(BuildDirectory)/build $(BuildDirectory)/stage: CROSS_COMPILE := $(CCACHE) $(CROSS_COMPILE)
$(BuildDirectory)/configure $(BuildDirectory)/build $(BuildDirectory)/stage: export KCFLAGS = "$(if $(ToolSysRootDir),--sysroot=$(ToolSysRootDir))"
# Generate the package build makefile.
# Configure the source for building.
$(BuildDirectory)/configure: $(BuildDirectory)/source | $(PackageSourceDir) $(BuildDirectory)
$(Verbose)unset MAKEFLAGS && \
$(MAKE) $(JOBSFLAG) -C $(PackageSourceDir) \
INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
O=$(CURDIR)/$(BuildDirectory) \
$(if $(BuildVerbose),V=$(BuildVerbose)) \
$(UBootDefaultConfig)
$(Verbose)touch $@
# Build the source.
$(BuildDirectory)/build: $(UnsignedUBootBuildPath)
$(Verbose)touch $@
$(UnsignedUBootBuildPath): $(BuildDirectory)/configure
$(Verbose)unset MAKEFLAGS && \
$(MAKE) $(JOBSFLAG) -C $(PackageSourceDir) \
INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
O=$(CURDIR)/$(BuildDirectory) \
$(if $(BuildVerbose),V=$(BuildVerbose)) \
NestBuildDefineFlags="$(NestBuildDefineFlags)" \
all
$(UBootPrintEnvBuildPath): $(BuildDirectory)/configure $(UnsignedUBootBuildPath)
$(Verbose)unset MAKEFLAGS && \
$(MAKE) $(JOBSFLAG) -C $(PackageSourceDir) \
INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
CC="$(CC) $(CPPOPTFLAGS) -isystem $(LinuxIncludePath)" \
O=$(CURDIR)/$(BuildDirectory) \
$(if $(BuildVerbose),V=$(BuildVerbose)) \
$(toolHostCCFlags) \
TOOLSUBDIRS=env \
NestBuildDefineFlags="$(NestBuildDefineFlags)" \
env tools
$(LinuxItbBuildPaths): $(UBootMkimageResultPath) $(zImageResultPath) $(LinuxDtbResultPaths)
$(Verbose)$(MAKE_FIT) $(UBootMkimageResultPath) \
$(abspath $(zImageResultPath)) \
NULL \
"$(KernelSigningKeyName)" \
"$(KernelSigningKeyURL)" \
$(LinuxItbBuildPaths) \
$(dtb_list) # Combine the kernel and DTBs into a FIT
# Stage the build to a temporary installation area.
#
# U-Boot does not support a notion of installing, so we have to
# cherry-pick the components we want from the build directory and
# copy/install them to the results directory.
.PHONY: stage
stage: $(BuildDirectory)/stage
$(BuildDirectory)/stage: $(BuildDirectory)/stage-target $(BuildDirectory)/stage-target-tools $(BuildDirectory)/stage-host-tools
$(Verbose)touch $@
$(BuildDirectory)/stage-target: $(BuildResults)
$(Verbose)$(CP) -f $(call GenerateBuildPaths,System.map) $(ResultDirectory)
$(Verbose)touch $@
$(BuildDirectory)/stage-target-tools: $(UBootPrintEnvResultPath) $(UBootSetEnvResultPath)
$(Verbose)touch $@
$(BuildDirectory)/stage-host-tools: $(UBootMkimageResultPath)
$(Verbose)touch $@
#
# Targets and commands for signing compiled images.
# Generates a regular signed image for NAND boot AND a special SDP one for USB DFU boot
#
$(UnsignedUBootResultPath): $(UnsignedUBootBuildPath) | $(ResultDirectory)
$(Verbose)$(CP) -f $< $@
$(SignedUBootResultPath): $(UnsignedUBootBuildPath) | $(ResultDirectory)
$(Verbose)$(call GenerateSignedResult,$<,$@,)
$(SignedSDPUBootResultPath): $(UnsignedUBootBuildPath) | $(ResultDirectory)
$(Verbose)$(call GenerateSignedResult,$<,$@,--sdp)
#
# Targets and commands for staging target (i.e cross-compiled) tools.
#
$(UBootResultSbinDir):
$(create-directory)
$(UBootPrintEnvResultPath): $(UBootPrintEnvBuildPath) | $(UBootResultSbinDir)
$(copy-result)
$(UBootSetEnvResultPath): $(UBootPrintEnvBuildPath) | $(UBootResultSbinDir)
$(Echo) "Creating \"$(call GenerateBuildRootEllipsedPath,$@)\""
$(Verbose)ln -sf fw_printenv "$(@)"
#
# Targets and commands for staging host (i.e. natively-compiled) tools
# that may be used elsewhere in the build.
#
$(UBootResultBinDir):
$(create-directory)
$(UBootMkimageBuildPath): $(BuildDirectory)/build
$(UBootMkimageResultPath): $(UBootMkimageBuildPath) | $(UBootResultBinDir)
$(copy-result)
$(LinuxItbResultPaths): $(LinuxItbBuildPaths)
$(copy-result)
clean:
$(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory)
$(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory)
include post.mak