Skip to content

netboot: enable netboot image workflow and automate target configuration - #10195

Open
deece wants to merge 3 commits into
armbian:mainfrom
deece:nfs-root
Open

netboot: enable netboot image workflow and automate target configuration#10195
deece wants to merge 3 commits into
armbian:mainfrom
deece:nfs-root

Conversation

@deece

@deece deece commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

This PR enables support for building netboot (network boot) targets directly from the Armbian Build Framework when NETBOOT=yes is passed.

The main intent is to facilitate developing new platforms, and testing in a lab environment.

Net booting will need to be enabled in u-boot on a per-platform basis.

For platforms without native network/PXE in firmware, we build a minimal stub image that can be flashed to SD/emmc, only containing U-boot, which then chains on to fetch and execute the kernel from the network, and mounts root via NFS.

Description of Changes

  1. sunxi64 Config Update: Enables built-in (=y) kernel support for CONFIG_NFS_FS, CONFIG_NFS_V2/V3/V4, and CONFIG_ROOT_NFS in current sunxi64 kernel configs, allowing the kernel to boot and mount NFS shares out-of-the-box.
  2. Netboot Image Workflow: Intercepts the build flow to run a dedicated create_netboot_tarballs_and_images stage when NETBOOT=yes.
  3. Automatic Script & Bootloader Generation:
    • Prompts for (or parses from env) the TFTP server, NFS server, subnet, router IP, and netmask settings.
    • Packages staging rootfs and boot directories into compressed tarballs.
    • Compiles a dynamic boot.scr from a boot.cmd template, using template placeholders (@BOARD@, @NETBOOT_NFS_SERVER@, and @NETBOOT_NFS_PATH@) that are substituted at build-time. This keeps personal hostnames, local IPs, and specific board names completely out of the git repository.
    • Creates a minimal 32MB bootloader loop image containing U-Boot and boot.scr to flash onto target SD cards.
  4. Target fstab Automation: Comments out block device mounts (such as /dev/mmcblk* mounts) in target /etc/fstab to prevent systemd from hanging during netboot.
  5. Deployment Documentation: Generates a custom netboot.md deployment guide tailored to the user's configured settings, detailing NFS exports, TFTP copy steps, OpenWrt/Dnsmasq DHCP setups, and ISC DHCP setups.

Tested Setup

This configuration has been successfully tested on:

  • Platforms:
    • Mellow Fly C5 (Allwinner H618, sunxi64)
  • DHCP Server: dnsmasq (v2.92)
  • TFTP Server: dnsmasq (v2.92)
  • NFS Server: nfs-kernel-server (NFSv3/v4)

Example Build Command

./compile.sh BOARD=mellowflyc5 BRANCH=current RELEASE=bookworm BUILD_MINIMAL=yes NETBOOT=yes

Output Artifacts (in output/images/):

  • Armbian_24.8.0-trunk_Mellowflyc5_bookworm_current_6.18.38-rootfs.tar.zst (NFS RootFS)
  • Armbian_24.8.0-trunk_Mellowflyc5_bookworm_current_6.18.38-boot.tar.zst (Kernel/Boot Archive)
  • Armbian_24.8.0-trunk_Mellowflyc5_bookworm_current_6.18.38-netboot/ (Directory with Raw Boot files, boot.scr, and netboot.md)
  • Armbian_24.8.0-trunk_Mellowflyc5_bootloader.img (Minimal 32MB bootloader image)

Summary by CodeRabbit

  • New Features
    • Added network boot artifact generation with bootloader images, rootfs/boot archives, TFTP-ready files, and PXE configuration.
    • Added diskless PXE booting with NFS, including optional tmpfs-backed OverlayFS for overlayroot=tmpfs.
    • Added generated deployment documentation with step-by-step NFS, TFTP, DHCP, and board boot instructions.
  • Bug Fixes
    • Improved non-interactive progress handling to prevent terminal hangs when running background progress output.
  • Deprecations
    • Deprecated ROOTFS_TYPE values nfs/nfs-root in favor of using NETBOOT=yes for PXE network booting.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a NETBOOT build path that prepares NFS-root filesystems, creates compressed and TFTP artifacts, generates deployment documentation and a bootloader image, sources the new helpers, warns about deprecated NFS rootfs types, and provides a TTY-safe pv wrapper.

Changes

Netboot generation

Layer / File(s) Summary
Netboot dispatch and module loading
lib/functions/main/rootfs-image.sh, lib/functions/image/rootfs-to-image.sh, lib/functions/image/rootfs-to-netboot.sh, lib/library-functions.sh, lib/functions/configuration/main-config.sh
NETBOOT builds invoke the netboot pipeline, required helpers are sourced in order, and legacy NFS rootfs types emit a deprecation warning.
Netboot rootfs preparation
lib/functions/image/rootfs-to-netboot.sh
Network settings and image version are collected, NFS-root filesystem behavior is provisioned, and OverlayFS initramfs support is configured.
Rootfs and TFTP artifacts
lib/functions/image/rootfs-to-netboot.sh, config/templates/netboot.md.template
Compressed archives, kernel and PXE files, and a templated deployment guide are generated.
Netboot bootloader image
lib/functions/image/rootfs-to-netboot.sh
A 32MB FAT32 image is partitioned, populated with boot files and environment data, and written with U-Boot.

Non-interactive progress handling

Layer / File(s) Summary
TTY-safe pv wrapper
lib/functions/logging/runners.sh
The exported wrapper delegates to pv on TTYs and uses cat for non-interactive execution.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested labels: Documentation

Suggested reviewers: igorpecovnik, juanesf, johnthecoolingfan, pyavitz, schwar3kat

Sequence Diagram(s)

sequenceDiagram
  participant build_rootfs_and_image
  participant create_netboot_tarballs_and_images
  participant target_rootfs
  participant FINALDEST
  build_rootfs_and_image->>create_netboot_tarballs_and_images: select netboot generation
  create_netboot_tarballs_and_images->>target_rootfs: provision rootfs and configure overlayroot
  create_netboot_tarballs_and_images->>FINALDEST: create archives and stage TFTP files
  create_netboot_tarballs_and_images->>FINALDEST: write deployment guide and bootloader image
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a netboot image workflow with automated target configuration.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added 08 Milestone: Third quarter release size/large PR with 250 lines or more Needs review Seeking for review Hardware Hardware related like kernel, U-Boot, ... Framework Framework components labels Jul 16, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/functions/image/rootfs-to-image.sh`:
- Around line 235-245: Propagate the resolved NETBOOT_TFTP_SERVER value into
tftp_server_ip after the TFTP server prompt/defaulting logic, and ensure the
same assignment is applied in the corresponding boot.scr generation paths
referenced by the comment. Preserve the existing NFS fallback behavior only when
no TFTP server is configured.
- Around line 492-505: Register a cleanup handler immediately after `loop_dev`
is assigned in the loop-device setup flow, before formatting or mounting. Have
it conditionally unmount and remove `temp_mount` and detach `loop_dev`,
explicitly tolerating cleanup-command failures under `set -e`; disarm the
handler after successful cleanup so later execution does not trigger it again.
- Around line 318-322: Update the fstab adjustment block in rootfs-to-image.sh
to comment every block-backed mount entry, including UUID/PARTUUID/LABEL
sources, all /dev/* sources, and indented entries. Preserve network and
pseudo-filesystem entries by limiting the match to block-device source forms.
- Around line 328-334: Update the deployment-guide generation associated with
the rootfs/boot archive instructions to install both `${version}-rootfs.${ext}`
and `${version}-boot.${ext}` before bind-mounting `${NETBOOT_NFS_PATH}/boot`
over TFTP. Generate extraction commands using the appropriate gzip or zstd
decompressor, and apply the same change to all corresponding guide sections.
- Around line 401-405: Update the `/etc/exports` entry in the rootfs-to-image
export setup to replace the unrestricted `*` client with the configured network,
or preferably the specific target address, while preserving the existing NFS
options and `no_root_squash` behavior.
- Around line 586-599: Update the U-Boot handling around
image_artifacts_debs_reversioned and write_uboot_to_loop_image so the upstream
artifact map is authoritative: remove the broad DEB_STORAGE fallback search, and
when the "uboot" entry is missing or unusable, emit an error and terminate with
failure instead of publishing the image. Preserve writing the mapped U-Boot
package when the entry is present.
- Around line 291-294: Update the sed expression assigning latest_installed_ver
in the latest_file block to use proper extended-regex alternation for the
vmlinuz and Image prefixes, removing either prefix from the extracted kernel
version instead of retaining it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1609498c-6cca-48cf-9180-4cbbb4534002

📥 Commits

Reviewing files that changed from the base of the PR and between 5cbc1c5 and cf4f357.

📒 Files selected for processing (3)
  • config/kernel/linux-sunxi64-current.config
  • lib/functions/image/rootfs-to-image.sh
  • lib/functions/main/rootfs-image.sh

Comment thread lib/functions/image/rootfs-to-image.sh Outdated
Comment thread lib/functions/image/rootfs-to-image.sh Outdated
Comment thread lib/functions/image/rootfs-to-image.sh Outdated
Comment thread lib/functions/image/rootfs-to-image.sh Outdated
Comment thread lib/functions/image/rootfs-to-image.sh Outdated
Comment thread lib/functions/image/rootfs-to-image.sh Outdated
Comment thread lib/functions/image/rootfs-to-image.sh Outdated
@igorpecovnik

igorpecovnik commented Jul 16, 2026

Copy link
Copy Markdown
Member

Good one. I was thinking on this too ... currently we use full images for initial deployment. A bit of a waste. https://github.com/armbian/infra/tree/main/nfs-image-prep (WIP, not in production as there is some problem with using overlaysfs - rootfs images are shared by more then one device)

@rpardini rpardini left a comment

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.

Interesting effort, but again, seems to me u-boot already provides much of this. Ref exporting, I thought that the nfs root stuff did that already?

Also create_netboot_tarballs_and_images is way too long for rootfs-to-image.sh, refactor it a bit, and use a separate rootfs-to-netboot.sh or such (and tools...gen-library.sh; or, better yet, make core extensible)

Comment thread lib/functions/image/rootfs-to-image.sh Outdated
@deece

deece commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Good one. I was thinking on this too ... currently we use full images for initial deployment. A bit of a waste. https://github.com/armbian/infra/tree/main/nfs-image-prep (WIP, not in production as there is some problem with using overlaysfs - rootfs images are shared by more then one device)

Interesting, I was thinking of how a production OverlayFS would work to allow a shared readonly root - similar to OpenWRT, stock image is RO, config, home, etc goes onto a writable mount.

The RO fs itself could be layered, a generic layer for nooarch packages, an arch layer that contains shared architecture files (most packages), and a board layer for the board specific things (like kernel packages). That would cut down storage requirements a bit, but does add complexity.

The benefits are that it would enable further work to create a more secure Armbian where most things are readonly.

The alternative would be to throw it all on a deduping filesystem on the server like ZFS (which is where I serve my test from), which removes the storage costs, but still incurs the packaging & extraction overheads.

@deece

deece commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Interesting effort, but again, seems to me u-boot already provides much of this. Ref exporting, I thought that the nfs root stuff did that already?

Also create_netboot_tarballs_and_images is way too long for rootfs-to-image.sh, refactor it a bit, and use a separate rootfs-to-netboot.sh or such (and tools...gen-library.sh; or, better yet, make core extensible)

Hmm, you're right, I didn't think to check for PXE - it looks like u-boot implements enough of PXE to get going, so I'll look into reworking this so that the local u-boot uses PXE, then drop any unnecessary infrastructure.

@deece
deece force-pushed the nfs-root branch 3 times, most recently from 16c6641 to 3bf5b40 Compare July 17, 2026 05:59

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@config/templates/netboot.md.template`:
- Around line 60-72: Update the netboot deployment instructions around the TFTP
copy and bind-mount example so generated pxelinux.cfg/default remains accessible
after mounting ${NETBOOT_NFS_PATH}/boot. Place the PXE configuration within the
bound boot tree or mount that tree beneath a separate TFTP subdirectory, and
ensure the documented copy path and fstab entry are consistent.

In `@lib/functions/image/rootfs-to-netboot.sh`:
- Around line 185-192: The kernel-copy fallback must require exactly one
matching kernel image before publishing it. Update the fallback in the “Copy
kernel image” block to collect candidates matching vmlinuz* or Image, fail the
build when none or multiple candidates are found, and copy the sole candidate to
netboot_dir/Image.
- Around line 224-232: Update the PXE entry generated in the rootfs-to-netboot
flow to use the board’s established console configuration instead of hardcoded
console=ttyS0,115200 and earlycon=uart,mmio32,0x05000000 arguments. Reuse the
existing board-configured console argument symbol or generation mechanism, while
preserving the remaining kernel, initrd, FDT, and NFS options.
- Around line 201-203: The netboot-specific boot script is not staged for
pure-PXE clients. In lib/functions/image/rootfs-to-netboot.sh lines 201-203,
generate or copy the netboot-specific boot.scr into ${netboot_dir}; in
config/templates/netboot.md.template lines 15-18, update the pure-PXE deployment
instructions to install that script, or switch them to native U-Boot PXE
loading.
- Around line 170-176: Update both archive pipelines in the rootfs packaging
flow to explicitly propagate tar failures when pipefail is disabled, covering
the root filesystem archive and the boot/kernel archive. Ensure a failed tar
causes the script to stop or return failure rather than allowing the
compressor’s successful exit status to publish an incomplete archive.
- Around line 133-150: Update the initramfs rebuild and uInitrd generation flow
around update-initramfs and mkimage so failures that prevent producing the
required uInitrd are propagated instead of ignored. Ensure the PXE-referenced
${SDCARD}/boot/uInitrd is successfully regenerated from the newest initrd.img,
and fail the function or script when either required generation step fails.

In `@lib/functions/logging/runners.sh`:
- Around line 14-44: Update the pv wrapper to use command pv whenever stderr is
a TTY, regardless of stdin or stdout. Replace regex-based option parsing with
explicit case handling for supported value-taking flags, treat -C/--no-control
as argument-free, safely handle missing option values without failing under set
-e, and stop parsing options after -- while preserving remaining operands as
files.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8105c867-58f1-4be9-9405-fc8e688e74e2

📥 Commits

Reviewing files that changed from the base of the PR and between 878a70c and 16c6641.

📒 Files selected for processing (6)
  • config/templates/netboot.md.template
  • lib/functions/image/rootfs-to-image.sh
  • lib/functions/image/rootfs-to-netboot.sh
  • lib/functions/logging/runners.sh
  • lib/functions/main/rootfs-image.sh
  • lib/library-functions.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/functions/main/rootfs-image.sh

Comment thread config/templates/netboot.md.template
Comment thread lib/functions/image/rootfs-to-netboot.sh Outdated
Comment thread lib/functions/image/rootfs-to-netboot.sh Outdated
Comment thread lib/functions/image/rootfs-to-netboot.sh
Comment thread lib/functions/image/rootfs-to-netboot.sh Outdated
Comment thread lib/functions/image/rootfs-to-netboot.sh Outdated
Comment thread lib/functions/logging/runners.sh
@deece
deece force-pushed the nfs-root branch 2 times, most recently from c354b0c to 7c94564 Compare July 17, 2026 12:25

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/functions/image/rootfs-to-netboot.sh`:
- Around line 291-310: The PXE configuration generation must not select an
arbitrary or empty DTB. Update the DTB resolution and `fdt` emission around
`dtb_rel_path` and the `Generating PXE configuration` heredoc to require the
board-configured `BOOT_FDT_FILE` for FDT-based targets, failing or handling the
missing file explicitly, while omitting the `fdt` directive only for
architectures that do not require one; remove the `find | head` fallback.
- Around line 12-24: Update the NETBOOT_TFTP_SERVER and NETBOOT_NFS_SERVER
handling in rootfs-to-netboot.sh to require valid numeric IPv4 addresses,
including when values are supplied non-interactively or NFS defaults from TFTP.
Revise the TFTP prompt to request an IP address and validate each server value
before generating U-Boot serverip and nfsroot settings, rejecting invalid or
hostname values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b77b8dd7-cdb0-417e-8048-6272fb176b09

📥 Commits

Reviewing files that changed from the base of the PR and between 3bf5b40 and c354b0c.

📒 Files selected for processing (7)
  • config/templates/netboot.md.template
  • lib/functions/configuration/main-config.sh
  • lib/functions/image/rootfs-to-image.sh
  • lib/functions/image/rootfs-to-netboot.sh
  • lib/functions/logging/runners.sh
  • lib/functions/main/rootfs-image.sh
  • lib/library-functions.sh
🚧 Files skipped from review as they are similar to previous changes (4)
  • lib/functions/image/rootfs-to-image.sh
  • lib/functions/main/rootfs-image.sh
  • lib/functions/logging/runners.sh
  • config/templates/netboot.md.template

Comment thread lib/functions/image/rootfs-to-netboot.sh Outdated
Comment on lines +291 to +310
local dtb_rel_path=""
if [[ -n "${BOOT_FDT_FILE}" && -f "${netboot_dir}/${BOOT_FDT_FILE}" ]]; then
dtb_rel_path="${BOOT_FDT_FILE}"
elif [[ -n "${BOOT_FDT_FILE}" && -f "${netboot_dir}/$(basename "${BOOT_FDT_FILE}")" ]]; then
dtb_rel_path="$(basename "${BOOT_FDT_FILE}")"
else
local dtb_file
dtb_file=$(find "${netboot_dir}" -name "*.dtb" -type f | head -n 1)
if [[ -n "${dtb_file}" ]]; then
dtb_rel_path=$(realpath --relative-to="${netboot_dir}" "${dtb_file}")
fi
fi

display_alert "Generating PXE configuration" "${pxe_dir}/default" "info"
cat <<EOF > "${pxe_dir}/default"
default armbian
label armbian
kernel Image
initrd uInitrd
fdt ${dtb_rel_path}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not publish an arbitrary or empty DTB path.

When the configured DTB is unavailable, find | head silently chooses an arbitrary DTB—or emits fdt when none exists. Require the board-configured DTB for FDT-based targets; only omit the directive on architectures that do not need one.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/functions/image/rootfs-to-netboot.sh` around lines 291 - 310, The PXE
configuration generation must not select an arbitrary or empty DTB. Update the
DTB resolution and `fdt` emission around `dtb_rel_path` and the `Generating PXE
configuration` heredoc to require the board-configured `BOOT_FDT_FILE` for
FDT-based targets, failing or handling the missing file explicitly, while
omitting the `fdt` directive only for architectures that do not require one;
remove the `find | head` fallback.

@deece

deece commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Latest version integrates the core ideas from @igorpecovnik's scripts - use an initrd to avoid changing kernel config, allows for readonly nfsroot with tmpfs overlay, as well as @rpardini's insight to utilise u-boot's built-in PXE functionality.

@deece
deece force-pushed the nfs-root branch 2 times, most recently from b385c03 to ff80f51 Compare July 17, 2026 12:34
deece added 3 commits July 18, 2026 15:19
- Implement a wrapper function for the `pv` (Pipe Viewer) command in lib/functions/logging/runners.sh.
- Check if stderr is connected to a TTY (`[[ -t 2 ]]`).
- If in an interactive TTY, delegate execution to the system `pv` command.
- If running in a non-interactive/redirected environment (such as Docker, background tasks, or CI pipelines), bypass the progress viewer to prevent hangs and terminal size query deadlocks by falling back to standard `cat` streaming.
- Safely parse command arguments to extract the list of target filenames using a robust case statement.

Why this is needed:
During automated builds (e.g. Docker runs, background daemon loggers, or CI runners), there is no interactive tty. The standard `pv` utility attempts to perform ioctl/tty size calls and wait on output channels. If these streams are redirected or run without an active controller terminal, `pv` can hang indefinitely or stall build execution. Wrapping it ensures the pipe continues to flow cleanly as a simple stdin-to-stdout stream.

Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
Assisted-by: Antigravity <antigravity@google.com>
… target config

- Modify lib/functions/main/rootfs-image.sh to run create_netboot_tarballs_and_images when NETBOOT=yes, bypassing the standard partition and SD image creation steps.
- Implement create_netboot_tarballs_and_images in lib/functions/image/rootfs-to-image.sh, and refactor it into smaller modular helper functions in lib/functions/image/rootfs-to-netboot.sh.
- Automatically verify and install initramfs-tools in target chroot, compile, and package the target initramfs (uInitrd) to support network boot.
- Parse or prompt for TFTP, NFS, target subnet, router/gateway IP, and netmask options, defaulting to generic fallback addresses (192.168.1.1, 192.168.1.0, 255.255.255.0).
- Package the staging rootfs and boot directories into compressed tarballs.
- Create a minimal 32MB bootloader loop image containing U-Boot and a U-Boot boot script.
- Pivot to U-Boot's native PXE network booting flow (pxe get && pxe boot) for both the SD bootloader and diskless boots.
- Generate a standard plain-text PXE configuration file (pxelinux.cfg/default) containing kernel, DTB, and command-line parameters, allowing users to modify boot arguments without recompiling boot.scr.
- Support pure diskless PXE booting (zero SD card) if U-Boot is pre-installed in SPI flash, or boot via the minimal SD card image.
- Support read-only NFS rootfs sharing using OverlayFS with `overlayroot=tmpfs` kernel parameter loaded via the custom initramfs hook.
- Add target fstab cleanup to automatically comment out block devices (like / and /usr) during image build to prevent systemd from hanging on read-only NFS mounts.
- Deprecate legacy ROOTFS_TYPE=nfs / nfs-root options. Add deprecation warnings to lib/functions/configuration/main-config.sh recommending users shift to the modern, complete NETBOOT=yes implementation.
- Update netboot.md guide explaining target deployment and config requirements, documenting standard/diskless PXE options, and detail advanced user configurations (locale, root password, timezone, SSH key injection).

Example Build Command:
  ./compile.sh BOARD=mellowflyc5 BRANCH=current RELEASE=bookworm BUILD_MINIMAL=yes NETBOOT=yes

Output Artifacts (in output/images/):
  - Armbian-unofficial_26.08.0-trunk_Mellowflyc5_bookworm_current_6.18.38_minimal-rootfs.tar.zst (compressed NFS root filesystem)
  - Armbian-unofficial_26.08.0-trunk_Mellowflyc5_bookworm_current_6.18.38_minimal-boot.tar.zst (compressed boot/kernel directory)
  - Armbian-unofficial_26.08.0-trunk_Mellowflyc5_bookworm_current_6.18.38_minimal-bootloader.img (minimal 32MB U-Boot bootloader image)
  - Armbian-unofficial_26.08.0-trunk_Mellowflyc5_bookworm_current_6.18.38_minimal-netboot/ (directory containing kernel Image, dtb/, boot.scr, uInitrd, pxelinux.cfg/default, and netboot.md)

Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
Assisted-by: Antigravity <antigravity@google.com>
- Add deprecation warnings to do_main_configuration in lib/functions/configuration/main-config.sh when ROOTFS_TYPE is set to nfs or nfs-root.
- Recommend users transition to the modern, complete NETBOOT=yes implementation instead.

Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
Assisted-by: Antigravity <antigravity@google.com>
@rpardini

Copy link
Copy Markdown
Member

Nice work. I do still think that this is waaay too big for core and would better serve us in an extension.

(I also disagree with that pv helper -- that masquerades for using it in the wrong context).

@deece

deece commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator Author

I would reframe it as a reimplementation of ROOTFS=nfs - it aims to do the same goals, but with minimal local storage (only u-boot where needed), vs the existing implementation that requires a local kernel.

This aligns it closer to how PCs network boot, and simplifies automated testing in a lab environment, as local storage only needs to be updated for u-boot changes, rather than kernel changes.

I'm sure we could probably even chain-load u-boot, so local storage won't need updating in an automated test scenario.

RE pv: this is used in a few places throughout the build, and the problem can be triggered just by trying to launch through an IDE without an associated terminal.

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

Labels

08 Milestone: Third quarter release Framework Framework components Hardware Hardware related like kernel, U-Boot, ... Needs review Seeking for review size/large PR with 250 lines or more

Development

Successfully merging this pull request may close these issues.

3 participants