Skip to content
Merged
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
7 changes: 7 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ jobs:
- name: Build UKI for ${{ matrix.arch }}
run: make ${{ matrix.arch }}

- name: Copy public keys to arch directory
run: |
cp tools/build-uki/keys/*.cer tools/build-uki/${{ matrix.arch }}/
cp tools/build-uki/keys/*.guid tools/build-uki/${{ matrix.arch }}/

- name: Upload UKI artifacts for ${{ matrix.arch }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
Expand All @@ -32,6 +37,8 @@ jobs:
tools/build-uki/${{ matrix.arch }}/stage1
tools/build-uki/${{ matrix.arch }}/os-release
tools/build-uki/${{ matrix.arch }}/efi-vars.*
tools/build-uki/${{ matrix.arch }}/*.cer
tools/build-uki/${{ matrix.arch }}/*.guid

release-docker:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Dockerfile.build
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ RUN apt-get -qq update && \
sbsigntool \
util-linux \
uuid-runtime \
wget && \
wget \
xz-utils && \
pip3 install --break-system-packages virt-firmware

# Reproducible builds environment
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -qq update && \
dnsmasq \
swtpm swtpm-tools \
tpm2-tools xxd \
gh
gh jq

RUN groupadd -g 1000 vscode-dc && useradd -u 1000 -g 1000 -d /src -s /bin/bash vscode-dc

Expand Down
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ tools/build-uki/%/busybox:
tools/build-uki/%/stub.efi:
$(MAKE) -C tools/build-uki $*/stub.efi

tools/build-uki/%/kernel.rpm:
$(MAKE) -C tools/build-uki $*/kernel.rpm
tools/build-uki/%/kernel-core.rpm:
$(MAKE) -C tools/build-uki $*/kernel-core.rpm

tools/build-uki/%/kernel-modules-core.rpm:
$(MAKE) -C tools/build-uki $*/kernel-modules-core.rpm

tools/qemu-test/%:
$(MAKE) -C tools/qemu-test $*
Expand Down Expand Up @@ -130,7 +133,7 @@ docker-shell-dev: docker-build-dev

# Build the UKI and boot disk for a specific architecture
# This creates: UKI, disk image with EFI boot structure
tools/build-uki/%/boot.disk: tools/build-uki/%/busybox tools/build-uki/%/stage1 tools/build-uki/%/stub.efi tools/build-uki/%/kernel.rpm tools/build-uki/keys/db.crt
tools/build-uki/%/boot.disk: tools/build-uki/%/busybox tools/build-uki/%/stage1 tools/build-uki/%/stub.efi tools/build-uki/%/kernel-core.rpm tools/build-uki/%/kernel-modules-core.rpm tools/build-uki/keys/db.crt
$(DOCKER_RUN) $(DOCKER_OPT_DOCKER) -e ARCH=$* \
$(BUILD_IMAGE) ./tools/build-uki/build.sh

Expand Down
32 changes: 26 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,36 @@ You can run any statically linked Linux ELF, but the minimal filesystem only has

## Cloud Deployment

Deploy the same config across AWS, GCP, or Azure:
Deploy the same config across AWS, GCP, or Azure. Publish scripts are provided in `tools/publish/`.

### AWS EC2

Requires Nitro v4+ instances with TPM 2.0 and UEFI boot support:

| Architecture | Tested Instance | Notes |
|---|---|---|
| x86_64 | `c6i.large` | Intel Xeon Gen 3, Nitro v4 |
| aarch64 | `c7g.medium` | Graviton 3, Nitro v4 |

```bash
# AWS
aws ec2 run-instances --user-data file://user-data.json --tpm-support v2.0 ...
tools/publish/ec2/create-ami.sh us-east-1 x86_64 local
```

### GCP Confidential VMs

Requires Confidential VM instances with Shielded VM and custom Secure Boot keys. Uses GVE network driver (virtio-net not available on Confidential VMs).

# GCP
gcloud compute instances create --metadata user-data="$(cat user-data.json)" ...
| Architecture | Tested Instance | Notes |
|---|---|---|
| x86_64 | `n2d-standard-2` | AMD SEV-SNP |

# Azure
```bash
tools/publish/gcp/create-image.sh my-project x86_64 local
```

### Azure

```bash
az vm create --user-data "$(cat user-data.json | base64 -w0)" ...
```

Expand Down
85 changes: 56 additions & 29 deletions tools/build-uki/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,40 @@ BUSYBOX_APK := busybox-static-$(BUSYBOX_VERSION).apk
BUSYBOX_URL_x86_64 := $(ALPINE_BASE_URL)/x86_64/$(BUSYBOX_APK)
BUSYBOX_URL_aarch64 := $(ALPINE_BASE_URL)/aarch64/$(BUSYBOX_APK)

# systemd-boot-unsigned from Amazon Linux (provides EFI stub)
# systemd-boot-unsigned from Fedora 41 (provides EFI stub)
# v256 supports PE vmlinuz on aarch64 (LoadImage/StartImage instead of direct jump)
# x86_64 provides: /usr/lib/systemd/boot/efi/linuxx64.efi.stub
# aarch64 provides: /usr/lib/systemd/boot/efi/linuxaa64.efi.stub
SYSTEMD_BOOT_VERSION := 252.23-8.amzn2023
SYSTEMD_BOOT_SHA256_x86_64 := d036e8fa194d4d660ef05fd2d4f12037a251fee0f20adfd6a45992d83532bbc9
SYSTEMD_BOOT_SHA256_aarch64 := ad89706bf213071aa3053fa23a19452bac5d95ab618f32ace3e485eea0e6eea3
SYSTEMD_BOOT_VERSION := 256.17-1.fc41
SYSTEMD_BOOT_SHA256_x86_64 := ec5ce2a3e685750a7743cf933ed9ff583fe4e90cef743c76349a158631b3dae5
SYSTEMD_BOOT_SHA256_aarch64 := f188ea9f918be9c2314c4208c0c247bd6dc7eae96df85fa9e3c672619853ddcf
SYSTEMD_BOOT_RPM_x86_64 := systemd-boot-unsigned-$(SYSTEMD_BOOT_VERSION).x86_64.rpm
SYSTEMD_BOOT_RPM_aarch64 := systemd-boot-unsigned-$(SYSTEMD_BOOT_VERSION).aarch64.rpm
SYSTEMD_BOOT_URL_x86_64 := https://cdn.amazonlinux.com/al2023/blobstore/$(SYSTEMD_BOOT_SHA256_x86_64)/$(SYSTEMD_BOOT_RPM_x86_64)
SYSTEMD_BOOT_URL_aarch64 := https://cdn.amazonlinux.com/al2023/blobstore/$(SYSTEMD_BOOT_SHA256_aarch64)/$(SYSTEMD_BOOT_RPM_aarch64)

# Amazon Linux 2023 kernel 6.12 and modules
AMAZON_KERNEL_PACKAGE := kernel6.12
AMAZON_KERNEL_SHA256_x86_64 := 2583dc9eb7ab114238aaecbbe76ab3d0bb650a8ed0ef0b666b54573dc4c1da5e
AMAZON_KERNEL_SHA256_aarch64 := 5eba5a6cffb9a5798533834bff1cb39d5d8303a454dc639c97179914ecafa7fb
AMAZON_KERNEL_VERSION := 6.12.53-69.119.amzn2023
AMAZON_KERNEL_RPM_x86_64 := $(AMAZON_KERNEL_PACKAGE)-$(AMAZON_KERNEL_VERSION).x86_64.rpm
AMAZON_KERNEL_RPM_aarch64 := $(AMAZON_KERNEL_PACKAGE)-$(AMAZON_KERNEL_VERSION).aarch64.rpm
AMAZON_KERNEL_URL_x86_64 := https://cdn.amazonlinux.com/al2023/blobstore/$(AMAZON_KERNEL_SHA256_x86_64)/$(AMAZON_KERNEL_RPM_x86_64)
AMAZON_KERNEL_URL_aarch64 := https://cdn.amazonlinux.com/al2023/blobstore/$(AMAZON_KERNEL_SHA256_aarch64)/$(AMAZON_KERNEL_RPM_aarch64)
SYSTEMD_BOOT_URL_x86_64 := https://kojipkgs.fedoraproject.org/packages/systemd/256.17/1.fc41/x86_64/$(SYSTEMD_BOOT_RPM_x86_64)
SYSTEMD_BOOT_URL_aarch64 := https://kojipkgs.fedoraproject.org/packages/systemd/256.17/1.fc41/aarch64/$(SYSTEMD_BOOT_RPM_aarch64)

# Fedora 41 kernel 6.12 (has both ena and gve drivers)
FEDORA_KERNEL_VERSION := 6.12.4-200.fc41
FEDORA_KERNEL_BASE_URL := https://kojipkgs.fedoraproject.org/packages/kernel/6.12.4/200.fc41

# kernel-core (contains vmlinuz)
FEDORA_KERNEL_CORE_SHA256_x86_64 := f7df5e7d36b7ed4c311f358340fcf2ae414cd1b4b8ad8d8555bb5cae2403cfc3
FEDORA_KERNEL_CORE_SHA256_aarch64 := 5494b00c95832eb52b39b306fd4ab912893824cd0419612fb52fc97643fa56cb
FEDORA_KERNEL_CORE_RPM_x86_64 := kernel-core-$(FEDORA_KERNEL_VERSION).x86_64.rpm
FEDORA_KERNEL_CORE_RPM_aarch64 := kernel-core-$(FEDORA_KERNEL_VERSION).aarch64.rpm
FEDORA_KERNEL_CORE_URL_x86_64 := $(FEDORA_KERNEL_BASE_URL)/x86_64/$(FEDORA_KERNEL_CORE_RPM_x86_64)
FEDORA_KERNEL_CORE_URL_aarch64 := $(FEDORA_KERNEL_BASE_URL)/aarch64/$(FEDORA_KERNEL_CORE_RPM_aarch64)

# kernel-modules-core (contains core .ko modules including gve and ena)
FEDORA_KERNEL_MODULES_SHA256_x86_64 := 7d9e7d9f925de56f04c103a65011285d0ded2fc45a79ca1b300828316916200c
FEDORA_KERNEL_MODULES_SHA256_aarch64 := 4bbe3e2922b044519d126cc1a06f0416d3f4f26523f0bae75d5fe355d4abb7ac
FEDORA_KERNEL_MODULES_RPM_x86_64 := kernel-modules-core-$(FEDORA_KERNEL_VERSION).x86_64.rpm
FEDORA_KERNEL_MODULES_RPM_aarch64 := kernel-modules-core-$(FEDORA_KERNEL_VERSION).aarch64.rpm
FEDORA_KERNEL_MODULES_URL_x86_64 := $(FEDORA_KERNEL_BASE_URL)/x86_64/$(FEDORA_KERNEL_MODULES_RPM_x86_64)
FEDORA_KERNEL_MODULES_URL_aarch64 := $(FEDORA_KERNEL_BASE_URL)/aarch64/$(FEDORA_KERNEL_MODULES_RPM_aarch64)

ARCHS = x86_64 aarch64
TARGETS = busybox stub.efi kernel.rpm
TARGETS = busybox stub.efi kernel-core.rpm kernel-modules-core.rpm

all: $(ARCHS)

Expand All @@ -49,7 +60,7 @@ aarch64: $(addprefix aarch64/,$(TARGETS))
@tar --warning=no-unknown-keyword -xzOf $< bin/busybox.static > "$@"
@chmod +x "$@"

# Download systemd-boot-unsigned RPM from Amazon Linux
# Download systemd-boot-unsigned RPM from Fedora
x86_64/$(SYSTEMD_BOOT_RPM_x86_64):
@./download-and-verify.sh "$@" "$(SYSTEMD_BOOT_SHA256_x86_64)" "$(SYSTEMD_BOOT_URL_x86_64)"

Expand All @@ -67,22 +78,36 @@ aarch64/stub.efi: aarch64/$(SYSTEMD_BOOT_RPM_aarch64)
@rpm2cpio $< | cpio -i --quiet --to-stdout ./usr/lib/systemd/boot/efi/linuxaa64.efi.stub > $@
@chmod +x $@

# Download Amazon Linux kernel RPM from blobstore
x86_64/$(AMAZON_KERNEL_RPM_x86_64):
@./download-and-verify.sh "$@" "$(AMAZON_KERNEL_SHA256_x86_64)" "$(AMAZON_KERNEL_URL_x86_64)"
# Download Fedora kernel-core RPMs from kojipkgs
x86_64/$(FEDORA_KERNEL_CORE_RPM_x86_64):
@./download-and-verify.sh "$@" "$(FEDORA_KERNEL_CORE_SHA256_x86_64)" "$(FEDORA_KERNEL_CORE_URL_x86_64)"

x86_64/kernel.rpm: x86_64/$(AMAZON_KERNEL_RPM_x86_64)
x86_64/kernel-core.rpm: x86_64/$(FEDORA_KERNEL_CORE_RPM_x86_64)
@ln -sf $(notdir $<) $@

aarch64/$(AMAZON_KERNEL_RPM_aarch64):
@./download-and-verify.sh "$@" "$(AMAZON_KERNEL_SHA256_aarch64)" "$(AMAZON_KERNEL_URL_aarch64)"
aarch64/$(FEDORA_KERNEL_CORE_RPM_aarch64):
@./download-and-verify.sh "$@" "$(FEDORA_KERNEL_CORE_SHA256_aarch64)" "$(FEDORA_KERNEL_CORE_URL_aarch64)"

aarch64/kernel.rpm: aarch64/$(AMAZON_KERNEL_RPM_aarch64)
aarch64/kernel-core.rpm: aarch64/$(FEDORA_KERNEL_CORE_RPM_aarch64)
@ln -sf $(notdir $<) $@

# Retrieve package URLs from dnf
# Download Fedora kernel-modules-core RPMs from kojipkgs
x86_64/$(FEDORA_KERNEL_MODULES_RPM_x86_64):
@./download-and-verify.sh "$@" "$(FEDORA_KERNEL_MODULES_SHA256_x86_64)" "$(FEDORA_KERNEL_MODULES_URL_x86_64)"

x86_64/kernel-modules-core.rpm: x86_64/$(FEDORA_KERNEL_MODULES_RPM_x86_64)
@ln -sf $(notdir $<) $@

aarch64/$(FEDORA_KERNEL_MODULES_RPM_aarch64):
@./download-and-verify.sh "$@" "$(FEDORA_KERNEL_MODULES_SHA256_aarch64)" "$(FEDORA_KERNEL_MODULES_URL_aarch64)"

aarch64/kernel-modules-core.rpm: aarch64/$(FEDORA_KERNEL_MODULES_RPM_aarch64)
@ln -sf $(notdir $<) $@

# Retrieve package URLs from koji (for reference)
kernel-hash-%:
docker run --rm --platform linux/amd64 amazonlinux:latest bash -c "dnf repoquery --forcearch=$* --arch=$* --location $(AMAZON_KERNEL_PACKAGE)-$(AMAZON_KERNEL_VERSION).$*"
@echo "Fedora kernel: $(FEDORA_KERNEL_PACKAGE)-$(FEDORA_KERNEL_VERSION).$*"
@echo "Download from: https://koji.fedoraproject.org/koji/buildinfo?buildID=2599252"

clean:
rm -rf x86_64 aarch64
Expand All @@ -94,5 +119,7 @@ check-urls:
@curl -sfI "$(BUSYBOX_URL_aarch64)" > /dev/null && echo "OK: busybox aarch64" || echo "FAIL: busybox aarch64"
@curl -sfI "$(SYSTEMD_BOOT_URL_x86_64)" > /dev/null && echo "OK: systemd-boot x86_64" || echo "FAIL: systemd-boot x86_64"
@curl -sfI "$(SYSTEMD_BOOT_URL_aarch64)" > /dev/null && echo "OK: systemd-boot aarch64" || echo "FAIL: systemd-boot aarch64"
@curl -sfI "$(AMAZON_KERNEL_URL_x86_64)" > /dev/null && echo "OK: kernel x86_64" || echo "FAIL: kernel x86_64"
@curl -sfI "$(AMAZON_KERNEL_URL_aarch64)" > /dev/null && echo "OK: kernel aarch64" || echo "FAIL: kernel aarch64"
@curl -sfI "$(FEDORA_KERNEL_CORE_URL_x86_64)" > /dev/null && echo "OK: kernel-core x86_64" || echo "FAIL: kernel-core x86_64"
@curl -sfI "$(FEDORA_KERNEL_CORE_URL_aarch64)" > /dev/null && echo "OK: kernel-core aarch64" || echo "FAIL: kernel-core aarch64"
@curl -sfI "$(FEDORA_KERNEL_MODULES_URL_x86_64)" > /dev/null && echo "OK: kernel-modules-core x86_64" || echo "FAIL: kernel-modules-core x86_64"
@curl -sfI "$(FEDORA_KERNEL_MODULES_URL_aarch64)" > /dev/null && echo "OK: kernel-modules-core aarch64" || echo "FAIL: kernel-modules-core aarch64"
Loading