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
4 changes: 2 additions & 2 deletions .github/workflows/ci_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ jobs:
# available at this stage covers that much. Plain TCG, so no KVM and
# no privileged container are required.
#
# x86_64 is absent on purpose: q35 has no bare-ELF equivalent of
# -kernel, so that path needs a UEFI stub before it can boot at all.
# x86_64 is absent on purpose: QEMU's -kernel loads a 64-bit ELF only
# with a Xen PVH note, and the image has neither that nor a UEFI stub.
# `cargo xtask boot-test --arch x86_64` says so explicitly rather
# than failing obscurely.
# Two boots: the ordinary path must greet, and the provoked path
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ Release codenames follow the six Noongar seasons — Birak, Bunuru, Djeran, Maku

### Fixed

- **The x86_64 docs no longer say `q35` has no bare-ELF `-kernel`.** `CLAUDE.md`, the README, the
x86_64 module, `xtask`'s refusal and a CI comment all claimed it. QEMU's x86 loader does take a
64-bit ELF through `-kernel` when it carries a Xen PVH note (`XEN_ELFNOTE_PHYS32_ENTRY`,
`hw/i386/x86-common.c`), and refuses this image only because it has none — reproduced on the
pinned QEMU 11.0.3, which reports "Error loading uncompressed kernel without PVH ELF Note". The
corrected text states the fact and leaves the choice between PVH and a UEFI stub to the x86_64
boot RFC.
- **xtask validates its workspace root at the source.** CodeQL's one open alert flagged the image
path as depending on a user-provided value (`CARGO_MANIFEST_DIR`). There is no privilege boundary
in xtask for a hostile value to cross — cargo sets the variable, and the tool runs with the
Expand Down
10 changes: 6 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ Independently of that, a microkernel must not touch registers it would have to
save and restore on every context switch: FP/SIMD belongs to userspace, enabled
per process and saved lazily, once there is a userspace.

aarch64 boots. x86_64 compiles and links but does not boot: `q35` has no
bare-ELF equivalent of `-kernel`, so it needs a UEFI stub first. Its entry point
aarch64 boots. x86_64 compiles and links but does not boot. QEMU's x86 `-kernel`
loads a 64-bit ELF only if it carries a Xen PVH note
(`XEN_ELFNOTE_PHYS32_ENTRY`), which this image does not; whether x86_64 enters
through PVH, a UEFI stub or both is a decision for its boot RFC. Its entry point
nevertheless calls straight through into the kernel proper, deliberately — an
entry that merely halted would leave everything above `arch` as dead code on that
target, and the second Tier-1 build would then prove nothing.
entry that merely halted would leave everything above `arch` as dead code on
that target, and the second Tier-1 build would then prove nothing.

## Building

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ rests on: link script, boot stub, stack, `.bss`, the hardware-abstraction
boundary, and the console.

x86_64 compiles and links against the same architecture-independent kernel, which
is what keeps the hardware-abstraction boundary honest, but it does not boot yet —
`q35` needs a UEFI stub first.
is what keeps the hardware-abstraction boundary honest, but it does not boot yet:
the image carries neither the Xen PVH note QEMU's `-kernel` needs nor a UEFI stub.

## Building

Expand Down
12 changes: 7 additions & 5 deletions kernel/src/arch/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
//!
//! What is missing, in the order it will be needed:
//!
//! - A UEFI entry path. `q35` has no equivalent of `-kernel` for a bare ELF, so
//! this needs a proper PE/COFF stub or a bootloader shim plus an ESP image.
//! - An entry path. QEMU's x86 `-kernel` loads a 64-bit ELF only if it carries
//! a Xen PVH note (`XEN_ELFNOTE_PHYS32_ENTRY`), entering it in 32-bit protected
//! mode; real hardware needs a UEFI stub. Which this target gets first is a
//! decision for its boot RFC.
//! - A console. The 16550 UART at `0x3f8` is the counterpart of the PL011, and
//! is where the console will land; the UEFI GOP framebuffer comes later.
//! - GDT and IDT, neither of which AArch64 needs before its first print, and a
Expand All @@ -22,9 +24,9 @@

/// The ELF entry point.
///
/// **This image cannot boot.** There is no UEFI stub, no multiboot header, no
/// descriptor tables and no stack of our own, so nothing will ever transfer
/// control here in practice.
/// **This image cannot boot.** There is no PVH note, no UEFI stub, no multiboot
/// header, no descriptor tables and no stack of our own, so nothing will ever
/// transfer control here in practice.
///
/// It nevertheless calls straight through to the kernel proper, and that is the
/// point: it makes the architecture-independent kernel genuinely compile and link
Expand Down
10 changes: 6 additions & 4 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,12 @@ fn build(arch: Arch, release: bool, features: Option<&str>) -> Result<PathBuf> {
/// Rejects architectures whose boot path is not implemented yet.
fn require_bootable(arch: Arch) -> Result<()> {
if arch == Arch::X86_64 {
return Err("the x86_64 boot path is not implemented yet — \
q35 has no bare-ELF equivalent of -kernel, so this needs a \
UEFI stub and an ESP image first (see kernel/src/arch/x86_64/mod.rs)"
.into());
return Err(
"the x86_64 boot path is not implemented yet — the image has \
neither the Xen PVH note QEMU's -kernel needs for a 64-bit ELF \
nor a UEFI stub (see kernel/src/arch/x86_64/mod.rs)"
.into(),
);
}
Ok(())
}
Expand Down