A complete netboot environment and management system for Raspberry Pi 4 devices using DHCP proxy, TFTP, HTTP, iPXE, EDK2, UEFI, and Redfish.
Metal Boot provides enterprise-grade server management capabilities for Raspberry Pi 4 devices by implementing:
- Network booting through DHCP proxy and TFTP services
- UEFI firmware customization for Raspberry Pi 4
- Redfish-compatible API for hardware management
- Power management via PoE switches
- Remote console access
This project turns inexpensive Raspberry Pi 4 hardware into managed computing resources with functionality similar to enterprise-grade BMC (Baseboard Management Controller) solutions.
- Store raspberry PI firmware json exports in filesystem as backend
- Raspberry PI bootloader init -> DHCP -> Lookup and merge options with remote backend if specified
- Raspberry PI boots into netboot -> fetches firmware -> firmware manager dynamically renders firmware with UEFI vars from filesystem backend
- If boot method is PXE -> provide ironic IPA or configured ramdisk
- Ironic boots via IPA -> fetch devices via callback -> Update devices and Redfish config in backend
- Redfish API is called -> Is power option? -> true -> use remote backend to configure POE -> false -> Update firmware from translated settings
stateDiagram-v2
direction TB
[*] --> Initialized: Firmware JSON stored in filesystem
state Initialized {
[*] --> BootloaderInit
BootloaderInit --> DHCPRequest
DHCPRequest --> ConfigLookup
}
state ConfigLookup {
[*] --> CheckRemoteBackend
CheckRemoteBackend --> MergeRemoteConfig: Remote backend specified
CheckRemoteBackend --> UseLocalConfig: No remote backend
MergeRemoteConfig --> ConfigReady
UseLocalConfig --> ConfigReady
}
Initialized --> NetbootReady: Configuration complete
state NetbootReady {
[*] --> FetchFirmware
FetchFirmware --> ReadUEFIVars
ReadUEFIVars --> RenderFirmware
RenderFirmware --> CheckBootMethod
}
state CheckBootMethod {
[*] --> BootMethodDecision
BootMethodDecision --> ProvidePXE: PXE boot
BootMethodDecision --> ProvideRamdisk: Other boot method
ProvidePXE --> BootReady
ProvideRamdisk --> BootReady
}
NetbootReady --> Booting: Boot method determined
state Booting {
[*] --> IronicBoot
IronicBoot --> HardwareDiscovery
HardwareDiscovery --> DeviceCallback
DeviceCallback --> UpdateDeviceRegistry
UpdateDeviceRegistry --> UpdateRedfishConfig
}
Booting --> Operational: Device registered and configured
state col1 {
state Operational {
[*] --> Idle
Idle --> ProcessingAPI: Redfish API called
state ProcessingAPI {
[*] --> CheckOperation
CheckOperation --> PowerManagement: Power operation
CheckOperation --> FirmwareUpdate: Configuration update
state PowerManagement {
[*] --> ConfigurePOE
ConfigurePOE --> ExecutePower
ExecutePower --> PowerComplete
}
state FirmwareUpdate {
[*] --> TranslateSettings
TranslateSettings --> ApplyFirmware
ApplyFirmware --> FirmwareComplete
}
}
ProcessingAPI --> Idle: Operation complete
}
}
state col2 {
state Error {
[*] --> DiagnoseError
DiagnoseError --> RetryOperation: Recoverable error
DiagnoseError --> FailedState: Fatal error
}
}
col1 --> col2: Critical error occurred
col2 --> col1: Error resolved
col2 --> [*]: Fatal error - system halt
Operational --> Shutdown: System shutdown requested
Shutdown --> [*]: Clean shutdown complete
flowchart TD
subgraph "Metal Boot Server"
DHCP[DHCP Proxy Service]
TFTP[TFTP Service]
HTTP[HTTP Service]
Redfish[Redfish API]
DB[(Config Files)]
end
subgraph "Network Infrastructure"
PoE[PoE Switch]
Router[Network Router]
end
subgraph "Raspberry Pi Devices"
Pi1[Raspberry Pi 4]
Pi2[Raspberry Pi 4]
Pi3[Raspberry Pi 4]
end
Router -->|Network Connection| DHCP
Router -->|Network Connection| TFTP
Router -->|Network Connection| HTTP
Router -->|Network Connection| Redfish
DHCP <-->|Configuration| DB
TFTP <-->|Firmware Files| DB
HTTP <-->|iPXE Scripts| DB
Redfish <-->|Management Data| DB
DHCP -->|DHCP Responses| Pi1
DHCP -->|DHCP Responses| Pi2
DHCP -->|DHCP Responses| Pi3
TFTP -->|UEFI Firmware| Pi1
TFTP -->|UEFI Firmware| Pi2
TFTP -->|UEFI Firmware| Pi3
HTTP -->|iPXE Scripts| Pi1
HTTP -->|iPXE Scripts| Pi2
HTTP -->|iPXE Scripts| Pi3
Redfish -->|Power Control| PoE
PoE -->|Power Delivery| Pi1
PoE -->|Power Delivery| Pi2
PoE -->|Power Delivery| Pi3
Metal Boot implements a comprehensive netboot process for Raspberry Pi 4 devices:
sequenceDiagram
participant Pi as Raspberry Pi 4
participant DHCP as DHCP Proxy
participant TFTP as TFTP Server
participant HTTP as HTTP Server
Pi->>DHCP: DHCP Discovery Broadcast
Note over Pi,DHCP: Pi requests network boot
DHCP->>Pi: DHCP Offer with TFTP details
Pi->>TFTP: Request for RPI_EFI.fd
TFTP->>Pi: Deliver EDK2 UEFI firmware
Note over Pi: Boot into UEFI firmware
Pi->>DHCP: Request boot configuration
DHCP->>Pi: Provide iPXE boot file location
Pi->>TFTP: Request iPXE boot file
TFTP->>Pi: Deliver iPXE boot loader
Note over Pi: Load iPXE boot loader
Pi->>HTTP: Request iPXE boot script
HTTP->>Pi: Deliver customized iPXE script
Pi->>HTTP: Request kernel and initramfs
HTTP->>Pi: Deliver kernel and initramfs
Note over Pi: Boot into loaded OS
-
Initial Boot Phase:
- The Raspberry Pi 4 sends a DHCP broadcast on the network
- Metal Boot's DHCP proxy service responds with appropriate options including TFTP server information
- The Pi downloads and boots the UEFI firmware (RPI_EFI.fd) via TFTP
-
UEFI Firmware Phase:
- The Pi boots into EDK2-based UEFI firmware
- UEFI firmware reads its configuration and boot entries
- Based on boot order, the Pi may attempt PXE boot
-
iPXE Boot Phase:
- If netbooting, the Pi requests iPXE boot loader
- The iPXE boot loader retrieves a dynamic boot script
- The boot script configures kernel, initramfs and boot parameters
- The Pi loads and boots the provided OS
Netboot configuration is managed through the netboot.yaml and backend.yaml files:
e0:92:8f:45:b4:40:
allow_pxe: true
console: ""
facility: ""
ipxe_script: ""
ipxe_script_url: null
osie:
kernel: ironic-python-agent.kernel
initrd: ironic-python-agent.initramfsThe configuration lets you define per-device settings, including:
- Whether PXE boot is allowed
- Console settings
- Custom iPXE scripts
- Kernel and initramfs files
Metal Boot incorporates tools for modifying and managing UEFI firmware for Raspberry Pi 4 devices.
Metal Boot uses the EDK2-based UEFI firmware for Raspberry Pi 4 (from pftf/RPi4). The firmware is embedded in the application and served via TFTP.
Default UEFI configuration:
arm_64bit=1
arm_boost=1
enable_uart=1
uart_2ndstage=1
enable_gic=1
armstub=RPI_EFI.fd
disable_commandline_tags=1
disable_overscan=1
device_tree_address=0x1f0000
device_tree_end=0x200000
dtoverlay=miniuart-bt
dtoverlay=upstream-pi4
tftp_prefix=2
Metal Boot provides functionality to:
- Read existing EFI variables from firmware
- Modify EFI variables including boot entries
- Write updated EFI variables back to firmware
- Serve customized firmware to devices
EFI boot entries control the boot sequence of the Raspberry Pi. Metal Boot can decode and modify these entries:
Example boot entry:
Boot0003: boot entry: title="UEFI PXEv4 (MAC:D83ADD5A440C)" devpath=MAC()/IPv4() optdata=4eac0881119f594d850ee21a522c59b2
Boot entries can be modified to change:
- Boot order (which devices are tried first)
- PXE boot configuration
- Network boot options
- MAC address binding
The virt-fw-vars tool is used to manipulate UEFI variables with commands like:
virt-fw-vars --inplace RPI_EFI.fd --set-json firmware-vars.jsonMetal Boot implements industry-standard Redfish API for out-of-band management of Raspberry Pi devices.
Metal Boot includes an optional Talos image handler that provides dynamically generated Talos OpenStack images with custom extensions and overlays. This allows for automated provisioning of Talos Linux on your infrastructure.
GET /images/talos/{talos_version}/{arch}/openstack.raw?extensions={extensions}&overlay={overlay}
Parameters:
talos_version: Specific version (e.g., "v1.11.1") or "latest" for the latest stable releasearch: Architecture ("amd64" or "arm64")extensions: Comma-separated list of extension names (optional)overlay: Single overlay name (optional)
Example URLs:
# Latest Talos for amd64
curl /images/talos/latest/amd64/openstack.raw
# Specific version with extensions
curl "/images/talos/v1.11.1/amd64/openstack.raw?extensions=qemu-guest-agent,nvidia-open-gpu-kernel-modules"
# ARM64 with Raspberry Pi overlay
curl "/images/talos/v1.11.1/arm64/openstack.raw?overlay=rpi-generic"- Smart Caching: Downloaded images are cached locally with SHA256 integrity verification
- Compression: Uses gzip-compressed downloads for bandwidth efficiency
- Validation: Validates extensions and overlays against available versions from Talos image factory
- Streaming: Images are streamed to clients while being cached simultaneously
- Integrity Checking: SHA256 checksums are calculated and verified for all cached images
- Proper Schematic Handling: Extensions and overlays are properly separated in Talos schematics
Enable the Talos handler in your configuration:
talos:
enabled: true
base_url: "https://factory.talos.dev"
cache_directory: "/var/cache/metal-boot/talos"
max_cache_size: 10737418240 # 10GB
default_extensions: []Configuration Options:
enabled: Enable/disable the Talos handlerbase_url: Talos image factory URL (default: "https://factory.talos.dev")cache_directory: Local cache directory for imagesmax_cache_size: Maximum cache size in bytes (0 = unlimited)default_extensions: Default extensions to include when none specified
Checksum Access:
SHA256 checksums for cached images are available by appending .sha256 to any image URL:
# Get the SHA256 checksum for a Talos image
curl /images/talos/v1.11.1/amd64/openstack.raw.sha256The Redfish API provides a RESTful interface for:
- Device discovery and inventory
- Hardware status monitoring
- Power control (on/off/restart)
- Boot configuration
- Firmware updates
Metal Boot can control power to Raspberry Pi devices by:
- PoE Switch Control: For Raspberry Pis powered via Power over Ethernet, Metal Boot can control power by managing PoE switch ports.
Power:
device_id: f4:e2:c6:50:60:bb
mode: "PowerOn"
port: 2
state: "on"Metal Boot maintains a mapping between MAC addresses and PoE switch ports, allowing for automatic discovery and power management of Raspberry Pi devices on the network.
Metal Boot can integrate with OpenStack Ironic for complete bare-metal provisioning:
flowchart TD
subgraph "Metal Boot Environment"
DHCP[DHCP Proxy]
TFTP[TFTP Server]
HTTP[HTTP Server]
Redfish[Redfish API]
end
subgraph "OpenStack Environment"
Ironic[Ironic API]
IPA[Ironic Python Agent]
Inspector[Ironic Inspector]
end
subgraph "Raspberry Pi Fleet"
Pi[Raspberry Pi 4 Devices]
end
DHCP -->|Boot Config| Pi
TFTP -->|UEFI Firmware| Pi
HTTP -->|iPXE Scripts| Pi
HTTP -->|IPA Kernel/Initramfs| Pi
Pi -->|Boot| IPA
IPA -->|Hardware Info| Inspector
Inspector -->|Inventory| Ironic
Ironic -->|Management| Redfish
Redfish -->|Power Control| Pi
- Metal Boot provides DHCP, TFTP and HTTP services for netbooting
- Raspberry Pi devices boot the Ironic Python Agent (IPA)
- IPA collects hardware information and sends to Ironic Inspector
- Ironic manages the devices through Metal Boot's Redfish API
Metal Boot supports DNSMasq-compatible DHCP lease management for production environments. See DHCP Lease Management for complete documentation.
Key features:
- DNSMasq-compatible lease file format
- Automatic DHCP option configuration for netboot clients
- Persistent lease storage across service restarts
- Periodic cleanup of expired leases
Enable lease management in your configuration:
dhcp:
enabled: true
proxy_enabled: false # Required for lease management
lease_file: "/var/lib/dhcp/dhcp.leases"
config_file: "/etc/dhcp/dhcp.conf"To set up a local testing environment:
- Configure a test network with a DHCP server that forwards PXE requests
- Connect Raspberry Pi devices to this network
- Run Metal Boot server on a machine on the same network
- Observe DHCP requests and responses using a network analyzer
To test modifications to UEFI firmware:
- Create a backup of existing firmware
- Make changes to EFI variables using the provided tools
- Serve the modified firmware to a test device
- Verify boot behavior matches expectations
- DHCP proxy correctly responds to PXE boot requests
- TFTP server successfully delivers firmware files
- UEFI firmware boots and honors variable settings
- iPXE boot loader successfully loads and runs
- Redfish API correctly reports device status
- Power control functions work as expected
Contributions to Metal Boot are welcome! Here are some guidelines:
- Code Style: Follow Go best practices and ensure code passes linting
- Testing: Add unit tests for new functionality
- Documentation: Update documentation for new features
- Pull Requests: Create PRs with clear descriptions of changes
- Issues: Use GitHub issues to report bugs or request features
# Clone the repository
git clone https://github.com/metal3-community/metal-boot.git
cd metal-boot
# Install dependencies
go mod download
# Build the project
go build ./cmd/metal-boot[License details would go here]
- A network with DHCP and TFTP capabilities
- Raspberry Pi 4 devices with network boot enabled
- For power management: PoE switch with API access
- Go 1.18+ for development