Skip to content
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ test_results/
*.swp
*.tar.gz
*.tar.xz
vmlinux
vmlinux*

# API docs for local preview only.
_site/
_serve/

29 changes: 19 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ SWIFT_CONFIGURATION := $(if $(filter-out false,$(WARNINGS_AS_ERRORS)),-Xswiftc -

# Commonly used locations
UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m)
KERNEL_ARCH := $(if $(filter $(UNAME_M),aarch64 arm64),arm64,$(UNAME_M))
# Candidate kernel filenames in bin/ (compiled vmlinuz first, kata-fetched vmlinux fallback).
ifeq ($(KERNEL_ARCH),x86_64)
KERNEL_CANDIDATES := bin/vmlinuz-x86_64 bin/vmlinux-x86_64
else
KERNEL_CANDIDATES := bin/vmlinux-$(KERNEL_ARCH)
endif
ifeq ($(UNAME_S),Darwin)
SWIFT ?= /usr/bin/swift
else
Expand Down Expand Up @@ -169,25 +177,26 @@ coverage: test

.PHONY: integration
integration:
ifeq (,$(wildcard bin/vmlinux))
@echo No bin/vmlinux kernel found. See fetch-default-kernel target.
@exit 1
endif
@echo Running the integration tests...
@./bin/containerization-integration
@kernel="$$(for f in $(KERNEL_CANDIDATES); do [ -f $$f ] && echo $$f && break; done)"; \
if [ -z "$$kernel" ]; then \
echo "No kernel found. Looked for: $(KERNEL_CANDIDATES). See fetch-default-kernel target or build via kernel/Makefile."; \
exit 1; \
fi; \
echo "Running the integration tests with kernel $$kernel..."; \
./bin/containerization-integration --kernel "$$kernel"

.PHONY: fetch-default-kernel
fetch-default-kernel:
@mkdir -p .local/ bin/
ifeq (,$(wildcard .local/kata.tar.gz))
@curl -SsL -o .local/kata.tar.gz ${KATA_BINARY_PACKAGE}
endif
ifeq (,$(wildcard .local/vmlinux))
ifeq (,$(wildcard .local/vmlinux-$(KERNEL_ARCH)))
@tar -zxf .local/kata.tar.gz -C .local/ --strip-components=1
@cp -L .local/opt/kata/share/kata-containers/vmlinux.container .local/vmlinux
@cp -L .local/opt/kata/share/kata-containers/vmlinux.container .local/vmlinux-$(KERNEL_ARCH)
endif
ifeq (,$(wildcard bin/vmlinux))
@cp .local/vmlinux bin/vmlinux
ifeq (,$(wildcard bin/vmlinux-$(KERNEL_ARCH)))
@cp .local/vmlinux-$(KERNEL_ARCH) bin/vmlinux-$(KERNEL_ARCH)
endif

.PHONY: check
Expand Down
18 changes: 17 additions & 1 deletion Sources/Integration/Suite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,23 @@ struct IntegrationSuite: AsyncParsableCommand {
var bootlogDir: String = "./bin/integration-bootlogs"

@Option(name: .shortAndLong, help: "Path to a kernel binary")
var kernel: String = "./bin/vmlinux"
var kernel: String = Self.defaultKernelPath

#if arch(arm64)
private static let kernelCandidates = ["./bin/vmlinux-arm64"]
#elseif arch(x86_64)
private static let kernelCandidates = ["./bin/vmlinuz-x86_64", "./bin/vmlinux-x86_64"]
#else
private static let kernelCandidates = ["./bin/vmlinux"]
#endif

private static let defaultKernelPath: String = {
let fm = FileManager.default
for candidate in kernelCandidates where fm.fileExists(atPath: candidate) {
return candidate
}
return kernelCandidates[0]
}()

@Option(name: .shortAndLong, help: "Maximum number of concurrent tests")
var maxConcurrency: Int = 4
Expand Down
5 changes: 4 additions & 1 deletion examples/ctr-example/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

SWIFT = /usr/bin/swift

UNAME_M := $(shell uname -m)
KERNEL_ARCH := $(if $(filter $(UNAME_M),aarch64 arm64),arm64,$(UNAME_M))

.PHONY: all build clean run

all: run
Expand All @@ -41,4 +44,4 @@ fmt:
$(SWIFT) format --in-place --recursive Sources/
fetch-default-kernel:
$(MAKE) -C ../.. fetch-default-kernel
cp -L ../../.local/vmlinux ./vmlinux
cp -L ../../.local/vmlinux-$(KERNEL_ARCH) ./vmlinux-$(KERNEL_ARCH)
9 changes: 8 additions & 1 deletion examples/ctr-example/Sources/ctr-example/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@ struct CtrExample {
defer { current.tryReset() }

let initfsReference = "ghcr.io/apple/containerization/vminit:0.26.5"
let kernelPath = "./vmlinux"
#if arch(arm64)
let kernelCandidates = ["./vmlinux-arm64"]
#elseif arch(x86_64)
let kernelCandidates = ["./vmlinuz-x86_64", "./vmlinux-x86_64"]
#else
let kernelCandidates = ["./vmlinux"]
#endif
let kernelPath = kernelCandidates.first(where: { FileManager.default.fileExists(atPath: $0) }) ?? kernelCandidates[0]
print("Fetching base container filesystem...")
// Create container manager with file-based initfs
var manager = try await ContainerManager(
Expand Down
43 changes: 37 additions & 6 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,61 @@

KSOURCE ?= https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.5.tar.xz
KIMAGE ?= kernel-build:0.1
CURDIR := $(shell pwd)
GIT_VERSION := $(shell git -C $(CURDIR) rev-parse --short=12 HEAD 2>/dev/null || echo unknown)
MAKEFILE_DIR := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
GIT_VERSION := $(shell git -C $(MAKEFILE_DIR) rev-parse --short=12 HEAD 2>/dev/null || echo unknown)
TARGET_ARCH ?=

# Resolve the effective target arch (TARGET_ARCH override, else host).
EFFECTIVE_ARCH := $(if $(TARGET_ARCH),$(TARGET_ARCH),$(shell uname -m))
ifneq (,$(filter $(EFFECTIVE_ARCH),aarch64))
EFFECTIVE_ARCH := arm64
endif
ifneq (,$(filter $(EFFECTIVE_ARCH),amd64))
EFFECTIVE_ARCH := x86_64
endif

# Compressed (vmlinuz) for x86_64 bzImage; uncompressed (vmlinux) for arm64 Image.
ifeq ($(EFFECTIVE_ARCH),x86_64)
KERNEL_OUTPUT := vmlinuz-x86_64
else
KERNEL_OUTPUT := vmlinux-arm64
endif

BIN_DIR := $(abspath $(MAKEFILE_DIR)/../bin)

.DEFAULT_GOAL := all

.PHONY: all
all: kernel-build-image
all: kernel-build
all: kernel-install

.PHONY: kernel-build-image
kernel-build-image:
container build image/ -f image/Dockerfile -t ${KIMAGE}
container build $(MAKEFILE_DIR)/image -f $(MAKEFILE_DIR)/image/Dockerfile -t ${KIMAGE}

.PHONY: kernel-build
kernel-build:
ifeq (,$(wildcard source.tar.xz))
curl -SsL -o source.tar.xz ${KSOURCE}
ifeq (,$(wildcard $(MAKEFILE_DIR)/source.tar.xz))
curl -SsL -o $(MAKEFILE_DIR)/source.tar.xz ${KSOURCE}
endif
container run \
--cpus 8 \
--rm \
--memory 16g \
-v ${CURDIR}:/kernel \
-v $(MAKEFILE_DIR):/kernel \
--env LOCALVERSION=-cz-${GIT_VERSION} \
$(if $(TARGET_ARCH),--env TARGET_ARCH=$(TARGET_ARCH),) \
--cwd /kernel \
${KIMAGE} \
/bin/bash -c "./build.sh"

.PHONY: kernel-install
kernel-install:
@mkdir -p $(BIN_DIR)
@cp -L $(MAKEFILE_DIR)/$(KERNEL_OUTPUT) $(BIN_DIR)/$(KERNEL_OUTPUT)
@echo "Installed $(KERNEL_OUTPUT) -> $(BIN_DIR)/$(KERNEL_OUTPUT)"

.PHONY: x86_64
x86_64:
$(MAKE) all TARGET_ARCH=x86_64
7 changes: 6 additions & 1 deletion kernel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ This directory includes an optimized kernel configuration to produce a fast and
1. The build process relies on having the `container` tool installed (https://github.com/apple/container/releases).
2. Run `make`. This should create the image used for building the resulting Linux kernel, and then run a container with that image to perform the kernel build.

A `kernel/vmlinux` file will be the result of the build.
The build produces an arch-suffixed kernel image, copied into the repo's `bin/` directory:

- `make` (default) → `vmlinux-arm64` (uncompressed `Image`)
- `make x86_64` → `vmlinuz-x86_64` (compressed `bzImage`, cross-compiled inside the arm64 container)

The `z` suffix on the x86 name follows Linux convention for a compressed kernel image.
31 changes: 27 additions & 4 deletions kernel/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,36 @@

set -e

TARGET_ARCH="${TARGET_ARCH:-$(uname -m)}"

case "${TARGET_ARCH}" in
aarch64|arm64)
CONFIG=config-arm64
KARCH=arm64
CROSS_COMPILE=aarch64-linux-gnu-
IMAGE_PATH=arch/arm64/boot/Image
OUTPUT_NAME=vmlinux-arm64
;;
x86_64|amd64)
CONFIG=config-x86_64
KARCH=x86_64
CROSS_COMPILE=x86_64-linux-gnu-
IMAGE_PATH=arch/x86/boot/bzImage
OUTPUT_NAME=vmlinuz-x86_64
;;
*)
echo "Unsupported target architecture: ${TARGET_ARCH}" >&2
exit 1
;;
esac

mkdir -p /kbuild
tar -xf /kernel/source.tar.xz -C /kbuild --strip-components=1
cp /kernel/config-arm64 /kbuild/.config
cp "/kernel/${CONFIG}" /kbuild/.config

(
cd /kbuild
make olddefconfig && \
make -j$((`nproc`-1)) LOCALVERSION="${LOCALVERSION}" && \
cp arch/arm64/boot/Image /kernel/vmlinux
make ARCH="${KARCH}" CROSS_COMPILE="${CROSS_COMPILE}" olddefconfig && \
make ARCH="${KARCH}" CROSS_COMPILE="${CROSS_COMPILE}" -j$((`nproc`-1)) LOCALVERSION="${LOCALVERSION}" && \
cp "${IMAGE_PATH}" "/kernel/${OUTPUT_NAME}"
)
Loading
Loading