mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-20 21:43:11 +00:00
f9d143d77a
- Add kgpe-d16 patch to remove HID for PCI devices (successful build on top of #1101 and #1012 per https://app.circleci.com/pipelines/github/tlaurion/heads/937/workflows/de49bea0-3f58-4a91-8891-87622f5a0eed) - CircleCI modified to build for coreboot 4.11 kgpe-d16_workstation on top of 4.15 passed workspace - CircleCI modified so that we still archive all the logs in artifacts for the current build even if failing. We now exit 1 after having archived all the log files under build/ - Add xx30 vbios extract scripts to test. Expecting musl-cross target to fail since make and gawk aren't built - CircleCI: gawk was not installed in apt statements under Debian. Installing - Makefile: seperate and fix local make and gawk building pror of using. Otherwise, impossible to build musl-cross target seperatly. - Also give some debugging info at start of Heads builds to tell which local gawk and make are used, also telling which make call will be propagated in the rest of the builds - Fix gawk version checking, reporting bad version even if 4.2.1 as expected on debian-10 (debian-10 OS deploys gawk and make in version 4.2.1) - CircleCI: Changing musl-cross taget to bootstrap (gawk+make) and musl-cross-make (bootstrap_musl-cross-make) for clarity
708 lines
20 KiB
Makefile
708 lines
20 KiB
Makefile
# Need to set CB_OUTPUT_FILE before board .config included so
|
|
# that target overrides in x230/x430-flash (eg) are properly handled
|
|
GIT_HASH := $(shell git rev-parse HEAD)
|
|
GIT_STATUS := $(shell \
|
|
if git diff --exit-code >/dev/null ; then \
|
|
echo clean ; \
|
|
else \
|
|
echo dirty ; \
|
|
fi)
|
|
HEADS_GIT_VERSION := $(shell git describe --tags --dirty)
|
|
|
|
CB_OUTPUT_FILE := heads-$(BOARD)-$(HEADS_GIT_VERSION).rom
|
|
CB_BOOTBLOCK_FILE := heads-$(BOARD)-$(HEADS_GIT_VERSION).bootblock
|
|
LB_OUTPUT_FILE := linuxboot-$(BOARD)-$(HEADS_GIT_VERSION).rom
|
|
|
|
all:
|
|
-include .config
|
|
|
|
ifneq "$(TOOLCHAIN)" ""
|
|
$(info Using $(TOOLCHAIN) for cross compiler and packages)
|
|
packages ?= $(TOOLCHAIN)/packages
|
|
CROSS := $(TOOLCHAIN)/crossgcc/x86_64-linux-musl/bin/x86_64-linux-musl-
|
|
endif
|
|
|
|
modules-y :=
|
|
pwd := $(shell pwd)
|
|
packages ?= $(pwd)/packages
|
|
build := $(pwd)/build
|
|
config := $(pwd)/config
|
|
INSTALL := $(pwd)/install
|
|
log_dir := $(build)/log
|
|
|
|
# Controls how many parallel jobs are invoked in subshells
|
|
CPUS ?= $(shell nproc)
|
|
MAKE_JOBS ?= -j$(CPUS) --max-load 16
|
|
|
|
# Create the log directory if it doesn't already exist
|
|
BUILD_LOG := $(shell mkdir -p "$(log_dir)" )
|
|
|
|
WGET ?= wget
|
|
|
|
# Timestamps should be in ISO format
|
|
DATE=`date --rfc-3339=seconds`
|
|
|
|
# Check that we have a correct version of make
|
|
# that matches at least the major version
|
|
LOCAL_MAKE_VERSION := $(shell $(MAKE) --version | head -1 | cut -d' ' -f3)
|
|
include modules/make
|
|
|
|
# Check we have a suitable version of gawk
|
|
# that's at least the same major version
|
|
LOCAL_GAWK_VERSION := $(shell gawk --version 2>/dev/null | head -1 | cut -d' ' -f3 | cut -d, -f1)
|
|
LOCAL_GAWK_MAJOR_VERSION := $(patsubst .%,.,$(LOCAL_GAWK_VERSION))
|
|
include modules/gawk
|
|
|
|
ifeq "" "$(filter $(make_version)%,$(LOCAL_MAKE_VERSION))"
|
|
# This is incorrect local version of make
|
|
# Wrong make version detected -- build our local version
|
|
# and re-invoke the Makefile with it instead.
|
|
$(eval $(shell echo >&2 "$(DATE) Wrong OS deployed make detected: $(LOCAL_MAKE_VERSION). Building and using $(make_version)..." ))
|
|
HEADS_MAKE := $(build)/$(make_dir)/make
|
|
|
|
# How to download and build the correct version of make
|
|
$(packages)/$(make_tar):
|
|
$(WGET) -O "$@.tmp" "$(make_url)"
|
|
if ! echo "$(make_hash) $@.tmp" | sha256sum --check -; then \
|
|
exit 1 ; \
|
|
fi
|
|
mv "$@.tmp" "$@"
|
|
|
|
$(build)/$(make_dir)/.extract: $(packages)/$(make_tar)
|
|
tar xf "$<" -C "$(build)"
|
|
touch "$@"
|
|
|
|
$(build)/$(make_dir)/.patch: $(build)/$(make_dir)/.extract
|
|
( cd "$(dir $@)" ; patch -p1 ) < "patches/make-$(make_version).patch"
|
|
touch "$@"
|
|
|
|
$(build)/$(make_dir)/.configured: $(build)/$(make_dir)/.patch
|
|
cd "$(dir $@)" ; \
|
|
./configure 2>&1 \
|
|
| tee "$(log_dir)/make.configure.log" \
|
|
$(VERBOSE_REDIRECT)
|
|
touch "$@"
|
|
|
|
$(HEADS_MAKE): $(build)/$(make_dir)/.configured
|
|
make -C "$(dir $@)" $(MAKE_JOBS) \
|
|
2>&1 \
|
|
| tee "$(log_dir)/make.log" \
|
|
$(VERBOSE_REDIRECT)
|
|
|
|
# Once we have a proper Make, we can just pass arguments into it
|
|
all linux cpio run: $(HEADS_MAKE)
|
|
LANG=C MAKE=$(HEADS_MAKE) $(HEADS_MAKE) $(MAKE_JOBS) $@
|
|
%.clean %.vol %.menuconfig: $(HEADS_MAKE)
|
|
LANG=C MAKE=$(HEADS_MAKE) $(HEADS_MAKE) $@
|
|
|
|
bootstrap: $(HEADS_MAKE)
|
|
endif
|
|
|
|
# Wrong gawk version
|
|
ifeq "" "$(filter $(LOCAL_GAWK_MAJOR_VERSION)%,$(gawk_version))"
|
|
# Wrong gawk version detected -- build our local version
|
|
# and re-invoke the Makefile with it instead.
|
|
$(eval $(shell echo >&2 "$(DATE) Wrong OS deployed gawk detected: $(LOCAL_GAWK_VERSION). Building and using $(gawk_version)..."))
|
|
HEADS_GAWK := $(build)/$(gawk_dir)/gawk
|
|
|
|
# How to download and build the correct version of gawk
|
|
$(packages)/$(gawk_tar):
|
|
$(WGET) -O "$@.tmp" "$(gawk_url)"
|
|
if ! echo "$(gawk_hash) $@.tmp" | sha256sum --check -; then \
|
|
exit 1 ; \
|
|
fi
|
|
mv "$@.tmp" "$@"
|
|
|
|
$(build)/$(gawk_dir)/.extract: $(packages)/$(gawk_tar)
|
|
tar xf "$<" -C "$(build)"
|
|
touch "$@"
|
|
|
|
$(build)/$(gawk_dir)/.patch: $(build)/$(gawk_dir)/.extract
|
|
# ( cd "$(dir $@)" ; patch -p1 ) < "patches/gawk-$(gawk_version).patch"
|
|
touch "$@"
|
|
|
|
$(build)/$(gawk_dir)/.configured: $(build)/$(gawk_dir)/.patch
|
|
cd "$(dir $@)" ; \
|
|
./configure 2>&1 \
|
|
| tee "$(log_dir)/gawk.configure.log" \
|
|
$(VERBOSE_REDIRECT)
|
|
touch "$@"
|
|
|
|
$(HEADS_GAWK): $(build)/$(gawk_dir)/.configured
|
|
$(MAKE) -C "$(dir $@)" $(MAKE_JOBS) \
|
|
2>&1 \
|
|
| tee "$(log_dir)/gawk.log" \
|
|
$(VERBOSE_REDIRECT)
|
|
|
|
# Once we have a suitable version of gawk, we can rerun make
|
|
all linux cpio run: $(HEADS_GAWK)
|
|
LANG=C HEADS_GAWK=$(HEADS_GAWK) $(MAKE) $(MAKE_JOBS) $@
|
|
%.clean %.vol %.menuconfig: $(HEADS_GAWK)
|
|
LANG=C HEADS_GAWK=$(HEADS_GAWK) $(MAKE) $@
|
|
|
|
bootstrap: $(HEADS_GAWK)
|
|
endif
|
|
|
|
BOARD ?= qemu-coreboot
|
|
CONFIG := $(pwd)/boards/$(BOARD)/$(BOARD).config
|
|
|
|
ifneq "y" "$(shell [ -r '$(CONFIG)' ] && echo y)"
|
|
$(error $(CONFIG): board configuration does not exist)
|
|
endif
|
|
|
|
include $(CONFIG)
|
|
|
|
# Unless otherwise specified, we are building for heads
|
|
CONFIG_HEADS ?= y
|
|
|
|
# record the build date / git hashes and other files here
|
|
HASHES := $(build)/$(BOARD)/hashes.txt
|
|
|
|
# Create the board output directory if it doesn't already exist
|
|
BOARD_LOG := $(shell \
|
|
mkdir -p "$(build)/$(BOARD)" ; \
|
|
echo "$(DATE) $(GIT_HASH) $(GIT_STATUS)" > "$(HASHES)" ; \
|
|
)
|
|
|
|
ifeq "y" "$(CONFIG_LINUX_BUNDLED)"
|
|
# Create empty initrd for initial kernel "without" initrd.
|
|
$(shell cpio -o < /dev/null > $(build)/$(BOARD)/initrd.cpio)
|
|
endif
|
|
|
|
# If V is set in the environment, do not redirect the tee
|
|
# command to /dev/null.
|
|
ifeq "$V" ""
|
|
VERBOSE_REDIRECT := > /dev/null
|
|
# Not verbose, so we only show the header
|
|
define do =
|
|
@echo "$(DATE) $1 $(2:$(pwd)/%=%)"
|
|
@$3
|
|
endef
|
|
else
|
|
# Verbose, so we display what we are doing
|
|
define do =
|
|
@echo "$(DATE) $1 $(2:$(pwd)/%=%)"
|
|
$3
|
|
endef
|
|
endif
|
|
|
|
|
|
# Create a temporary directory for the initrd
|
|
initrd_dir := $(BOARD)
|
|
initrd_tmp_dir := $(shell mktemp -d)
|
|
initrd_lib_dir := $(initrd_tmp_dir)/lib
|
|
initrd_bin_dir := $(initrd_tmp_dir)/bin
|
|
modules-y += initrd
|
|
|
|
$(shell mkdir -p "$(initrd_lib_dir)" "$(initrd_bin_dir)")
|
|
|
|
# We are running our own version of make,
|
|
# proceed with the build.
|
|
|
|
# Force pipelines to fail if any of the commands in the pipe fail
|
|
SHELL := /bin/bash
|
|
.SHELLFLAGS := -o pipefail -c
|
|
|
|
# Include the musl-cross module early so that $(CROSS) will
|
|
# be defined prior to any other module.
|
|
include modules/musl-cross
|
|
|
|
musl_dep := musl-cross
|
|
heads_cc := $(CROSS)gcc \
|
|
-fdebug-prefix-map=$(pwd)=heads \
|
|
-gno-record-gcc-switches \
|
|
-D__MUSL__ \
|
|
-isystem $(INSTALL)/include \
|
|
-L$(INSTALL)/lib \
|
|
|
|
CROSS_TOOLS_NOCC := \
|
|
AR="$(CROSS)ar" \
|
|
LD="$(CROSS)ld" \
|
|
STRIP="$(CROSS)strip" \
|
|
NM="$(CROSS)nm" \
|
|
OBJCOPY="$(CROSS)objcopy" \
|
|
OBJDUMP="$(CROSS)objdump" \
|
|
PKG_CONFIG_PATH="$(INSTALL)/lib/pkgconfig" \
|
|
PKG_CONFIG_SYSROOT_DIR="$(INSTALL)" \
|
|
|
|
ifneq "$(HEADS_GAWK)" ""
|
|
CROSS_TOOLS_NOCC += AWK=$(HEADS_GAWK)
|
|
endif
|
|
|
|
ifneq "$(HEADS_MAKE)" ""
|
|
MAKE=$(HEADS_MAKE)
|
|
endif
|
|
|
|
#Some debugging info in link with locally built versions and usage for the rest Heads build:
|
|
$(eval $(shell echo >&2 "$(DATE) Local built HEADS_GAWK only if different then provided by OS: $(HEADS_GAWK)"))
|
|
$(eval $(shell echo >&2 "$(DATE) Local built HEADS_MAKE only if different then provided by OS: $(HEADS_MAKE)"))
|
|
$(eval $(shell echo >&2 "$(DATE) Heads build system will call make from now on as: MAKE: $(MAKE)." ))
|
|
|
|
|
|
CROSS_TOOLS := \
|
|
CC="$(heads_cc)" \
|
|
$(CROSS_TOOLS_NOCC) \
|
|
|
|
|
|
|
|
ifeq ($(CONFIG_COREBOOT), y)
|
|
|
|
all: $(build)/$(BOARD)/$(CB_OUTPUT_FILE)
|
|
ifneq ($(CONFIG_COREBOOT_BOOTBLOCK),)
|
|
all: $(build)/$(BOARD)/$(CB_BOOTBLOCK_FILE)
|
|
endif
|
|
|
|
else ifeq ($(CONFIG_LINUXBOOT), y)
|
|
all: $(build)/$(BOARD)/$(LB_OUTPUT_FILE)
|
|
else
|
|
$(error "$(BOARD): neither CONFIG_COREBOOT nor CONFIG_LINUXBOOT is set?")
|
|
endif
|
|
|
|
all:
|
|
@sha256sum $< | tee -a "$(HASHES)"
|
|
|
|
# Disable all built in rules
|
|
.INTERMEDIATE:
|
|
.SUFFIXES:
|
|
FORCE:
|
|
|
|
# Make helpers to operate on lists of things
|
|
# Prefix is "smart" and doesn't add the prefix for absolute file paths
|
|
define prefix =
|
|
$(foreach _, $2, $(if $(patsubst /%,,$_),$1$_,$_))
|
|
endef
|
|
define map =
|
|
$(foreach _,$2,$(eval $(call $1,$_)))
|
|
endef
|
|
|
|
# Bring in all of the module definitions;
|
|
# these are the external pieces that will be downloaded and built
|
|
# as part of creating the Heads firmware image.
|
|
include modules/*
|
|
|
|
define bins =
|
|
$(foreach m,$1,$(call prefix,$(build)/$($m_dir)/,$($m_output)))
|
|
endef
|
|
define libs =
|
|
$(foreach m,$1,$(call prefix,$(build)/$($m_dir)/,$($m_libraries)))
|
|
endef
|
|
|
|
define outputs =
|
|
$(foreach m,$1,\
|
|
$(call bins,$m)\
|
|
$(call libs,$m)\
|
|
)
|
|
endef
|
|
|
|
#
|
|
# Build a cpio from a directory
|
|
#
|
|
define do-cpio =
|
|
$(call do,CPIO ,$1,\
|
|
( cd "$2"; \
|
|
find . \
|
|
| cpio \
|
|
--quiet \
|
|
-H newc \
|
|
-o \
|
|
) \
|
|
| ./bin/cpio-clean \
|
|
> "$1.tmp" \
|
|
)
|
|
@if ! cmp --quiet "$1.tmp" "$1" ; then \
|
|
mv "$1.tmp" "$1" ; \
|
|
else \
|
|
echo "$(DATE) UNCHANGED $(1:$(pwd)/%=%)" ; \
|
|
rm "$1.tmp" ; \
|
|
fi
|
|
@sha256sum "$1" | tee -a "$(HASHES)"
|
|
$(call do,HASHES , $1,\
|
|
( cd "$2"; \
|
|
echo "-----" ; \
|
|
find . -type f -print0 \
|
|
| xargs -0 sha256sum ; \
|
|
echo "-----" ; \
|
|
) >> "$(HASHES)" \
|
|
)
|
|
endef
|
|
|
|
define do-copy =
|
|
$(call do,INSTALL ,$1 => $2,\
|
|
if cmp --quiet "$1" "$2" ; then \
|
|
echo "$(DATE) UNCHANGED $(1:$(pwd)/%=%)" ; \
|
|
fi ; \
|
|
cp -a "$1" "$2" ; \
|
|
)
|
|
@sha256sum "$(2:$(pwd)/%=%)"
|
|
endef
|
|
|
|
|
|
#
|
|
# Generate the targets for a module.
|
|
#
|
|
# Special variables like $@ must be written as $$@ to avoid
|
|
# expansion during the first evaluation.
|
|
#
|
|
define define_module =
|
|
# if they have not defined a separate base dir, define it
|
|
# as the same as their build dir.
|
|
$(eval $1_base_dir = $(or $($1_base_dir),$($1_dir)))
|
|
|
|
ifneq ("$($1_repo)","")
|
|
$(eval $1_patch_name = $1$(if $($1_patch_version),-$($1_patch_version),))
|
|
# Checkout the tree instead and touch the canary file so that we know
|
|
# that the files are all present. No signature hashes are checked in
|
|
# this case, since we don't have a stable version to compare against.
|
|
$(build)/$($1_base_dir)/.canary:
|
|
git clone $($1_repo) "$(build)/$($1_base_dir)"
|
|
cd $(build)/$($1_base_dir) && git submodule update --init --checkout
|
|
if [ -r patches/$($1_patch_name).patch ]; then \
|
|
( cd $(build)/$($1_base_dir) ; patch -p1 ) \
|
|
< patches/$($1_patch_name).patch \
|
|
|| exit 1 ; \
|
|
fi
|
|
if [ -d patches/$($1_patch_name) ] && \
|
|
[ -r patches/$($1_patch_name) ] ; then \
|
|
for patch in patches/$($1_patch_name)/*.patch ; do \
|
|
echo "Applying patch file : $$$$patch " ; \
|
|
( cd $(build)/$($1_base_dir) ; patch -p1 ) \
|
|
< $$$$patch \
|
|
|| exit 1 ; \
|
|
done ; \
|
|
fi
|
|
@touch "$$@"
|
|
else
|
|
$(eval $1_patch_version ?= $($1_version))
|
|
$(eval $1_patch_name = $1-$($1_patch_version))
|
|
# Fetch and verify the source tar file
|
|
# wget creates it early, so we have to cleanup if it fails
|
|
$(packages)/$($1_tar):
|
|
$(call do,WGET,$($1_url),\
|
|
if ! $(WGET) -O "$$@.tmp" $($1_url) ; then \
|
|
exit 1 ; \
|
|
fi ; \
|
|
mv "$$@.tmp" "$$@" \
|
|
)
|
|
$(packages)/.$1-$($1_version)_verify: $(packages)/$($1_tar)
|
|
echo "$($1_hash) $$^" | sha256sum --check -
|
|
@touch "$$@"
|
|
|
|
# Unpack the tar file and touch the canary so that we know
|
|
# that the files are all present
|
|
$(build)/$($1_base_dir)/.canary: $(packages)/.$1-$($1_version)_verify
|
|
mkdir -p "$$(dir $$@)"
|
|
tar -xf "$(packages)/$($1_tar)" $(or $($1_tar_opt),--strip 1) -C "$$(dir $$@)"
|
|
if [ -r patches/$($1_patch_name).patch ]; then \
|
|
( cd $$(dir $$@) ; patch -p1 ) \
|
|
< patches/$($1_patch_name).patch \
|
|
|| exit 1 ; \
|
|
fi
|
|
if [ -d patches/$($1_patch_name) ] && \
|
|
[ -r patches/$($1_patch_name) ] ; then \
|
|
for patch in patches/$($1_patch_name)/*.patch ; do \
|
|
echo "Applying patch file : $$$$patch " ; \
|
|
( cd $$(dir $$@) ; patch -p1 ) \
|
|
< $$$$patch \
|
|
|| exit 1 ; \
|
|
done ; \
|
|
fi
|
|
@touch "$$@"
|
|
endif
|
|
|
|
# Allow the module to override the destination configuration file
|
|
# via a relative path. Linux uses this to have a per-board build.
|
|
$(eval $1_config_file_path := $(build)/$($1_dir)/$(or $($1_config_file),.config))
|
|
|
|
ifeq "$($1_config)" ""
|
|
# There is no official .config file
|
|
$($1_config_file_path): $(build)/$($1_base_dir)/.canary
|
|
@mkdir -p $$(dir $$@)
|
|
@touch "$$@"
|
|
else
|
|
# Copy the stored config file into the unpacked directory
|
|
$($1_config_file_path): $($1_config) $(build)/$($1_base_dir)/.canary
|
|
@mkdir -p $$(dir $$@)
|
|
$(call do-copy,$($1_config),$$@)
|
|
endif
|
|
|
|
# The first time we have to wait for all the dependencies to be built
|
|
# before we can configure the target. Once the dep has been built,
|
|
# we only depend on it for a rebuild.
|
|
$(eval $1_config_wait := $(foreach d,$($1_depends),\
|
|
$(shell [ -r $(build)/$($d_dir)/.build ] || echo $d)))
|
|
|
|
# Use the module's configure variable to build itself
|
|
# this has to wait for the dependencies to be built since
|
|
# cross compilers and libraries might be messed up
|
|
$(dir $($1_config_file_path)).configured: \
|
|
$(build)/$($1_base_dir)/.canary \
|
|
$(foreach d,$($1_config_wait),$(build)/$($d_dir)/.build) \
|
|
$($1_config_file_path) \
|
|
modules/$1
|
|
@echo "$(DATE) CONFIG $1"
|
|
@( \
|
|
cd "$(build)/$($1_dir)" ; \
|
|
echo "$($1_configure)"; \
|
|
$($1_configure) \
|
|
) \
|
|
< /dev/null \
|
|
2>&1 \
|
|
| tee "$(log_dir)/$1.configure.log" \
|
|
$(VERBOSE_REDIRECT)
|
|
@touch "$$@"
|
|
|
|
# Short hand for our module build target
|
|
$1: \
|
|
$(build)/$($1_dir)/.build \
|
|
$(call outputs,$1) \
|
|
|
|
# Target for all of the outputs, which depend on their dependent modules
|
|
# being built, as well as this module being configured
|
|
$(call outputs,$1): $(build)/$($1_dir)/.build
|
|
|
|
# If any of the outputs are missing, we should force a rebuild
|
|
# of the entire module
|
|
$(eval $1.force = $(shell \
|
|
stat $(call outputs,$1) >/dev/null 2>/dev/null || echo FORCE \
|
|
))
|
|
|
|
$(build)/$($1_dir)/.build: $($1.force) \
|
|
$(foreach d,$($1_depends),$(build)/$($d_dir)/.build) \
|
|
$(dir $($1_config_file_path)).configured \
|
|
|
|
@echo "$(DATE) MAKE $1"
|
|
+@( \
|
|
echo "$(MAKE) \
|
|
-C \"$(build)/$($1_dir)\" \
|
|
$($1_target)" ; \
|
|
$(MAKE) \
|
|
-C "$(build)/$($1_dir)" \
|
|
$($1_target) \
|
|
) \
|
|
< /dev/null \
|
|
2>&1 \
|
|
| tee "$(log_dir)/$1.log" \
|
|
$(VERBOSE_REDIRECT) \
|
|
|| ( \
|
|
echo "tail $(log_dir)/$1.log"; \
|
|
echo "-----"; \
|
|
tail -20 "$(log_dir)/$1.log"; \
|
|
exit 1; \
|
|
)
|
|
$(call do,DONE,$1,\
|
|
touch $(build)/$($1_dir)/.build \
|
|
)
|
|
|
|
|
|
|
|
$1.clean:
|
|
-$(RM) "$(build)/$($1_dir)/.configured"
|
|
-$(MAKE) -C "$(build)/$($1_dir)" clean
|
|
|
|
endef
|
|
|
|
$(call map, define_module, $(modules-y))
|
|
|
|
# hack to force musl-cross to be built before musl
|
|
#$(build)/$(musl_dir)/.configured: $(build)/$(musl-cross_dir)/../../crossgcc/x86_64-linux-musl/bin/x86_64-musl-linux-gcc
|
|
|
|
#
|
|
# Install a file into the initrd, if it changed from
|
|
# the destination file.
|
|
#
|
|
define install =
|
|
@-mkdir -p "$(dir $2)"
|
|
$(call do,INSTALL,$2,cp -a "$1" "$2")
|
|
endef
|
|
|
|
#
|
|
# Files that should be copied into the initrd
|
|
# THis should probably be done in a more scalable manner
|
|
#
|
|
define initrd_bin_add =
|
|
$(initrd_bin_dir)/$(notdir $1): $1
|
|
$(call do,INSTALL-BIN,$$(<:$(pwd)/%=%),cp -a "$$<" "$$@")
|
|
@$(CROSS)strip --preserve-dates "$$@" 2>&-; true
|
|
initrd_bins += $(initrd_bin_dir)/$(notdir $1)
|
|
endef
|
|
|
|
|
|
define initrd_lib_add =
|
|
$(initrd_lib_dir)/$(notdir $1): $1
|
|
$(call do,INSTALL-LIB,$(1:$(pwd)/%=%),\
|
|
$(CROSS)strip --preserve-dates -o "$$@" "$$<")
|
|
initrd_libs += $(initrd_lib_dir)/$(notdir $1)
|
|
endef
|
|
|
|
# Only some modules have binaries that we install
|
|
# Shouldn't this be specified in the module file?
|
|
#bin_modules-$(CONFIG_MUSL) += musl-cross
|
|
bin_modules-$(CONFIG_KEXEC) += kexec
|
|
bin_modules-$(CONFIG_TPMTOTP) += tpmtotp
|
|
bin_modules-$(CONFIG_PCIUTILS) += pciutils
|
|
bin_modules-$(CONFIG_FLASHROM) += flashrom
|
|
bin_modules-$(CONFIG_CRYPTSETUP) += cryptsetup
|
|
bin_modules-$(CONFIG_CRYPTSETUP2) += cryptsetup2
|
|
bin_modules-$(CONFIG_GPG) += gpg
|
|
bin_modules-$(CONFIG_GPG2) += gpg2
|
|
bin_modules-$(CONFIG_PINENTRY) += pinentry
|
|
bin_modules-$(CONFIG_LVM2) += lvm2
|
|
bin_modules-$(CONFIG_DROPBEAR) += dropbear
|
|
bin_modules-$(CONFIG_FLASHTOOLS) += flashtools
|
|
bin_modules-$(CONFIG_NEWT) += newt
|
|
bin_modules-$(CONFIG_CAIRO) += cairo
|
|
bin_modules-$(CONFIG_FBWHIPTAIL) += fbwhiptail
|
|
bin_modules-$(CONFIG_HOTPKEY) += hotp-verification
|
|
bin_modules-$(CONFIG_MSRTOOLS) += msrtools
|
|
bin_modules-$(CONFIG_NKSTORECLI) += nkstorecli
|
|
|
|
$(foreach m, $(bin_modules-y), \
|
|
$(call map,initrd_bin_add,$(call bins,$m)) \
|
|
)
|
|
|
|
# Install the libraries for every module that we have built
|
|
$(foreach m, $(modules-y), \
|
|
$(call map,initrd_lib_add,$(call libs,$m)) \
|
|
)
|
|
|
|
#
|
|
# hack to build cbmem from coreboot
|
|
# this must be built *AFTER* musl, but since coreboot depends on other things
|
|
# that depend on musl it should be ok.
|
|
#
|
|
COREBOOT_UTIL_DIR=$(build)/$(coreboot_base_dir)/util
|
|
ifeq ($(CONFIG_COREBOOT),y)
|
|
$(eval $(call initrd_bin_add,$(COREBOOT_UTIL_DIR)/cbmem/cbmem))
|
|
#$(eval $(call initrd_bin_add,$(COREBOOT_UTIL_DIR)/superiotool/superiotool))
|
|
#$(eval $(call initrd_bin_add,$(COREBOOT_UTIL_DIR)/inteltool/inteltool))
|
|
endif
|
|
|
|
$(COREBOOT_UTIL_DIR)/cbmem/cbmem \
|
|
$(COREBOOT_UTIL_DIR)/superiotool/superiotool \
|
|
$(COREBOOT_UTIL_DIR)/inteltool/inteltool \
|
|
: $(build)/$(coreboot_base_dir)/.canary musl-cross
|
|
+$(call do,MAKE,$(notdir $@),\
|
|
$(MAKE) -C "$(dir $@)" $(CROSS_TOOLS) \
|
|
)
|
|
|
|
# superio depends on zlib and pciutils
|
|
$(COREBOOT_UTIL_DIR)/superiotool/superiotool: \
|
|
$(build)/$(zlib_dir)/.build \
|
|
$(build)/$(pciutils_dir)/.build \
|
|
|
|
#
|
|
# initrd image creation
|
|
#
|
|
# The initrd is constructed from various bits and pieces
|
|
# The cpio-clean program is used ensure that the files
|
|
# always have the same timestamp and appear in the same order.
|
|
#
|
|
# The blobs/dev.cpio is also included in the Linux kernel
|
|
# and has a reproducible version of /dev/console.
|
|
#
|
|
# The xz parameters are copied from the Linux kernel build scripts.
|
|
# Without them the kernel will not decompress the initrd.
|
|
#
|
|
# The padding is to ensure that if anyone wants to cat another
|
|
# file onto the initrd then the kernel will be able to find it.
|
|
#
|
|
|
|
initrd-y += $(pwd)/blobs/dev.cpio
|
|
initrd-y += $(build)/$(initrd_dir)/modules.cpio
|
|
initrd-y += $(build)/$(initrd_dir)/tools.cpio
|
|
initrd-$(CONFIG_HEADS) += $(build)/$(initrd_dir)/heads.cpio
|
|
|
|
#$(build)/$(initrd_dir)/.build: $(build)/$(initrd_dir)/initrd.cpio.xz
|
|
|
|
$(build)/$(initrd_dir)/initrd.cpio.xz: $(initrd-y)
|
|
$(call do,CPIO-XZ ,$@,\
|
|
$(pwd)/bin/cpio-clean \
|
|
$^ \
|
|
| xz \
|
|
--check=crc32 \
|
|
--lzma2=dict=1MiB \
|
|
-9 \
|
|
| dd bs=512 conv=sync status=none > "$@.tmp" \
|
|
)
|
|
@if ! cmp --quiet "$@.tmp" "$@" ; then \
|
|
mv "$@.tmp" "$@" ; \
|
|
else \
|
|
echo "$(DATE) UNCHANGED $(@:$(pwd)/%=%)" ; \
|
|
rm "$@.tmp" ; \
|
|
fi
|
|
@sha256sum "$(@:$(pwd)/%=%)" | tee -a "$(HASHES)"
|
|
|
|
#
|
|
# At the moment PowerPC can only load initrd bundled with the kernel.
|
|
#
|
|
bundle-$(CONFIG_LINUX_BUNDLED) += $(build)/$(BOARD)/$(LINUX_IMAGE_FILE).bundled
|
|
all: $(bundle-y)
|
|
|
|
#
|
|
# The heads.cpio is built from the initrd directory in the
|
|
# Heads tree.
|
|
#
|
|
$(build)/$(initrd_dir)/heads.cpio: FORCE
|
|
$(call do-cpio,$@,$(pwd)/initrd)
|
|
|
|
|
|
#
|
|
# The tools initrd is made from all of the things that we've
|
|
# created during the submodule build.
|
|
#
|
|
$(build)/$(initrd_dir)/tools.cpio: \
|
|
$(initrd_bins) \
|
|
$(initrd_libs) \
|
|
$(initrd_tmp_dir)/etc/config \
|
|
|
|
$(call do-cpio,$@,$(initrd_tmp_dir))
|
|
@$(RM) -rf "$(initrd_tmp_dir)"
|
|
|
|
$(initrd_tmp_dir)/etc/config: FORCE
|
|
@mkdir -p $(dir $@)
|
|
$(call do,INSTALL,$(CONFIG), \
|
|
export \
|
|
| grep ' CONFIG_' \
|
|
| sed -e 's/^declare -x /export /' \
|
|
-e 's/\\\"//g' \
|
|
> $@ \
|
|
)
|
|
$(call do,HASH,$(GIT_HASH) $(GIT_STATUS) $(BOARD), \
|
|
echo export GIT_HASH=\'$(GIT_HASH)\' \
|
|
>> $@ ; \
|
|
echo export GIT_STATUS=$(GIT_STATUS) \
|
|
>> $@ ; \
|
|
echo export CONFIG_BOARD=$(BOARD) \
|
|
>> $@ ; \
|
|
)
|
|
|
|
# Ensure that the initrd depends on all of the modules that produce
|
|
# binaries for it
|
|
$(build)/$(initrd_dir)/tools.cpio: $(foreach d,$(bin_modules-y),$(build)/$($d_dir)/.build)
|
|
|
|
|
|
# List of all modules, excluding the slow to-build modules
|
|
modules-slow := musl musl-cross kernel_headers
|
|
module_dirs := $(foreach m,$(filter-out $(modules-slow),$(modules-y)),$($m_dir))
|
|
|
|
echo_modules:
|
|
echo $(module_dirs)
|
|
|
|
modules.clean:
|
|
for dir in $(module_dirs) \
|
|
; do \
|
|
$(MAKE) -C "build/$$dir" clean ; \
|
|
rm "build/$$dir/.configured" ; \
|
|
done
|
|
|
|
real.clean:
|
|
for dir in \
|
|
$(module_dirs) \
|
|
$(kernel_headers) \
|
|
; do \
|
|
if [ ! -z "$$dir" ]; then \
|
|
rm -rf "build/$$dir"; \
|
|
fi; \
|
|
done
|
|
cd install && rm -rf -- *
|