-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathMakefile.inc
More file actions
371 lines (316 loc) · 14.3 KB
/
Makefile.inc
File metadata and controls
371 lines (316 loc) · 14.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# vim: syntax=make
#
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
# This file should be paramterized and included by platform Makefile.
# See `examples/qemu/Makefile` for one.
MAKEFLAGS += --warn-undefined-variables
.PHONY: always-build build clean clean-coreboot clean-initramfs clean-kernel coreboot-toolchain initramfs kernel wipe wipe-initramfs wipe-coreboot wipe-kernel
.DEFAULT_GOAL: build
.SUFFIXES:
ifndef PLATFORM
$(error Please define PLATFORM)
endif
ifndef ARCH
$(error Please define ARCH)
endif
ifndef LINUX_IMAGE_RELATIVE_PATH
$(error Please define LINUX_IMAGE_RELATIVE_PATH)
endif
ifndef OSF_BUILDER_DIR
$(error Please define OSF_BUILDER_DIR)
endif
ifndef CONFIGS_DIR
$(error Please define CONFIGS_DIR)
endif
ifndef PATCHES_DIR
$(error Please define PATCHES_DIR)
endif
# If defined, specifies URL overrides to be applied when fetching deps.
URL_OVERRIDES ?=
# Version of the firmware being built.
VERSION ?= 0.0.0
HASH_MODE ?= strict
BUILD_DIR ?= $(realpath $(CURDIR))/build
PLATFORM_BUILD_DIR ?= $(BUILD_DIR)/$(PLATFORM)
ROM_OUT ?= $(PLATFORM_BUILD_DIR)/osf-$(PLATFORM).rom
# Absolutize CONFIGS_DIR
CONFIGS_DIR := $(realpath $(CONFIGS_DIR))
CONFIG ?= $(CONFIGS_DIR)/config-$(PLATFORM).json
KERNEL_CONFIG ?= $(CONFIGS_DIR)/kernel-$(LINUX_ARCH).config
COREBOOT_CONFIG ?= $(CONFIGS_DIR)/coreboot.config-$(PLATFORM)
TOOLS_DIR := $(realpath $(OSF_BUILDER_DIR)/tools)
URL_OVERRIDES_ABS = $(realpath $(URL_OVERRIDES))
# We build initramfs every time to pick up possible changes.
# If you are not actively working on u-root, feel free to set this to 0.
ALWAYS_BUILD_INITRAMFS ?= 1
# Same for the kernel and coreboot.
ALWAYS_BUILD_KERNEL ?= 1
ALWAYS_BUILD_COREBOOT ?= 1
_WIPE_CONFIRMED ?= 0
ALL_CONFIGS := $(wildcard $(CONFIGS_DIR)/*.json)
DEFAULT_GETDEPS_TOOL ?= $(PLATFORM_BUILD_DIR)/getdeps
GETDEPS_TOOL ?= $(DEFAULT_GETDEPS_TOOL)
VPD_TOOL ?= $(TOOLS_DIR)/vpd
FLASHROM_TOOL ?= $(TOOLS_DIR)/flashrom
CBNT_PROV_TOOL ?= $(TOOLS_DIR)/cbnt-prov
FINAL_CONFIG_OUT := $(PLATFORM_BUILD_DIR)/final_config.json
NPROC ?= $(shell nproc --all --ignore=1)
INITRAMFS_BUILD_DIR := $(PLATFORM_BUILD_DIR)/initramfs
INITRAMFS_DEPS_FLAG := $(PLATFORM_BUILD_DIR)/.initramfs-deps
INITRAMFS_PATCH_FLAG := $(PLATFORM_BUILD_DIR)/.initramfs-patch
ifndef INITRAMFS_OUT
INITRAMFS_OUT := $(INITRAMFS_BUILD_DIR)/initramfs_linuxboot.$(GOARCH).cpio
endif
# By default, build initramfs but a prebuilt one can be provided via INITRAMFS_IN.
INITRAMFS_IN ?= $(INITRAMFS_OUT)
KERNEL_BUILD_DIR := $(PLATFORM_BUILD_DIR)/kernel
KERNEL_CONFIG_OUT := $(KERNEL_BUILD_DIR)/.config
KERNEL_DEPS_FLAG := $(PLATFORM_BUILD_DIR)/.kernel-deps
KERNEL_PATCH_FLAG := $(PLATFORM_BUILD_DIR)/.kernel-patch
KERNEL_OUT_DEFAULT := $(KERNEL_BUILD_DIR)/$(LINUX_IMAGE_RELATIVE_PATH)
ifndef KERNEL_OUT
KERNEL_OUT := $(KERNEL_OUT_DEFAULT)
endif
# Prebuilt kernel can be provided via KERNEL_IN.
KERNEL_IN ?= $(KERNEL_OUT)
COREBOOT_BUILD_DIR := $(PLATFORM_BUILD_DIR)/coreboot
COREBOOT_CONFIG_OUT := $(COREBOOT_BUILD_DIR)/.config
COREBOOT_TOOLCHAIN_OUT := $(COREBOOT_BUILD_DIR)/util/crossgcc/xgcc
COREBOOT_OUT := $(COREBOOT_BUILD_DIR)/build/coreboot.rom
COREBOOT_DEPS_FLAG := $(PLATFORM_BUILD_DIR)/.coreboot-deps
COREBOOT_PATCH_FLAG := $(PLATFORM_BUILD_DIR)/.coreboot-patch
COREBOOT_TOOLCHAIN_FLAG := $(PLATFORM_BUILD_DIR)/.coreboot-toolchain
COREBOOT_TOOLCHAIN_CACHE_ENABLE ?= 1
COREBOOT_VPD_SUPPORT ?= 1
# coreboot Intel blobs
ifdef COREBOOT_BLOBS_DIR
COREBOOT_BLOBS_DIR := $(realpath $(COREBOOT_BLOBS_DIR))
endif
# FIXME: Go needs to be run on the host architecture (GOARCH is used for cross-
# compiling Go programs). However, the target platform's config will likely want
# to use a Go tarball for that target architecture. For now, override this with
# whatever the host has installed. THIS IS A GROSS HACK.
#
# We might change the json schema to specify only Go version, but not point at
# a particular tarball (which includes architecture in the name). This would
# also require changing the download verification scheme to something like GPG
# signature instead of sha255sum, since the hash will obviously be different
# among tarballs for different architectures.
#
# FIXME #2: It's not clear if we want to always use the coreboot toolchain when
# cross compiling Linux. It's certainly an easy approach, though.
#
# FIXME #3: Some distros add the version number of the tool as a suffix, for
# example "x86_64-linux-gnu-gcc-10".
ifeq ($(CROSS_COMPILING), 1)
INITRAMFS_BUILD_GOROOT ?= /usr/local/go
ifeq ($(shell which $(LINUX_GCC_TUPLE)gcc),)
BUILD_LINUX_WITH_COREBOOT_TOOLCHAIN = 1
CROSS_COMPILE ?= $(COREBOOT_BUILD_DIR)/util/crossgcc/xgcc/bin/$(LINUX_GCC_TUPLE)
else
BUILD_LINUX_WITH_COREBOOT_TOOLCHAIN = 0
CROSS_COMPILE ?= $(LINUX_GCC_TUPLE)
endif
else
CROSS_COMPILE =
# FIXME: Also need to fix behavior when we're not cross-compilng, but system's
# go version doesn't match the version we're using to build the initramfs...
#INITRAMFS_BUILD_GOROOT ?= $(INITRAMFS_BUILD_DIR)/go
INITRAMFS_BUILD_GOROOT ?= /usr/local/go
endif
UROOT_BOOT_CMDS := fbnetboot localboot systemboot
UROOT_EXP_CMDS := cbmem dmidecode modprobe ipmidump
UROOT_BASE_CMDS ?= \
core \
$(addprefix github.com/u-root/u-root/cmds/boot/, $(UROOT_BOOT_CMDS)) \
$(addprefix github.com/u-root/u-root/cmds/exp/, $(UROOT_EXP_CMDS)) \
UROOT_ADDITIONAL_CMDS ?=
UROOT_ADDITIONAL_GOPATH ?=
BASE_FILES ?= $(FLASHROM_TOOL):bin/flashrom $(VPD_TOOL):bin/vpd
UROOT_ADDITIONAL_FILES ?=
UINIT_CMD ?= systemboot
# Shorthand for building the firmware.
build: $(ROM_OUT)
# Main output product - firmware with VPD variables.
$(ROM_OUT): $(COREBOOT_OUT)
ifeq "$(COREBOOT_VPD_SUPPORT)" "1"
$(VPD_TOOL) -f "$<" -O -i RO_VPD -s internal_versions="`cat $(FINAL_CONFIG_OUT)`"
[ -z "$(VERSION)" ] || $(VPD_TOOL) -f "$<" -i RO_VPD -s firmware_version=$(VERSION)
$(VPD_TOOL) -f "$<" -O -i RW_VPD || true # Format RW_VPD region, if present.
endif
cp "$<" "$@"
@echo '***' >&2
@echo '*** Build done, $@' >&2
@echo '***' >&2
# ========================
# === coreboot section ===
# ========================
# coreboot build - produces a firmware image, depends on payload (kernel + initramfs), config and toolchain.
$(COREBOOT_OUT): $(KERNEL_IN) $(COREBOOT_CONFIG_OUT) $(COREBOOT_PATCH_FLAG) $(COREBOOT_TOOLCHAIN_FLAG)
@# Parallel builds are not always reliable, hence -j1.
UPDATED_SUBMODULES=1 MAKEFLAGS= $(MAKE) -C $(COREBOOT_BUILD_DIR) -j1
ifeq "$(ALWAYS_BUILD_COREBOOT)" "1"
$(COREBOOT_OUT): always-build
endif
# Applies coreboot patches for this platform, if any.
$(COREBOOT_PATCH_FLAG): $(realpath $(wildcard $(PATCHES_DIR)/coreboot-$(PLATFORM)-*))
$(call patch,$(COREBOOT_BUILD_DIR),$^)
touch $@
# Toolchain version identifier - same as in coreboot/util/crossgcc/buildgcc.
# Produces something like "2021-04-06_7014f825", uniquely identifes the toolchain and is used to cache it.
CROSSGCC_VERSION = $(shell git -C $(COREBOOT_BUILD_DIR)/util/crossgcc log -n 1 --pretty=%cd --date=short .)_$(shell git -C $(COREBOOT_BUILD_DIR)/util/crossgcc log -n 1 --pretty=%h .)
COREBOOT_TOOLCHAIN_CACHE = $(BUILD_DIR)/coreboot-toolchain-$(CROSSGCC_VERSION).tar
# Flag signaling that coreboot toolchain build is done.
# Depends on IASL binary which is built last during the toolchain build, meaning it's complete (in case build was interrupted).
# Toolchain cache archive is created here, unless already exists.
$(COREBOOT_TOOLCHAIN_FLAG): $(COREBOOT_TOOLCHAIN_OUT)/bin/iasl
ifeq "$(COREBOOT_TOOLCHAIN_CACHE_ENABLE)" "1"
if ! [ -f "$(COREBOOT_TOOLCHAIN_CACHE)" ]; then \
tar cf $(COREBOOT_TOOLCHAIN_CACHE).tmp -C $(dir $(COREBOOT_TOOLCHAIN_OUT)) $(notdir $(COREBOOT_TOOLCHAIN_OUT)) && \
mv $(COREBOOT_TOOLCHAIN_CACHE).tmp $(COREBOOT_TOOLCHAIN_CACHE); \
fi
endif
touch $@
# Provides the crossgcc toolchain. Uses cache if enabled and available, otherwise build from sources.
$(COREBOOT_TOOLCHAIN_OUT)/bin/iasl: $(COREBOOT_DEPS_FLAG) $(COREBOOT_PATCH_FLAG)
if [ -f $(COREBOOT_TOOLCHAIN_CACHE) ]; then \
echo Using cached toolchain from $(COREBOOT_TOOLCHAIN_CACHE) >&2; \
tar xf $(COREBOOT_TOOLCHAIN_CACHE) -C $(dir $(COREBOOT_TOOLCHAIN_OUT)); \
touch $@; \
else \
COREBOOT_BUILD_DIR=$(COREBOOT_BUILD_DIR) CPUS=$(NPROC) MAKE=$(MAKE) ARCH=$(COREBOOT_TOOLCHAIN_ARCH) \
TOOLS_DIR=$(TOOLS_DIR) $(TOOLS_DIR)/build_toolchain.sh coreboot; \
fi
# Creates coreboot config file using the user-provided one and feeding it to make olddefconfig.
$(COREBOOT_CONFIG_OUT): $(COREBOOT_CONFIG) $(COREBOOT_DEPS_FLAG) $(COREBOOT_TOOLCHAIN_FLAG)
cp $(COREBOOT_CONFIG) $(COREBOOT_CONFIG_OUT)
if [ -d "$(COREBOOT_BLOBS_DIR)" ]; then \
echo Using provided coreboot Intel blobs FSP, ME and microcode from $(COREBOOT_BLOBS_DIR) >&2; \
sed -i "s|CONFIG_CPU_UCODE_BINARIES=.*|CONFIG_CPU_UCODE_BINARIES=\"$(COREBOOT_BLOBS_DIR)/microcode.mcb\"|" $@; \
sed -i "s|CONFIG_FSP_T_FILE=.*|CONFIG_FSP_T_FILE=\"$(COREBOOT_BLOBS_DIR)/Server_T.fd\"|" $@; \
sed -i "s|CONFIG_FSP_M_FILE=.*|CONFIG_FSP_M_FILE=\"$(COREBOOT_BLOBS_DIR)/Server_M.fd\"|" $@; \
sed -i "s|CONFIG_FSP_S_FILE=.*|CONFIG_FSP_S_FILE=\"$(COREBOOT_BLOBS_DIR)/Server_S.fd\"|" $@; \
sed -i "s|CONFIG_IFD_BIN_PATH=.*|CONFIG_IFD_BIN_PATH=\"$(COREBOOT_BLOBS_DIR)/flashregion_0_flashdescriptor.bin\"|" $@; \
sed -i "s|CONFIG_ME_BIN_PATH=.*|CONFIG_ME_BIN_PATH=\"$(COREBOOT_BLOBS_DIR)/flashregion_2_intel_me.bin\"|" $@; \
fi
sed -i "s|CONFIG_PAYLOAD_FILE=.*|CONFIG_PAYLOAD_FILE=\"$(KERNEL_IN)\"|" $@
! grep -q CONFIG_INTEL_CBNT_PROV_EXTERNAL_BIN=y $@ || \
sed -i "s|CONFIG_INTEL_CBNT_PROV_EXTERNAL_BIN_PATH=.*|CONFIG_INTEL_CBNT_PROV_EXTERNAL_BIN_PATH=\"$(CBNT_PROV_TOOL)\"|" $@
MAKEFLAGS= $(MAKE) -C $(COREBOOT_BUILD_DIR) olddefconfig
clean-coreboot:
rm -f $(COREBOOT_OUT)
[ -d $(COREBOOT_BUILD_DIR) ] && MAKEFLAGS= $(MAKE) -C $(COREBOOT_BUILD_DIR) clean
wipe-coreboot:
rm -rf $(COREBOOT_BUILD_DIR) $(COREBOOT_DEPS_FLAG) $(COREBOOT_PATCH_FLAG) $(COREBOOT_TOOLCHAIN_FLAG)
# ======================
# === Kernel section ===
# ======================
# Top-level initramfs target, for use by humans.
kernel: $(KERNEL_OUT)
kernel_toolchain: $(COREBOOT_DEPS_FLAG) $(COREBOOT_PATCH_FLAG)
ifeq "$(BUILD_LINUX_WITH_COREBOOT_TOOLCHAIN)" "1"
echo 'Building cross toolchain for Linux'
COREBOOT_BUILD_DIR=$(COREBOOT_BUILD_DIR) CPUS=$(NPROC) MAKE=$(MAKE) ARCH=$(LINUX_ARCH) \
TOOLS_DIR=$(TOOLS_DIR) $(TOOLS_DIR)/build_toolchain.sh linux;
else
echo 'Building Linux with toolchain tuple: $(CROSS_COMPILE)'
endif
# Kernel build target. Requires initrmafs image, config and patches.
ifneq "$(INITRAMFS_IN)" ""
$(KERNEL_OUT): $(INITRAMFS_IN) $(KERNEL_CONFIG_OUT) $(KERNEL_PATCH_FLAG) kernel_toolchain
else
$(KERNEL_OUT): $(KERNEL_CONFIG_OUT) $(KERNEL_PATCH_FLAG) $(KERNEL_TOOLCHAIN) $(KERNEL_TOOLCHAIN)
endif
@# If lzma(1) is not available, kernel build will fall back to gzip and we don't want that.
@if ! lzma -h > /dev/null 2>/dev/null; then \
echo ' *** Please install the lzma CLI utility.' >&2; \
echo ' *** In RedHat distros it`s provided by xz-lzma-compat, in Debian/Ubuntu it`s provided by xz-utils.' >&2; \
exit 1; \
fi
ARCH=$(LINUX_ARCH) CROSS_COMPILE=$(CROSS_COMPILE) MAKEFLAGS= $(MAKE) -C $(KERNEL_BUILD_DIR) -j$(NPROC) KCFLAGS=-pipe
[ "$@" = "$(KERNEL_OUT_DEFAULT)" ] || cp -v "$(KERNEL_OUT_DEFAULT)" "$@"
ifeq "$(ALWAYS_BUILD_KERNEL)" "1"
$(KERNEL_OUT): always-build
endif
$(KERNEL_CONFIG_OUT): $(KERNEL_CONFIG) $(KERNEL_DEPS_FLAG)
cp $(KERNEL_CONFIG) $@
sed -i "s|CONFIG_INITRAMFS_SOURCE=.*|CONFIG_INITRAMFS_SOURCE=\"$(INITRAMFS_IN)\"|" $@
ARCH=$(LINUX_ARCH) MAKEFLAGS= $(MAKE) -C $(KERNEL_BUILD_DIR) olddefconfig
$(KERNEL_PATCH_FLAG): $(realpath $(wildcard $(PATCHES_DIR)/kernel-*))
$(call patch,$(KERNEL_BUILD_DIR),$^)
touch $@
clean-kernel:
rm -f $(KERNEL_OUT)
[ -d $(KERNEL_BUILD_DIR) ] && MAKEFLAGS= $(MAKE) -C $(KERNEL_BUILD_DIR) clean
wipe-kernel:
rm -rf $(KERNEL_BUILD_DIR) $(KERNEL_DEPS_FLAG) $(KERNEL_PATCH_FLAG)
# =========================
# === Initramfs section ===
# =========================
# Top-level initramfs target, for use by humans.
initramfs: $(INITRAMFS_OUT)
# Initramfs build target.
$(INITRAMFS_OUT): $(INITRAMFS_DEPS_FLAG) $(INITRAMFS_PATCH_FLAG)
GO111MODULE=off \
GOARCH=$(GOARCH) \
GOROOT=$(INITRAMFS_BUILD_GOROOT) \
GOCACHE=$(INITRAMFS_BUILD_DIR)/go/.cache \
GOPATH=$(INITRAMFS_BUILD_DIR)/gopath:$(UROOT_ADDITIONAL_GOPATH) \
$(GOROOT)/bin/go run github.com/u-root/u-root \
-build=bb -o $@ -uinitcmd=$(UINIT_CMD) \
$(addprefix -files=,$(BASE_FILES) $(UROOT_ADDITIONAL_FILES)) \
$(UROOT_ADDITIONAL_CMDS) \
$(UROOT_BASE_CMDS) \
|| { rm -f $@; exit 1; }
ifeq "$(ALWAYS_BUILD_INITRAMFS)" "1"
$(INITRAMFS_OUT): always-build
endif
$(INITRAMFS_PATCH_FLAG): $(realpath $(wildcard $(PATCHES_DIR)/initramfs-*))
$(call patch,$(INITRAMFS_BUILD_DIR),$^)
touch $@
clean-initramfs:
rm -f $(INITRAMFS_OUT)
wipe-initramfs:
rm -rf $(INITRAMFS_BUILD_DIR) $(INITRAMFS_DEPS_FLAG) $(INITRAMFS_PATCH_FLAG)
# ====================
# === Misc section ===
# ====================
# If any of the configs is not there, give the user a clear message (probably PLATFORM is incorrect).
$(CONFIG) $(COREBOOT_CONFIG) $(KERNEL_CONFIG):
@echo '***' >&2
@echo '*** Missing config - $@' >&2
@echo '***' >&2
@false
# Rebuild the getdeps tool if necessary.
$(DEFAULT_GETDEPS_TOOL): $(wildcard $(OSF_BUILDER_DIR)/getdeps/*.go)
mkdir -p $(PLATFORM_BUILD_DIR)
GO111MODULE=off GOBIN=$(dir $@) go get $(OSF_BUILDER_DIR)/getdeps
# Run the getdeps tool for a component (initramfs, kernel, coreboot) and create a flag file.
# The flag file is used to avoid re-running unless JSON configs have changed.
$(PLATFORM_BUILD_DIR)/.%-deps: $(CONFIG) $(GETDEPS_TOOL) $(ALL_CONFIGS)
@if [ -f "$@" -a $(_WIPE_CONFIRMED) -eq 0 ]; then \
echo "WARNING: A full wipe is being triggered, it will remove build artifacts and git repos under $(PLATFORM_BUILD_DIR), are you sure to continue? (y/n)"; \
read ans; \
if [ "$$ans" = "y" ]; then \
echo continue; \
else \
echo exit 1; exit 1; \
fi \
fi
$(eval _WIPE_CONFIRMED=1)
mkdir -p $(PLATFORM_BUILD_DIR)
cd $(PLATFORM_BUILD_DIR) && $(GETDEPS_TOOL) --components $* -c $(CONFIG) -H $(HASH_MODE) --url-overrides=$(URL_OVERRIDES_ABS) -o $(FINAL_CONFIG_OUT)
touch $@
define patch # dir,patches
[ -z "$2" ] || { cd $1 && for p in $2; do patch -p 1 -N -b --verbose -i $$p; done }
endef
clean: clean-initramfs clean-kernel clean-coreboot
rm -f $(OUT)
wipe:
rm -rf $(PLATFORM_BUILD_DIR)
# Dummy target to depend on when forcing rebuild.
always-build:
@true