1# Copyright 2020 The ChromiumOS Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5# Builds the kernel and rootfs for the guest used in integration testing. 6# 7# The main artifacts are: 8# target/guest_under_test/bzImage 9# target/guest_under_test/rootfs 10 11ARCH ?= $(shell arch) 12ifeq ($(ARCH), x86_64) 13 KERNEL_ARCH=x86 14 KERNEL_BINARY=bzImage 15 DOCKER_ARCH=amd64 16 CROSS_COMPILE= 17 RUSTFLAGS= 18else ifeq ($(ARCH), aarch64) 19 KERNEL_ARCH=arm64 20 KERNEL_BINARY=Image 21 DOCKER_ARCH=arm64v8 22 CROSS_COMPILE=aarch64-linux-gnu- 23 RUSTFLAGS="-Clinker=aarch64-linux-gnu-ld" 24else 25 $(error Only x86_64 or aarch64 are supported) 26endif 27 28# Build against the musl toolchain, which will produce a statically linked, 29# portable binary that we can run on the alpine linux guest without needing 30# libc at runtime 31RUST_TARGET ?= $(ARCH)-unknown-linux-musl 32 33# We are building everything in target/guest_under_test 34CARGO_TARGET ?= $(shell cargo metadata --no-deps --format-version 1 | \ 35 jq -r ".target_directory") 36TARGET ?= $(CARGO_TARGET)/guest_under_test/$(ARCH) 37$(shell mkdir -p $(TARGET)) 38 39# Parameteters for building the kernel locally 40KERNEL_REPO ?= https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git 41KERNEL_BRANCH ?= v6.1.59 42KERNEL_SRC_BASE ?= $(TARGET)/kernel-source-$(KERNEL_BRANCH) 43KERNEL_SRC_PATCHED ?= $(KERNEL_SRC_BASE)-patched 44KERNEL_BUILD ?= $(TARGET)/kernel-build 45KERNEL_PATCHES ?= "`readlink -f ./kernel/patches`" 46 47################################################################################ 48# Main targets 49 50all: $(TARGET)/rootfs $(TARGET)/bzImage 51 52# Clean all local build artifacts, but not downloaded sources. 53clean: 54 rm -rf $(TARGET)/kernel-build $(TARGET)/rootfs-build $(TARGET)/initramfs-build $(TARGET)/rootfs $(TARGET)/bzImage $(TARGET)/initramfs.cpio.gz 55 56clean-all: 57 rm -rf $(TARGET) 58 59x86_64_initramfs: $(TARGET)/initramfs 60 61delegate: $(TARGET)/rootfs-build/delegate 62 63readclock: $(TARGET)/rootfs-build/readclock 64 65################################################################################ 66# Build rootfs 67rootfs : ${TARGET}/rootfs 68 69# Build rootfs from Dockerfile and export into squashfs 70$(TARGET)/rootfs: $(TARGET)/rootfs-build/delegate $(TARGET)/rootfs-build/readclock rootfs/Dockerfile 71 # Build image from Dockerfile 72 DOCKER_BUILDKIT=1 docker build -t crosvm_e2e_test_guest $(TARGET)/rootfs-build \ 73 -f rootfs/Dockerfile --build-arg ARCH=$(DOCKER_ARCH) 74 # Make sure tar2sqfs is available. If not, print a help message. 75 tar2sqfs --help > /dev/null || \ 76 { \ 77 echo 'tar2sqfs is not found. To install, run: `sudo apt install -y squashfs-tools-ng` or something equivalent.' ; \ 78 exit 1 ; \ 79 } 80 # Create container and export into squashfs, and don't forget to clean up 81 # the container afterwards. 82 set -x && \ 83 CONTAINER=$$(docker create crosvm_e2e_test_guest) && \ 84 docker export $$CONTAINER | tar2sqfs -c gzip -f $@ && \ 85 docker rm $$CONTAINER 86 87# Build and copy delegate binary into rootfs build directory 88$(TARGET)/rootfs-build/delegate: rootfs/delegate/Cargo.toml rootfs/delegate/src/main.rs rootfs/delegate/src/wire_format.rs 89 rustup target add $(RUST_TARGET) 90 CARGO_TARGET_DIR=$(TARGET) RUSTFLAGS=$(RUSTFLAGS) cargo build --target $(RUST_TARGET) --release --manifest-path=rootfs/delegate/Cargo.toml 91 mkdir -p $(TARGET)/rootfs-build 92 cp $(TARGET)/$(RUST_TARGET)/release/delegate $(TARGET)/rootfs-build/delegate 93 94# Build and copy readclock binary into rootfs build directory 95$(TARGET)/rootfs-build/readclock: rootfs/readclock/Cargo.toml rootfs/readclock/src/main.rs rootfs/readclock/src/lib.rs 96 rustup target add $(RUST_TARGET) 97 CARGO_TARGET_DIR=$(TARGET) RUSTFLAGS=$(RUSTFLAGS) cargo build --target $(RUST_TARGET) --release --manifest-path=rootfs/readclock/Cargo.toml 98 mkdir -p $(TARGET)/rootfs-build 99 cp $(TARGET)/$(RUST_TARGET)/release/readclock $(TARGET)/rootfs-build/readclock 100 101################################################################################ 102# Build initramfs 103 104# Build initramfs from Containerfile and package as cpio archive 105$(TARGET)/initramfs: $(TARGET)/rootfs-build/delegate initramfs/Containerfile initramfs/init.sh 106 -mkdir -p $(TARGET)/initramfs-build 107 cp initramfs/init.sh $(TARGET)/initramfs-build/init.sh 108 cp $(TARGET)/rootfs-build/delegate $(TARGET)/initramfs-build/delegate 109 podman build -t crosvm_e2e_test_guest_initramfs $(TARGET)/initramfs-build -f initramfs/Containerfile 110 -mkdir -p $(TARGET)/initramfs-build/cpio-base 111 # Create container and export into squashfs, and don't forget to clean up 112 # the container afterwards. 113 set -x; \ 114 CONTAINER=$$(podman create crosvm_e2e_test_guest_initramfs); \ 115 podman export $$CONTAINER | tar -xf - -C $(TARGET)/initramfs-build/cpio-base; \ 116 podman rm $$CONTAINER; \ 117 cd $(TARGET)/initramfs-build/cpio-base; \ 118 find . -print0 | cpio --null --create --verbose --format=newc | gzip --best > $(TARGET)/initramfs.cpio.gz 119 120################################################################################ 121# Build kernel 122 123kernel: $(TARGET)/bzImage 124 125# Make this target PHONY to make sure everything is up to date with the kernel's make recipe. 126# You can use custom kernel source by running: 127# make kernel KERNEL_SRC_PATCHED=${PATH_TO_YOUR_KERNEL} 128# (Note: you have to manually apply the patches applied in %-patched recipe to pass all the tests.) 129.PHONY : $(TARGET)/bzImage 130$(TARGET)/bzImage : $(KERNEL_SRC_PATCHED) 131 mkdir -p $(KERNEL_BUILD) 132 cat kernel/common.config kernel/$(KERNEL_ARCH).config > $(KERNEL_BUILD)/.config 133 make -C $(KERNEL_SRC_PATCHED) O=$(KERNEL_BUILD) \ 134 ARCH=$(KERNEL_ARCH) \ 135 CROSS_COMPILE=$(CROSS_COMPILE) \ 136 -j$(shell nproc)\ 137 olddefconfig \ 138 $(KERNEL_BINARY) 139 cp $(KERNEL_BUILD)/arch/${KERNEL_ARCH}/boot/$(KERNEL_BINARY) $@ 140 141$(KERNEL_SRC_PATCHED): $(KERNEL_SRC_BASE) 142 rm -rf $@.tmp ; true # ignore failure 143 cp -r $(KERNEL_SRC_BASE) $@.tmp 144 git -C $@.tmp am $(KERNEL_PATCHES)/virtio_pvclock.patch 145 mv $@.tmp $@ 146 147$(KERNEL_SRC_BASE): 148 rm -rf $@ 149 git clone --depth 1 --branch $(KERNEL_BRANCH) $(KERNEL_REPO) $@ 150 151.PHONY: clean all update-prebuilts 152