badappleuefi-rs/README.md
2025-10-01 08:11:05 +02:00

80 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Bad Apple for UEFI (Rust)
Firmware payload that plays the Bad Apple animation directly from a UEFI image. The project uses the [`uefi`](https://github.com/rust-osdev/uefi-rs) crate, renders video frames through GOP, and synthesises audio via the legacy PC speaker using a 1-bit sigma-delta stream. Everything fits inside a `no_std` Rust binary and can be driven under QEMU.
## Repository layout
- `src/` modular firmware code (`app` contains assets, graphics, audio, timing, and player logic).
- `assets/` tiny demo clip/audio used as an embedded fallback.
- `tools/` helper utilities, notably `process_badapple.py` for converting the real video/audio into firmware-friendly blobs.
- `ai/state.json` persistent JSON with personas/tasks as requested.
- `flake.nix` reproducible Nix environment with Rust, ffmpeg, and QEMU.
## Building the EFI binary
1. Ensure you have a recent stable Rust toolchain with the UEFI target installed:
```bash
rustup target add aarch64-unknown-uefi
```
2. Build the binary:
```bash
cargo build --release --target aarch64-unknown-uefi
```
The resulting image will be at `target/aarch64-unknown-uefi/release/badapple-uefi.efi`.
Using Nix instead? Enter the dev shell or boot straight from the flake:
```bash
nix develop
# (rustup target add aarch64-unknown-uefi is invoked automatically in the shell)
# Build & boot in one go under QEMU (cross-emulates aarch64 firmware):
nix run .#qemu
```
## Preparing real assets
The repository embeds a tiny placeholder clip so builds work immediately. To convert the actual Bad Apple video/audio:
```bash
python3 tools/process_badapple.py \
--input /path/to/badapple.mp4 \
--output-dir build/assets \
--width 320 --height 240 --fps 30 \
--sample-rate 44100
```
Copy the generated `video.baa` and `audio.pdm` onto the EFI system partition alongside the application under `\EFI\BADAPPLE\`. The firmware attempts to load external assets first, then falls back to the embedded demo when they are missing.
### Asset format summary
- `video.baa`: magic `"BAA\0"`, header with width/height/fps/frame count, followed by 1-bit packed frames (LSB-first).
- `audio.pdm`: magic `"BAP\0"`, header with sample rate and sample count, followed by 1-bit sigma-delta stream (LSB-first).
## Running under QEMU
A minimal invocation after copying the EFI binary and assets to a FAT image might look like:
```bash
qemu-system-aarch64 \
-machine virt \
-cpu cortex-a72 \
-m 1024 \
-drive if=pflash,format=raw,readonly=on,file=/path/to/AAVMF_CODE.fd \
-drive if=pflash,format=raw,file=/path/to/AAVMF_VARS.fd \
-drive file=fat:rw:esp,format=raw \
-device virtio-gpu-pci \
-device ramfb \
-serial mon:stdio
```
Make sure the `esp` directory contains `EFI/BOOT/BOOTAA64.EFI` (your compiled binary) plus the `EFI/BADAPPLE` assets. Audio output is currently disabled on non-x86 platforms because the legacy PC speaker is unavailable; video playback continues in sync.
## Notes & limitations
- Audio playback uses the legacy PC speaker path on x86 machines; on aarch64 builds the backend is currently silent because that device is absent.
- Timing relies on TSC calibration during boot services. Firmware with non-constant TSCs may require additional guarding.
- Video rendering assumes the selected GOP mode exposes a writable framebuffer (non-BLT-only). Modes with vendor-specific bitmasks are supported via mask calculation.
## Next steps
- Replace the placeholder clip with the full Bad Apple dataset via the tooling above.
- Consider double buffering and smarter frame pacing to reduce tearing.
- Experiment with richer audio backends (e.g. direct HDA/AC97 programming) if available on your platform.