| # | |
| # 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 |