Network-boot Raspberry Pi 3, 4, or 5 over Ethernet or WiFi — iSCSI root, kexec, or USB disk mode
Part of scsipub — block devices over the internet, one click, no account
A minimal Linux distribution for Raspberry Pi 3B/3B+, 4, and 5 that boots over the network, connects to an iSCSI target, and hands off to the operating system stored there. The Pi needs no local OS — the shim is a single kernel file served via TFTP with everything baked in.
The shim pairs directly with scsipub.com, which streams disk images (Alpine, memtest86+, blank scratch volumes) over iSCSI on demand. Point the shim at a scsipub target and the Pi boots that image with no local storage.
Mount the iSCSI root partition and switch_root into it. Works with any target OS — no iSCSI support required in the target.
Load a kernel from the iSCSI boot partition and kexec into it. Deploy new kernels without updating TFTP — just write to the iSCSI disk.
Expose the entire iSCSI LUN as a USB mass storage device over the Pi's USB-C port. Connect a laptop to browse or image the disk.
Two image variants are built by CI. Both produce the same bootstrap SD card; the difference is the TFTP kernel served to the Pi after netboot is configured.
| Variant | Image.gz | Includes |
|---|---|---|
| WiFi + Ethernet (recommended) | ~19 MB | BCM43455 WiFi driver, firmware, wpa_supplicant, Ethernet |
| Ethernet-only | ~13 MB | Wired Ethernet only — smaller TFTP footprint |
| File | Purpose |
|---|---|
Image.gz |
TFTP kernel with embedded initramfs — the only file your TFTP server needs |
sdcard.img |
Bootstrap SD card — flash once to configure EEPROM for netboot |
The SD card image contains the same kernel as Image.gz (with the initramfs embedded), so each variant has its own SD card image. Use the WiFi SD card if you need WiFi during bootstrap or plan to serve the WiFi kernel via TFTP.
Write sdcard.img to a micro SD card. The Pi can boot from this
SD card permanently — or you can remove it later and the Pi will fall
through to TFTP netboot automatically.
On first boot from SD:
BOOT_ORDER=0xf21 (SD → Network → USB). Reboots only
when firmware changes.program_usb_boot_mode=1)
to enable network boot. This is permanent and irreversible
but harmless — SD boot continues to work. Pi3B+ has this enabled
from the factory.sdcard.img.Download balenaEtcher, open sdcard.img, select drive, flash.
sudo dd if=sdcard.img of=/dev/sdX bs=4M status=progress sync
Replace /dev/sdX with your SD card device. Use lsblk to identify it.
wpa_supplicant.conf file on the boot partition with your WiFi
credentials. The shim will copy it at boot and use WiFi for iSCSI.
Insert the SD card into the Pi and power on. The shim boots, updates the EEPROM if needed (one-time reboot), then proceeds to bring up the network and connect to iSCSI. The SD card can stay in permanently or be removed — without it, the Pi falls through to TFTP netboot on next power cycle.
If you leave the SD card in the Pi, TFTP is not needed — the Pi boots the shim directly from the card. TFTP is for SD-less operation: remove the SD card and the Pi fetches boot files over the network instead.
The Pi firmware fetches multiple files over TFTP — not just
the kernel. All boards need config.txt, the matching device tree
blob, overlays, cmdline.txt, and the kernel. GPU firmware
requirements differ: Pi3 fetches bootcode.bin,
start.elf, and fixup.dat; Pi4 fetches
start4.elf + fixup4.dat (bootcode is in the EEPROM);
Pi5 has everything in its EEPROM and fetches only the kernel
and DTB.
/srv/tftp/
config.txt # Pi firmware config
cmdline.txt # Kernel command line
Image.gz # Kernel with embedded initramfs
bootcode.bin # Pi3 second-stage bootloader (Pi4/5 ignore)
start.elf # Pi3 GPU firmware (Pi4/5 ignore)
fixup.dat # Pi3 GPU memory fixup (Pi4/5 ignore)
start4.elf # Pi4 GPU firmware (Pi3/5 ignore)
fixup4.dat # Pi4 GPU memory fixup (Pi3/5 ignore)
bcm2837-rpi-3-b.dtb # Pi3 Model B device tree
bcm2837-rpi-3-b-plus.dtb # Pi3 Model B+ device tree
bcm2837-rpi-3-a-plus.dtb # Pi3 Model A+ device tree
bcm2837-rpi-zero-2-w.dtb # Pi Zero 2 W device tree
bcm2711-rpi-4-b.dtb # Pi4 Model B device tree
bcm2711-rpi-400.dtb # Pi 400 device tree
bcm2711-rpi-cm4.dtb # Pi Compute Module 4 device tree
bcm2711-rpi-cm4s.dtb # Pi CM4S device tree
bcm2712-rpi-5-b.dtb # Pi5 device tree
bcm2712d0-rpi-5-b.dtb # Pi5 D0 stepping device tree
bcm2712-rpi-500.dtb # Pi 500 device tree
overlays/ # DT overlays from config.txt
miniuart-bt.dtbo
dwc2.dtbo # Pi4 USB gadget (optional)
Copy all files from the SD card's boot partition to your TFTP root — it contains everything the firmware needs.
# /etc/dnsmasq.conf enable-tftp tftp-root=/srv/tftp
# /etc/dhcp/dhcpd.conf next-server 192.168.1.1; # TFTP server IP
# Install tftpd-hpa sudo apt install tftpd-hpa # Copy the entire SD card boot partition content to TFTP root sudo cp -r /mnt/sdcard/* /srv/tftp/
/abcdef01/Image.gz). You can either create per-Pi directories or configure the
EEPROM to request a flat path. See the
RPi network boot docs.
The iSCSI target presents a disk image to the Pi. This disk image has the same partition layout as a real SD card — a FAT boot partition and an ext4 root partition.
Use any Raspberry Pi OS image (or your own). The image must have at least two partitions: p1 (FAT, boot) and p2 (ext4, root).
# Example: create a 16 GB sparse image and write a Pi OS image to it truncate -s 16G /srv/iscsi/pi4-root.img sudo dd if=raspios.img of=/srv/iscsi/pi4-root.img bs=4M conv=notrunc
sudo targetcli /> backstores/fileio create pi4-root /srv/iscsi/pi4-root.img /> iscsi/ create iqn.2024-01.local:pi4-root /> iscsi/iqn.2024-01.local:pi4-root/tpg1/luns/ create /backstores/fileio/pi4-root /> iscsi/iqn.2024-01.local:pi4-root/tpg1/ set attribute authentication=0 demo_mode_write_protect=0 generate_node_acls=1 /> saveconfig /> exit
Create a new iSCSI target and LUN through the web UI. Use the disk image as the backing store. The IQN and portal IP are needed for the DHCP configuration.
The shim reads iSCSI parameters from standard DHCP options. Configure your DHCP server to provide option 17 (root-path) with the iSCSI URI.
# iSCSI target URI (option 17) dhcp-option=17,iscsi:192.168.1.10:::1:iqn.2024-01.local:pi4-root # Boot mode (option 224, optional — defaults to pivot) # pivot — switch_root into iSCSI root # kexec — kexec kernel from iSCSI boot partition # usb — expose iSCSI disk over USB-C dhcp-option=224,pivot
option root-path "iscsi:192.168.1.10:::1:iqn.2024-01.local:pi4-root"; # Optional: boot mode option local-proxy-config "pivot";
192.168.1.10 with your iSCSI server IP
and iqn.2024-01.local:pi4-root with your actual target IQN.
You can pass iSCSI parameters directly on the kernel cmdline instead of
(or in addition to) DHCP. Edit cmdline.txt on the SD card or
the TFTP server's boot config:
console=ttyAMA0 earlycon iscsi.ip=192.168.1.10 iscsi.target=iqn.2024-01.local:pi4-root iscsi.port=3260 iscsi.mode=pivot
Cmdline values take precedence over DHCP-supplied options.
The WiFi variant (~19 MB Image.gz vs ~13 MB without) includes the BCM43455
driver, firmware, and wpa_supplicant. The shim prefers Ethernet
if available and falls back to WiFi when no wired interface is found.
WiFi credentials can come from three sources (in priority order):
| Source | How |
|---|---|
| SD card | Place wpa_supplicant.conf on the FAT boot partition before first boot |
| Kernel cmdline | Add wifi.ssid=MyNetwork wifi.psk=MyPassword to the TFTP cmdline |
| Build-time | Bake /etc/wpa_supplicant.conf into the rootfs for site-specific images |
network={
ssid="MyNetwork"
psk="MyPassword"
}
Pi3/4/5 boot ROM TFTP Server iSCSI Target
| | |
|--- DHCP discover ---->| |
|<-- IP + next-server --| |
| | |
|--- TFTP config.txt -->| |
|--- TFTP *.dtb ------->| (firmware patches |
|--- TFTP overlays/ --->| MAC, serial, memory) |
|--- TFTP Image.gz ---->| |
|<-- boot files --------| |
| | |
[kernel boots, shim init starts] |
| |
|--- DHCP (option 17 = iSCSI URI) ------------->|
| |
|--- iSCSI login ------>|----------------------->|
|<-- block device ------|<-----------------------|
| |
[pivot_root / kexec / USB mode] |
The kernel (Image.gz) has the entire root filesystem embedded as
an initramfs — no separate initrd file. The TFTP server also serves
config.txt, device tree blobs, and overlays that the Pi firmware
needs before it can start the kernel. The simplest setup: copy the contents
of the SD card boot partition to the TFTP root.
Check that the EEPROM was flashed successfully (serial console shows
[init] EEPROM flashed). Verify the TFTP server is running and
reachable. The Pi requests Image.gz (or the filename set in
DHCP filename option) from the next-server IP.
The serial console (or HDMI splash screen) shows progress. Common issues:
root-path in iSCSI URI formatIf the Pi has a USB-C connection to a computer, it will present a help disk with setup instructions when boot fails.
Verify wpa_supplicant.conf is on the SD card boot partition (FAT)
or that wifi.ssid= and wifi.psk= are on the kernel cmdline.
The shim waits 30 seconds for WiFi association before giving up.
The WiFi stack adds ~6 MB to Image.gz (13 MB → 19 MB). If all your Pis are
wired, use the Ethernet-only download from the eth-only branch
for a smaller TFTP image. Both variants produce the same SD card bootstrap image.
scsipub (parent project) — streams disk images over iSCSI on demand. One click, no account, no VPN, no VM. Pick an image (Alpine, memtest86+, blank scratch volume), get session credentials with a unique IQN and CHAP login, and mount it as a local block device on Linux, Windows, or macOS. Copy-on-write layering gives each session its own isolated volume.
This shim is the "Pi-side" client for scsipub: combine it with a scsipub target and a Raspberry Pi becomes a diskless machine that boots whatever image you picked on the web.
ESP32 iSCSI USB Bridge — turns an ESP32-S3 into a wireless-to-USB storage bridge. The device connects to WiFi, logs into an iSCSI target, and presents it to any USB host as an ordinary flash drive. No drivers or software needed on the host side.
Use it to give legacy devices (smart TVs, car stereos, thin clients) transparent access to network storage, or as a standalone iSCSI-to-USB adapter alongside the Pi3/4/5 shim in a diskless deployment.
© Defensible Logic · Source · Built with Buildroot + RPi kernel 6.19