Skip to content

feat(virtio-linux): EFI-bootable kernel + vmlinuz-efi output#208

Open
norrietaylor wants to merge 2 commits into
mainfrom
feat/virtio-linux-efi
Open

feat(virtio-linux): EFI-bootable kernel + vmlinuz-efi output#208
norrietaylor wants to merge 2 commits into
mainfrom
feat/virtio-linux-efi

Conversation

@norrietaylor
Copy link
Copy Markdown
Member

@norrietaylor norrietaylor commented May 29, 2026

Makes the virtio-linux kernel directly EFI-bootable, so it can boot under EFI firmware (e.g. OVMF, as used by libkrun-efi/krunkit) in addition to the existing direct-kernel-load VMMs.

Changes:

  • Enable CONFIG_EFI, CONFIG_EFI_STUB, CONFIG_ACPI, CONFIG_DMI, CONFIG_EFIVAR_FS — adds the PE/COFF EFI-stub entry point and the ACPI/DMI support EFI firmware needs. Additive: the kernel still boots qemu/cloud-hypervisor/firecracker unchanged.
  • New output vmlinuz-efi: the EFI-firmware-bootable image (uncompressed Image on arm64, since OVMF cannot unwrap Image.gz; the same bzImage on x86). The existing vmlinuz is unchanged.
  • Bake a forced kernel cmdline (CONFIG_CMDLINE_FORCE + console=hvc0 root=/dev/vda2 rootfstype=ext4 ro init=/sbin/stub-init). OVMF launches the EFI-stub kernel with empty LoadOptions, so without a built-in cmdline the kernel has no root= and panics. This is a purpose-built microVM kernel for the Minimal VM image, whose disk convention is GPT { p1=ESP, p2=ext4 root } on /dev/vda — fair to bake. init=/sbin/stub-init is the current boot-verification entrypoint and becomes the in-VM agent (/sbin/init) later.

Context: consumed by the alpine-virtio-linux package, which assembles an EFI-bootable GPT disk (ESP + ext4 root) that krunkit boots.

Validation: validated end-to-end against krunkit 1.2.1 (libkrun-efi) on Apple Silicon — OVMF → kernel 6.12.43 → ext4 root → init. The minimal build CI check (external Linux build) is green, and minimal check --packages virtio-linux passes all 14 checkers locally (the artifact contains both vmlinuz and the EFI vmlinuz-efi).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

📝 Walkthrough

Walkthrough

This PR extends virtio-linux kernel packaging by adding EFI-bootable kernel support. The build script now defines architecture-specific EFI targets, configures the kernel with EFI options, builds both normal and EFI variants, and publishes them as separate outputs. The build specification declares the new EFI artifact.

Changes

EFI bootable kernel support

Layer / File(s) Summary
EFI kernel target and build configuration
packages/virtio-linux/build.sh
Architecture-specific EFI kernel targets defined (x86_64 bzImage, aarch64 uncompressed Image). EFI-related kernel config options (EFI, EFI_STUB, ACPI, DMI, EFIVAR_FS) added with dependency resolution. Both normal and EFI kernel targets built and published as vmlinuz and vmlinuz-efi.
EFI output artifact declaration
packages/virtio-linux/build.ncl
vmlinuz_efi output declared in build specification, matching EFI kernel artifacts from usr/share/virtio-linux/vmlinuz-efi.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • gominimal/pkgs#197: Extends existing kernel packaging logic from this PR by adding vmlinuz-efi output/copying and EFI-specific kernel build/config steps.

Poem

🐰 A kernel now boots from firmware's gold,
With EFI whispers, both new and bold,
x86 and ARM in tandem run free,
Building bzImage and Image with glee!
vmlinuz-efi hops forth—hooray! 🥾

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding EFI-bootable kernel support with a new vmlinuz-efi output artifact, which aligns with the core objective of the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/virtio-linux-efi

Comment @coderabbitai help to get the list of available commands and usage tips.

OVMF launches the EFI-stub kernel with empty LoadOptions, so a built-in,
forced cmdline is required or the kernel boots with no root= and panics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# the in-VM agent (/sbin/init) in a later iteration.
$CFG --enable CMDLINE_BOOL
$CFG --set-str CMDLINE "console=hvc0 root=/dev/vda2 rootfstype=ext4 ro init=/sbin/stub-init"
$CFG --enable CMDLINE_FORCE
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Baking the cmdline here ties this kernel to the VM-image disk convention (root=/dev/vda2, init=/sbin/stub-init). That's intentional for a purpose-built microVM kernel and needs zero extra packages.

The alternative, if this kernel ever needs to stay generic (multiple image variants with different cmdlines, an initrd, or secure/measured boot): drop CMDLINE* here and supply the cmdline at the image-assembly layer via a UKIukify/systemd-stub embeds a .cmdline section into the EFI binary, set per-image without recompiling the kernel. Costs a systemd-stub package (+ deps), so deferred until one of those needs it. init=/sbin/stub-init also becomes the in-VM agent (/sbin/init) later.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can typically also set the kernel command line when you load the kernel, so i guess most of the time this is mostly a default


outputs = {
vmlinuz = { glob = "usr/share/virtio-linux/vmlinuz" } | OutputData,
vmlinuz_efi = { glob = "usr/share/virtio-linux/vmlinuz-efi" } | OutputData,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to just ship vmlinuz_efi and skip the non-efi one, if we need efi for minvmd?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants