Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support building across architectures #5

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 64 additions & 11 deletions Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ MAKEFLAGS += --warn-undefined-variables
ifndef PLATFORM
$(error Please define PLATFORM)
endif
ifndef ARCH
$(error Please define ARCH)
rminnich marked this conversation as resolved.
Show resolved Hide resolved
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
Expand All @@ -25,6 +31,7 @@ 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.
Expand All @@ -39,7 +46,7 @@ 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.config
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))
Expand All @@ -65,7 +72,7 @@ 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.amd64.cpio
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)
Expand All @@ -74,7 +81,7 @@ 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)/arch/x86/boot/bzImage
KERNEL_OUT_DEFAULT := $(KERNEL_BUILD_DIR)/$(LINUX_IMAGE_RELATIVE_PATH)
ifndef KERNEL_OUT
KERNEL_OUT := $(KERNEL_OUT_DEFAULT)
endif
Expand All @@ -89,11 +96,45 @@ 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 ?= \
Expand All @@ -116,9 +157,11 @@ 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
Expand Down Expand Up @@ -166,8 +209,8 @@ $(COREBOOT_TOOLCHAIN_OUT)/bin/iasl: $(COREBOOT_DEPS_FLAG) $(COREBOOT_PATCH_FLAG)
tar xf $(COREBOOT_TOOLCHAIN_CACHE) -C $(dir $(COREBOOT_TOOLCHAIN_OUT)); \
touch $@; \
else \
COREBOOT_BUILD_DIR=$(COREBOOT_BUILD_DIR) CPUS=$(NPROC) MAKE=$(MAKE) TOOLS_DIR=$(TOOLS_DIR) \
$(TOOLS_DIR)/build_toolchain.sh; \
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.
Expand Down Expand Up @@ -201,19 +244,28 @@ wipe-coreboot:
# 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_OUT): $(INITRAMFS_IN) $(KERNEL_CONFIG_OUT) $(KERNEL_PATCH_FLAG) kernel_toolchain
else
$(KERNEL_OUT): $(KERNEL_CONFIG_OUT) $(KERNEL_PATCH_FLAG)
$(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
MAKEFLAGS= $(MAKE) -C $(KERNEL_BUILD_DIR) -j$(NPROC) KCFLAGS=-pipe
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"
Expand All @@ -223,7 +275,7 @@ endif
$(KERNEL_CONFIG_OUT): $(KERNEL_CONFIG) $(KERNEL_DEPS_FLAG)
cp $(KERNEL_CONFIG) $@
sed -i "s|CONFIG_INITRAMFS_SOURCE=.*|CONFIG_INITRAMFS_SOURCE=\"$(INITRAMFS_IN)\"|" $@
MAKEFLAGS= $(MAKE) -C $(KERNEL_BUILD_DIR) olddefconfig
ARCH=$(LINUX_ARCH) MAKEFLAGS= $(MAKE) -C $(KERNEL_BUILD_DIR) olddefconfig

$(KERNEL_PATCH_FLAG): $(realpath $(wildcard $(PATCHES_DIR)/kernel-*))
$(call patch,$(KERNEL_BUILD_DIR),$^)
Expand All @@ -246,10 +298,11 @@ initramfs: $(INITRAMFS_OUT)
# Initramfs build target.
$(INITRAMFS_OUT): $(INITRAMFS_DEPS_FLAG) $(INITRAMFS_PATCH_FLAG)
GO111MODULE=off \
GOROOT=$(INITRAMFS_BUILD_DIR)/go \
GOARCH=$(GOARCH) \
GOROOT=$(INITRAMFS_BUILD_GOROOT) \
GOCACHE=$(INITRAMFS_BUILD_DIR)/go/.cache \
GOPATH=$(INITRAMFS_BUILD_DIR)/gopath:$(UROOT_ADDITIONAL_GOPATH) \
$(INITRAMFS_BUILD_DIR)/go/bin/go run github.com/u-root/u-root \
$(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) \
Expand Down
73 changes: 59 additions & 14 deletions examples/qemu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,40 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

PLATFORM := qemu-x86_64
ARCH ?= $(shell uname -m)
ifneq ($(ARCH), $(shell uname -m))
CROSS_COMPILING := 1
else
CROSS_COMPILING := 0
endif

ifeq ($(ARCH), aarch64)
COREBOOT_TOOLCHAIN_ARCH := aarch64
LINUX_ARCH := arm64
LINUX_GCC_TUPLE := $(ARCH)-linux-
LINUX_IMAGE_RELATIVE_PATH := arch/arm64/boot/Image.gz
GOARCH := arm64
PLATFORM := qemu-$(ARCH)
QEMU_SYSTEM := qemu-system-$(ARCH)
endif
ifeq ($(ARCH), ppc64le)
COREBOOT_TOOLCHAIN_ARCH=$(ARCH)
GOARCH := $(ARCH)
LINUX_ARCH := powerpc
LINUX_IMAGE_RELATIVE_PATH := arch/powerpc/boot/zImage
LINUX_GCC_TUPLE := powerpc64-linux-gnu-
PLATFORM := qemu-$(ARCH)
QEMU_SYSTEM := qemu-system-$(ARCH)
endif
ifeq ($(ARCH), x86_64)
COREBOOT_TOOLCHAIN_ARCH := i386
LINUX_ARCH := $(ARCH)
LINUX_GCC_TUPLE := $(ARCH)-linux-
LINUX_IMAGE_RELATIVE_PATH := arch/x86/boot/bzImage
GOARCH := amd64
PLATFORM := qemu-amd64
QEMU_SYSTEM := qemu-system-$(ARCH)
endif

OSF_BUILDER_DIR := ../..

Expand All @@ -13,18 +46,30 @@ CONFIGS_DIR := ./configs
PATCHES_DIR := ./patches

include $(OSF_BUILDER_DIR)/Makefile.inc
OUT ?= build/$(PLATFORM)/osf-$(PLATFORM).rom

# RNG to avoid DHCP lockups when waiting for entropy
# redirect all the output to the console
QEMU_COMMON_OPTS := -bios $(OUT) $(QEMU_KVM_OPTS) \
-m 1024 \
-object rng-random,filename=/dev/urandom,id=rng0 \
-nographic

run:
sudo qemu-system-x86_64 \
`# the machine type specified in the coreboot mainboard configuration` \
-M q35 \
`# use KVM to avail of hardware virtualization extensions` \
-enable-kvm \
`# the coreboot ROM to run as system firmware` \
-bios $(OUT) \
`# the amount of RAM in MB` \
-m 1024 \
`# RNG to avoid DHCP lockups when waiting for entropy` \
-object rng-random,filename=/dev/urandom,id=rng0 \
`# redirect all the output to the console` \
-nographic
ifeq ($(ARCH), aarch64)
$(QEMU_SYSTEM) $(QEMU_COMMON_OPTS) \
-M virt,secure=on,virtualization=on \
-cpu cortex-a53
endif
ifeq ($(ARCH), ppc64le)
$(QEMU_SYSTEM) $(QEMU_COMMON_OPTS) \
-M powernv,hb-mode=on \
-cpu power9 \
-drive file=build/coreboot.rom,if=mtd \
-serial stdio \
-display none
endif
ifeq ($(ARCH), x86_64)
$(QEMU_SYSTEM) $(QEMU_COMMON_OPTS) \
-M q35
endif
80 changes: 80 additions & 0 deletions examples/qemu/configs/config-qemu-aarch64.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{
"initramfs": {
"untar": [
{
"label": "go",
"url": "https://golang.org/dl/go1.17.2.linux-arm64.tar.gz",
"hash": "sha256:a5a43c9cdabdb9f371d56951b14290eba8ce2f9b0db48fb5fc657943984fd4fc"
}
],
"goget": [
{
"label": "uroot",
"pkg": "https://github.com/u-root/u-root",
"branch": "master",
"hash": "ba3c4503673291183f54568dc0c0d0d7411302cd"
}
]
},
"kernel": {
"untar": [
{
"label": "kernel",
"url": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/snapshot/linux-5.14.14.tar.gz",
"hash": "sha256:7649f5496c34eae104fc391988d5dc4993082cf6195984303433bafa358fd7da",
"subdir": "linux-5.14.0"
}
]
},
"coreboot": {
"git": [
{
"label": "coreboot",
"url": "https://review.coreboot.org/coreboot",
"branch": "master",
"hash": "37a977dde945de15464925d4501d4b85e01c3a16"
},
{
"label": "vboot",
"url": "https://review.coreboot.org/vboot",
"dest": "3rdparty/vboot",
"branch": "master",
"hash": "48195e5878006ac2cf74cb7f02953ab06c68202d"
}
],
"files": {
"label": "crossgcc_tarballs",
"dest": "util/crossgcc/tarballs",
"filelist": [
{
"url": "https://ftpmirror.gnu.org/gmp/gmp-6.2.1.tar.xz",
"hash": "sha256:fd4829912cddd12f84181c3451cc752be224643e87fac497b69edddadc49b4f2"
},
{
"url": "https://ftpmirror.gnu.org/mpfr/mpfr-4.1.0.tar.xz",
"hash": "sha256:0c98a3f1732ff6ca4ea690552079da9c597872d30e96ec28414ee23c95558a7f"
},
{
"url": "https://ftpmirror.gnu.org/mpc/mpc-1.2.1.tar.gz",
"hash": "sha256:17503d2c395dfcf106b622dc142683c1199431d095367c6aacba6eec30340459"
},
{
"url": "https://ftpmirror.gnu.org/binutils/binutils-2.37.tar.xz",
"hash": "sha256:820d9724f020a3e69cb337893a0b63c2db161dadcb0e06fc11dc29eb1e84a32c"
},
{
"url": "https://ftpmirror.gnu.org/gcc/gcc-11.2.0/gcc-11.2.0.tar.xz",
"hash": "sha256:d08edc536b54c372a1010ff6619dd274c0f1603aa49212ba20f7aa2cda36fa8b"
},
{
"url": "https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2",
"hash": "sha256:3c4b8339e5ab54b1bcb2316101f8985a5da50a3f9e504d43fa6f35668bee2fd0"
},
{
"url": "https://acpica.org/sites/acpica/files/acpica-unix2-20210331.tar.gz",
"hash": "sha256:3dab326c262d4f3eaf380bbbbd7aa8c2eb5f2697f7821659222cf898d8be28c1"
}
]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,47 +32,47 @@
"label": "coreboot",
"url": "https://review.coreboot.org/coreboot",
"branch": "master",
"hash": "7014f8258e6e015fe91d6928266d10ec536e9001"
"hash": "cc66b56c80862a59117a4582abc8d59f092ac59c"
},
{
"label": "vboot",
"url": "https://review.coreboot.org/vboot",
"dest": "3rdparty/vboot",
"dest": "3rdparty/vboot",
"branch": "master",
"hash": "48195e5878006ac2cf74cb7f02953ab06c68202d"
"hash": "13f601fbd4c1b128f333391e4552082594f0ff25"
}
],
"files": {
"label": "crossgcc_tarballs",
"dest": "util/crossgcc/tarballs",
"filelist": [
{
"url": "https://ftpmirror.gnu.org/gmp/gmp-6.2.0.tar.xz",
"hash": "sha256:258e6cd51b3fbdfc185c716d55f82c08aff57df0c6fbd143cf6ed561267a1526"
"url": "https://ftpmirror.gnu.org/gmp/gmp-6.2.1.tar.xz",
"hash": "sha256:fd4829912cddd12f84181c3451cc752be224643e87fac497b69edddadc49b4f2"
},
{
"url": "https://ftpmirror.gnu.org/mpfr/mpfr-4.1.0.tar.xz",
"hash": "sha256:0c98a3f1732ff6ca4ea690552079da9c597872d30e96ec28414ee23c95558a7f"
},
{
"url": "https://ftpmirror.gnu.org/mpc/mpc-1.2.0.tar.gz",
"hash": "sha256:e90f2d99553a9c19911abdb4305bf8217106a957e3994436428572c8dfe8fda6"
"url": "https://ftpmirror.gnu.org/mpc/mpc-1.2.1.tar.gz",
"hash": "sha256:17503d2c395dfcf106b622dc142683c1199431d095367c6aacba6eec30340459"
},
{
"url": "https://ftpmirror.gnu.org/binutils/binutils-2.35.1.tar.xz",
"hash": "sha256:3ced91db9bf01182b7e420eab68039f2083aed0a214c0424e257eae3ddee8607"
"url": "https://ftpmirror.gnu.org/binutils/binutils-2.37.tar.xz",
"hash": "sha256:820d9724f020a3e69cb337893a0b63c2db161dadcb0e06fc11dc29eb1e84a32c"
},
{
"url": "https://ftpmirror.gnu.org/gcc/gcc-8.3.0/gcc-8.3.0.tar.xz",
"hash": "sha256:64baadfe6cc0f4947a84cb12d7f0dfaf45bb58b7e92461639596c21e02d97d2c"
"url": "https://ftpmirror.gnu.org/gcc/gcc-11.2.0/gcc-11.2.0.tar.xz",
"hash": "sha256:d08edc536b54c372a1010ff6619dd274c0f1603aa49212ba20f7aa2cda36fa8b"
},
{
"url": "https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2",
"hash": "sha256:3c4b8339e5ab54b1bcb2316101f8985a5da50a3f9e504d43fa6f35668bee2fd0"
},
{
"url": "https://acpica.org/sites/acpica/files/acpica-unix2-20200925.tar.gz",
"hash": "sha256:5cb40ff01aaf27caf639e9928bab02706c3d7bff649f16e32d48bee99208c6a2"
"url": "https://acpica.org/sites/acpica/files/acpica-unix2-20210331.tar.gz",
"hash": "sha256:3dab326c262d4f3eaf380bbbbd7aa8c2eb5f2697f7821659222cf898d8be28c1"
}
]
}
Expand Down
Loading