# Network Booting the n-os-tr ISO from the Internet

## Status: **Paused / On Hold**

This document captures the design thinking, hardware validation, and implementation
plan for letting a client machine boot the [n-os-tr live ISO](../iso/) directly from
a URL on the internet — no local installation media required.

**Current state:** feasibility fully validated on the target hardware. Server-side
infrastructure not yet built. Resume here when ready.

---

## 1. The Goal

Make it possible to power on a bare-metal machine, press a key, and have it boot
straight into a running n-os-tr live environment whose kernel, initrd, and root
filesystem were downloaded over HTTPS from a server on the public internet at
boot time. No USB stick, no local disk, no LAN-side boot infrastructure required.

This complements — rather than replaces — the ISO file we already produce in
[`build.sh`](../build.sh). The ISO remains the primary deliverable; network boot
becomes a second distribution channel for that same set of artifacts.

---

## 2. Options Considered

Five distinct network-boot approaches were evaluated. They are listed in order
of "how close to the goal of booting from an internet URL with nothing on the LAN".

### Option 1: UEFI HTTP(S) Boot (firmware-native)
Modern UEFI 2.5+ firmware (≈2015 and newer) can itself fetch a `.efi` bootloader
over HTTP/HTTPS from any URL. No PXE server, no TFTP, no USB stick. You enter
the URL into the BIOS (or supply it via DHCP option 67) and the firmware does
the rest.

- **Pros:** zero LAN-side infrastructure, cleanest flow, one-time BIOS setup.
- **Cons:** requires UEFI 2.5+ with the feature exposed; older BIOSes don't have it;
  many consumer BIOSes hide or restrict the option.
- **Selected as primary path for this project.** See §4 for hardware validation.

### Option 2: Classic PXE with iPXE chainload
BIOS uses its PXE Option ROM to DHCP on the LAN and TFTP-load a bootloader.
That bootloader is [iPXE](https://ipxe.org), which then has full HTTPS support
and fetches everything else from the internet.

- **Pros:** works on essentially any BIOS from ~2005 onward. Well-documented.
- **Cons:** requires a DHCP and TFTP server on the LAN. More infrastructure setup.
- **Secondary fallback** if HTTP Boot ever becomes unavailable.

### Option 3: iPXE on a USB stick (or CD)
Flash the ~1 MB [`ipxe.usb`](https://boot.ipxe.org/ipxe.usb) image to any USB drive
and boot from USB. iPXE launches, reaches the internet over HTTPS, and fetches
the ISO assets. Once the stick is made, it's effectively a permanent
"network boot" key — the ISO lives on the internet and can be updated server-side
without touching the stick.

- **Pros:** works on any machine that can boot USB (i.e. all of them). Zero
  BIOS configuration needed. Zero LAN infrastructure needed.
- **Cons:** requires distributing a physical medium one time per machine.
- **Universal fallback** when neither HTTP Boot nor PXE are usable.

### Option 4: netboot.xyz
Hosted iPXE menu service at [netboot.xyz](https://netboot.xyz). Flash their USB
or point PXE at their URL; get a menu of hundreds of bootable OSes. Can be
extended with custom menu entries for your own ISO.

- **Pros:** no build step needed; community-maintained.
- **Cons:** dependency on third-party service; extra indirection for a
  single-ISO use case.
- **Not chosen.** More value for general-purpose multi-distro booting than for
  a single project's distribution channel.

### Option 5: GRUB with `http` + `loopback` modules
GRUB 2 can load `.iso` files over HTTP and loopback-mount them using the
`http` and `net` modules. Requires GRUB already installed somewhere
(local disk, USB, or chainloaded).

- **Pros:** familiar bootloader; loopback-mount of real ISOs.
- **Cons:** niche; less common tooling; redundant next to iPXE.
- **Not chosen.**

---

## 3. Decision Tree

```mermaid
flowchart TD
    Start[Want to netboot ISO from the internet] --> Q1{UEFI HTTP Boot<br/>available?}
    Q1 -->|Yes| UEFI[Configure URL in BIOS<br/>firmware fetches .efi]
    Q1 -->|No| Q2{BIOS supports<br/>PXE?}
    Q2 -->|Yes| Q3{Can you run a<br/>LAN DHCP+TFTP server?}
    Q3 -->|Yes| PXE[Local DHCP+TFTP<br/>chainload iPXE to HTTPS]
    Q3 -->|No| USB1[iPXE USB stick]
    Q2 -->|No| USB2[iPXE USB stick]
    UEFI --> ISO[ISO served from HTTPS]
    PXE --> ISO
    USB1 --> ISO
    USB2 --> ISO
```

---

## 4. Hardware Validation (Target: ASRock B650I Lightning WiFi)

The target platform is the ASRock B650I Lightning WiFi motherboard (AMD AM5,
Ryzen 7000 series CPUs, 2.5 GbE Realtek RTL8125BG, Wi-Fi 6E).
Reference: [`B650I Lightning WiFi.pdf`](../B650I%20Lightning%20WiFi.pdf).

### 4.1 Firmware Facts
From the manual's Section 1.2 Specifications:
- **BIOS family:** AMI Aptio V UEFI ("AMI UEFI Legal BIOS with GUI support", p. 5)
- **Onboard LAN:** Dragon RTL8125BG 2.5 GbE (p. 3)
- **Wi-Fi:** 802.11ax Wi-Fi 6E module (p. 3)
- **BIOS Flashback button:** present (Section 2.13, pp. 47–48) — allows BIOS
  update with no CPU, RAM, or GPU installed.

### 4.2 BIOS Revision Tested
- **Current BIOS on the unit:** version `3.01` (released 2024-05-14,
  AGESA 1.1.7.0)
- **Latest stable at time of writing:** `4.10` (2026-03-03, AGESA 1.3.0.0a)
- None of the release notes between `1.28` (initial) and `4.10` mention
  Network Stack / HTTP Boot / PXE changes — the feature set for UEFI networking
  has been stable across all revisions. Updating is therefore not expected to
  add or remove HTTP Boot capability.

### 4.3 CSM (Legacy BIOS Compatibility)
- CSM cannot be persistently enabled on this board. Every attempt resets to
  disabled on reboot. This is **normal and expected on AM5** — AMD removed
  legacy Option ROM support at the silicon level in Ryzen 7000, so CSM is a
  vestigial menu item only. The platform is UEFI-only by design.
- This is the correct state for UEFI HTTP Boot; no action required.

### 4.4 BIOS Menu Layout Discovered
The Network Stack menu layout on this specific BIOS revision is **partial**:
- ✅ `Advanced → IPv4 Network Configuration` (exposed)
- ✅ `Advanced → IPv6 Network Configuration` (exposed)
- ❌ Parent "Network Stack" toggle with `Ipv4 PXE Support` / `Ipv4 HTTP Support`
  sub-options — **not visible in the UI on BIOS 3.01**.
- ✅ However, the `Advanced → Onboard Devices Configuration` submenu does exist
  on this board (confirmed by the warning text on ASRock's BIOS download page
  referencing `BIOS\Advanced\Onboard Devices Configuration\Display Priority`).
  Typical options there: Change LEDs, Display Priority, HD Audio, Onboard LAN,
  WAN, Bluetooth toggles — but **no Network Stack option inside** on 3.01.

### 4.5 HTTP Boot Status: **ENABLED AND ACTIVE**
Empirical probe via the F11 one-shot boot menu revealed two UEFI network
boot entries already present:
```
UEFI: PXE IPv4 Realtek PCIe GbE Family Controller
UEFI: HTTP IPv4 Realtek PCIe GbE Family Controller   ← this one, confirmed present
```
On this BIOS revision ASRock ships Network Stack **auto-enabled**
with both PXE and HTTP IPv4 supported, even though the granular toggle for
HTTP Support is not surfaced in the Setup UI. No BIOS configuration change
is required to use HTTP Boot on this machine.

### 4.6 Wi-Fi Boot
- **Not supported.** The Wi-Fi 6E module is not exposed to the UEFI network
  stack. Network boot requires wired Ethernet plugged in at POST time.
  Once the live system is running, Wi-Fi works normally (via Linux drivers,
  not firmware).

### 4.7 Summary Table

| Capability | Status on this board with BIOS 3.01 |
|---|---|
| UEFI HTTP Boot (IPv4) | ✅ Active and ready |
| UEFI HTTPS Boot | ⚠️ Likely requires certificate enrollment; not investigated |
| UEFI PXE (IPv4) | ✅ Active |
| Legacy CSM/PXE | ❌ Not possible on AM5 platform |
| Wi-Fi boot | ❌ Not supported by firmware |
| BIOS Flashback for recovery/upgrade | ✅ Available (no CPU/RAM/GPU required) |

**Bottom line:** the hardware is ideal for this use case. Zero firmware work
is needed; the only remaining task is building the server-side delivery chain.

---

## 5. Target Architecture

```mermaid
flowchart TD
    subgraph Client [Client machine B650I or compatible]
        A[Power on → F11 boot menu]
        A2[Select UEFI HTTP IPv4]
    end
    subgraph Server [Public HTTPS server host TBD]
        B[bootx64.efi<br/>~1MB iPXE UEFI binary<br/>with embedded script]
        C[boot.ipxe<br/>boot script]
        D[vmlinuz<br/>Linux kernel]
        E[initrd.img<br/>Debian live initramfs]
        F[filesystem.squashfs<br/>compressed root FS]
    end
    A --> A2
    A2 -->|1. HTTP GET bootx64.efi| B
    B -->|2. firmware launches iPXE| IPXE[iPXE running]
    IPXE -->|3. HTTPS GET boot.ipxe| C
    C -->|4. HTTPS GET kernel and initrd| D
    C --> E
    E -->|5. initramfs HTTPS GET fetch=squashfs| F
    F --> Live[n-os-tr live system running]
```

### Protocol Notes
- **Step 1 (firmware → bootx64.efi): plain HTTP.** UEFI 2.5+ firmware generally
  supports HTTPS boot only with CA certificates enrolled into the firmware
  trust store — extra complexity, and on ASRock consumer boards this path is
  not well-documented. Plain HTTP is acceptable for this one hop because:
  1. The binary is ≤ 1 MB and trivial to re-serve.
  2. iPXE binaries can be code-signed separately and/or hash-verified.
  3. All subsequent traffic is HTTPS.
- **Steps 3–5 (iPXE and live-boot): HTTPS.** iPXE has modern TLS support and
  `live-boot` uses standard libcurl/wget semantics via the `fetch=URL` kernel
  parameter. No special configuration required to use HTTPS throughout.

### Artifact Inventory

| File | Size | Source | Hosted at (example) |
|---|---|---|---|
| `bootx64.efi` | ~1 MB | Built from [`iPXE`](https://github.com/ipxe/ipxe) with embedded script | `http://boot.example/bootx64.efi` |
| `boot.ipxe` | ~1 KB | Hand-written | `https://boot.example/n-os-tr/boot.ipxe` |
| `vmlinuz` | ~8–15 MB | `live-build` output at `binary/live/vmlinuz` | `https://boot.example/n-os-tr/vmlinuz` |
| `initrd.img` | ~30–50 MB | `live-build` output at `binary/live/initrd.img` | `https://boot.example/n-os-tr/initrd.img` |
| `filesystem.squashfs` | ~1–2 GB | `live-build` output at `binary/live/filesystem.squashfs` | `https://boot.example/n-os-tr/filesystem.squashfs` |

---

## 6. Implementation Plan (When Resumed)

### Phase 1: Proof-of-Concept — Build iPXE
- [ ] Clone [`github.com/ipxe/ipxe`](https://github.com/ipxe/ipxe).
- [ ] Create an embedded script `myscript.ipxe` that DHCPs and chainloads
      `https://boot.example/n-os-tr/boot.ipxe`.
- [ ] Enable in `src/config/general.h`:
  - `DOWNLOAD_PROTO_HTTPS`
  - `NET_PROTO_IPV6` (optional but recommended)
- [ ] Build: `make bin-x86_64-efi/ipxe.efi EMBED=myscript.ipxe`.
- [ ] Upload resulting `.efi` to the webserver as `bootx64.efi`.

### Phase 2: Choose and Configure the Hosting
- [ ] Decide where to host:
  - Plain nginx/Apache on a VPS.
  - The project's own [`includes/ginxsom/`](../includes/ginxsom/) Blossom
    server — natural fit for the static squashfs given content-addressing.
  - An object store (S3 / R2 / Backblaze) fronted by a CDN.
- [ ] Ensure the host serves `.efi` with an appropriate MIME type
      (`application/octet-stream` or `application/efi`).
- [ ] Verify HTTP (not HTTPS) works for the `bootx64.efi` endpoint — some
      hosts redirect HTTP→HTTPS by default and the UEFI firmware may not
      follow redirects.

### Phase 3: Extend `build.sh` to Publish Artifacts
- [ ] After `lb build` completes, copy `binary/live/vmlinuz`, `initrd.img`,
      and `filesystem.squashfs` out of the build tree.
- [ ] Push them to a versioned path on the webserver
      (e.g. `/n-os-tr/v${VERSION}/...`).
- [ ] Update a `/n-os-tr/latest/` symlink or alias.
- [ ] Regenerate `boot.ipxe` to reference the correct versioned paths.
- [ ] Consider integrity: publish a SHA-256 manifest alongside the artifacts
      so iPXE's `imgverify` / manual verification can catch tampering even
      over plain HTTP.

### Phase 4: Write `boot.ipxe`
```ipxe
#!ipxe
set base-url https://boot.example/n-os-tr/latest

echo Loading n-os-tr from ${base-url}
kernel ${base-url}/vmlinuz boot=live components quiet splash \
       fetch=${base-url}/filesystem.squashfs
initrd ${base-url}/initrd.img
boot
```
- [ ] The `fetch=URL` parameter is handled by Debian's
      [`live-boot`](https://manpages.debian.org/testing/live-boot-doc/live-boot.7.en.html)
      initramfs; it downloads the squashfs into RAM and pivots root to it.
- [ ] The `iso/` build already includes `live-boot` via
      [`iso/config/package-lists/base.list.chroot`](../iso/config/package-lists/base.list.chroot) —
      confirm at resume time.

### Phase 5: Optional — DHCP Option 67 for Hands-Free Boot
If the LAN's DHCP server is controllable, set DHCP option 67
(Boot-File-Name) so the client firmware auto-receives the URL instead of
prompting at boot.

- **ISC dhcpd:**
  ```conf
  option arch code 93 = unsigned integer 16;
  class "httpclients" {
      match if substring (option vendor-class-identifier, 0, 10) = "HTTPClient";
      option vendor-class-identifier "HTTPClient";
      if option arch = 00:10 {
          filename "http://boot.example/bootx64.efi";
      }
  }
  ```
- **dnsmasq:**
  ```conf
  dhcp-vendorclass=set:httpboot,HTTPClient
  dhcp-boot=tag:httpboot,http://boot.example/bootx64.efi
  ```
- **Result:** F11 → HTTP IPv4 → boots with zero user input.

### Phase 6: End-to-End Test
- [ ] Fresh boot of the B650I target with wired Ethernet connected.
- [ ] F11 → `UEFI: HTTP IPv4 Realtek …` → enter (or auto-receive) URL.
- [ ] Confirm iPXE banner appears.
- [ ] Confirm `boot.ipxe` is fetched and executed.
- [ ] Confirm kernel + initrd load.
- [ ] Confirm squashfs streams in and live system boots to login prompt.
- [ ] Confirm [`n-os-tr-firstboot`](../iso/config/includes.chroot/usr/local/sbin/n-os-tr-firstboot)
      and [`n-os-tr-smoketest`](../iso/config/includes.chroot/usr/local/bin/n-os-tr-smoketest)
      behave identically to the USB-boot case.

---

## 7. Open Questions for When We Resume

1. **Where are we hosting the artifacts?** Public VPS with nginx, project-owned
   ginxsom/Blossom, object store + CDN, or something else?
2. **Versioning strategy:** `/latest/` symlink, or require client to supply a
   version in the URL? Rollback semantics?
3. **HTTPS Boot (instead of plain HTTP) for the first hop:** worth the
   certificate-enrollment effort, or is integrity via out-of-band hash
   pinning enough?
4. **Signed iPXE:** do we want to build a Secure Boot-signed iPXE so that
   Secure Boot can remain enabled on clients? Shim + MOK, or use an existing
   signed build?
5. **Multi-arch:** is arm64 (aarch64) netboot ever in scope, or x86_64 only?
   (If yes, second iPXE build for `bin-arm64-efi/ipxe.efi`.)
6. **Observability:** do we want a log/telemetry endpoint so that network-
   booted clients phone home on successful boot?
7. **Fallback distribution:** still ship the full `.iso` for USB installs?
   (Answer assumed "yes" — network boot is additive, not a replacement.)

---

## 8. Known Limitations

- **Wired Ethernet required at boot time.** No Wi-Fi netboot on consumer UEFI.
- **Plain HTTP for the bootloader hop** unless certificate enrollment is done;
  mitigate with hash verification.
- **Boot speed bounded by internet throughput** for the ~1–2 GB squashfs. A
  cached/CDN-fronted origin is strongly recommended for realistic fleet use.
- **No offline fallback** by design — this is complementary to the regular USB
  ISO, not a replacement.
- **BIOS 3.01 on the target doesn't expose a UI toggle** for `Ipv4 HTTP
  Support` but the feature is active by default. If a future BIOS revision
  changes this, revisit via F11 inspection as in §4.5.

---

## 9. References

- iPXE project: <https://ipxe.org>
- iPXE build targets: <https://ipxe.org/appnote/buildtargets>
- iPXE scripting reference: <https://ipxe.org/scripting>
- Debian `live-boot(7)`:
  <https://manpages.debian.org/testing/live-boot-doc/live-boot.7.en.html>
- Debian Live Manual — runtime behaviours:
  <https://live-team.pages.debian.net/live-manual/html/live-manual/customizing-run-time-behaviours.en.html>
- UEFI HTTP Boot overview (UEFI spec §24): <https://uefi.org/specifications>
- ASRock B650I Lightning WiFi BIOS downloads:
  <https://www.asrock.com/mb/AMD/B650I%20Lightning%20WiFi/index.asp#BIOS>
- Project ISO architecture sibling plan: [`iso_architecture.md`](./iso_architecture.md)
- Project build entry point: [`build.sh`](../build.sh)
- Project live-build wrapper: [`lb-wrapper.sh`](../lb-wrapper.sh)
- Running / usage docs: [`docs/RUNNING.md`](../docs/RUNNING.md)
