This lets us run `which`
I've found myself wanting this a bunch while trying to figure out, well,
which binary I'm running. I can walk $PATH myself, but it's no fun.
libbusybox.so size impact: +0 bytes (that is, it's less than the
4KB-padded text section we already have).
Ping is a foundational tool for network debugging, and with so many
network integrations in Home Assistant, we deserve a fancy ping.
This enables flags like `-c` count ping and packet loss statistics.
Nothing totally groundbreaking, but it enables more detailed debugging.
Without fancy ping, you get very limited flags, that just do one ping
per invocation.
```
# ping 127.0.0.1
127.0.0.1 is alive!
# ping --help
BusyBox v1.37.0 (2026-07-01 07:04:23 UTC) multi-call binary.
Usage: ping HOST
```
Add firmware for the Intel Wi-Fi 7 BZ family (e.g. BE201, used in Arrow
Lake systems) and the Intel SC chip (Panther Lake). Both detect but fail
to probe without their respective iwlwifi-bz-*/iwlwifi-sc-* firmware.
* buildroot fe7b14c878...c1438cf214 (2):
> package/linux-firmware: add Intel BZ WiFi firmware
> package/linux-firmware: add Intel SC WiFi firmware
Closes#4829Closes#4826
* Enable CONFIG_BT_INTEL_PCIE for Intel PCIe Bluetooth
Starting with Meteor Lake and continuing through Lunar Lake and Panther
Lake, Intel integrates the Bluetooth controller as a native PCIe endpoint
rather than behind the internal USB hub. These chips (e.g. Scorpius Peak
on Panther Lake, PCI 8086:e476) require the btintel_pcie transport driver,
which was not built so far.
The Kconfig dependencies (PCI, ACPI, BT_INTEL, FW_LOADER) and the
linux-firmware ibt-* files are already present, so enabling the module is
sufficient to bind these controllers.
Closes#4827
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Rewording of comment
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
The boot script only persisted the decremented boot-attempt counter
(storebootstate) when a kernel was successfully loaded. When *neither*
slot's kernel could be loaded, it instead reset both counters back to 3
and rebooted - pinning them and looping forever without ever counting
down or falling back. A failed kernel load therefore never consumed an
attempt, defeating the A/B rollback safety net (#4788).
Persist the (decremented) counters on a failed load too, and only re-arm
them once both slots are actually exhausted instead of on every failure.
Repeated load failures now count down and we fall back to the other slot.
Note: this does not address the underlying eMMC read unreliability seen
on some N2 units (kernel/boot.scr loads failing in U-Boot); it makes the
slot-fallback logic behave correctly when a load does fail.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The seedrng applet got pulled in by an oldconfig default when busybox was
bumped to 1.37.0; it was never a deliberate choice. RNG seeding on HAOS is
already handled by systemd's systemd-random-seed.service, which runs the
native systemd-random-seed binary directly (it does not invoke the seedrng
command). The applet is therefore redundant and orphaned - nothing in the
image references it - so disable it.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The netstat applet is not used anywhere within HAOS and is superseded by
ss from iproute2, which is shipped on all boards and is the modern,
preferred equivalent (e.g. ss -tulpn replaces netstat -tulpn).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This costs a few KB, but is invaluable when debugging host problems,
otherwise busybox just exits failure on any argument it doesn't
understand.
Fixes#4830
The haos-expand.service ("HAOS data resizing") is a Type=oneshot unit
without an explicit timeout, so it inherited systemd's
DefaultTimeoutStartSec (90s). On slow or previously used disks the data
partition resize can take longer than that, causing the service to be
killed and mnt-data.mount to fail with "Dependency failed for HAOS data
resizing", leaving the system unusable.
Aborting the resize serves no purpose: if it fails the installation is
broken anyway. Set TimeoutStartSec=infinity so the resize runs for as
long as it needs instead of failing the boot.
Fixes#3365
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Enable CONFIG_DRM_ACCEL_IVPU on the generic-x86-64 and OVA boards so the
Intel NPU (Neural Processing Unit) found on Core Ultra CPUs (Meteor Lake
and later, including Panther Lake) is exposed as /dev/accel/accel0. This
lets add-ons such as Frigate use OpenVINO with hardware-accelerated
inference on the NPU.
Also select the Intel NPU firmware (intel/vpu/vpu_*.bin), which already
ships in linux-firmware 20260410 including the Panther Lake (vpu_50xx)
blob.
The driver is x86_64-only, so it is added to the per-board configs rather
than the shared device-support-pci.config which is also used by aarch64
boards.
Fixes#4783
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The kernel bump to 6.18 means newer Intel Wi-Fi 7 devices (BZ/GL/SC/DR
families, e.g. the BE200) are no longer handled by the iwlmvm op-mode.
Their firmware now requires the new iwlmld driver, and without it the
iwlwifi core aborts the probe with:
IWLMLD needs to be compiled to support this firmware
probe with driver iwlwifi failed with error -22
Enable CONFIG_IWLMLD so these devices bind again. The matching firmware
(iwlwifi-gl-*) already ships via linux-firmware.
Fixes#4784
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Enable usbip on all targets
Enable the usbip userland tools (BR2_PACKAGE_USBIP), already provided by
the pinned Buildroot (package/usbip), to attach remote USB devices over
the network. The USBIP kernel modules are already enabled via
device-support.config.
This is the OS-side prerequisite for driving USB/IP from os-agent
(home-assistant/os-agent#265).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix configs ordering using savedefconfig
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Jan Čermák <sairon@sairon.cz>
After #4762, NFS_V4 was set as module in ODROIDs, Green and VIM3
kernels. This is because their defconfigs set the upper NFS_FS symbol to
module. Set it to built-in in these defconfigs as well (for other
targets this is handled by defconfigs from the kernel) and remove
redundant options we set in the haos fragment.
Borrow shrinking used in home-assistant/operating-system-full-images for
reducing the data partition size to only fit its contents. Currently the
data partition is intentionally overprovisioned to comfortably fit all
docker images in the hassio build. This results in unnecessarily large
image which takes longer to flash, as all the zeroes at the end of the
filesystem need to be written to the SD card.
For OVA and aarch64 VM formats, the image is resized before creating the
VM images - this also makes all generic-aarch64 images sized to 32GB,
unlike 6GB which inherently needed resizing before use. Some juggling
extra juggling is needed in the aarch64 post-image step, as we want to
preserve the raw image (e.g. for generic aarch64 boards) but it's
desirable to keep it minimal as well, as it's meant to be flashed to
real hardware storage.
Not all defconfigs enable NFS v4.1/v4.2 by default, most importantly
it's not enabled for x86_64 (on the other hand, it is enabled on RPi,
Rockchip and Amlogic). Explicitly enable NFS_V4 and its minor versions
in the common config fragment to ensure it's available everywhere.
It can now be removed from the Rochckip fragment, while removing the
migration option there for good (as Kconfig says it's very
experimental).
Fixes#4742
Add certificates with new PKI chain to replace the old one. Until May
14th 2028, bundles signed with the old certs will be accepted as well.
The transition to the new authority using bundles signed by the new
certs is ensured by the intermediate certificate signed by the old CA.
This, and the old CA certificates can be removed from the keyring after
their expiry.
The keyrings no longer contain CRLs, but the validity of the
certificates will be shortened to 4 years, as discussed in the linked
issue.
Closes#4743
The rule using 33% of RAM for default swapfile size had flaws both for
low and high RAM systems - for the former the swap was too small to
provide any buffer for OOM situations, for the latter it created
unnecessarily big swapfile.
Clamp the swapfile size to 1-4 GB. This means the file will somewhat
grow on systems with 1 or 2 GB of RAM, but this should be within bounds
of what's reported by HA as low storage. For systems with >12 GB of RAM,
the swap file wouldn't be created larger than 4 GB (in fact, will be
recreated if bigger). The configured size is still respected.
Closes#4481
Enable the JMicron JMC25x Gigabit Ethernet driver (CONFIG_JME) in the
kernel configuration.
This controller (specifically the JMC251) is very common on various
budget mini PCs (often used as Home Assistant nodes) but currently lacks
native driver support in Home Assistant OS out of the box. Adding these
flags restores native network connectivity for these devices.
Enable Intel Xe driver as a module and the related linux-firmware
option for generic-x86-64 and ova.
The bloat in generic-x86-64 image is 1.2MiB, which is acceptable.
Closes#4611
In #4279 we enabled PSI globally. However, Raspberry Pi config enables
it along with CONFIG_PSI_DEFAULT_DISABLED, which requires adding a
cmdline option to expose PSI metrics. Add a global disable for this
option to enable PSI on all targets unconditionally.
Fixes#4616
* Harmonize systemd unit and helper-script prefixes to haos (#4725)
Rename the hassos-prefixed systemd units and their ExecStart helper
binaries to a consistent haos- prefix, and update all in-repo
references. Normalize the affected unit Description= strings as well.
Units renamed in this commit are not referred externally (except for
syslog identifiers used in Supervisor Host logs), so no other changes
should be needed.
* Rename hassos-config to haos-config with alias
Rename the hassos-config.service unit and its binary to the haos-
prefix. This unit is restarted by Supervisor in os/manager.py, so add
Alias= to avoid the need to try both variants there.
* Rename hassos-cli binary to haos-cli
* Change HassOS to HAOS in unit descriptions and comments
* Rename hassos->haos in Buildroot makefiles, scripts and configs
* Rename bootargs_hassos to bootargs_haos in U-Boot scripts
* Rename external Buildroot tree HASSOS to HAOS
Set external.desc name to HAOS and rename all BR2_EXTERNAL_HASSOS_PATH
references to BR2_EXTERNAL_HAOS_PATH accordingly.
* Rename hassos.conf service drop-ins to haos.conf
* Rename hassos.config kernel fragment to haos.config
* Rename hassos-blobs repo in package/bluetooth-rtl8723
The repo was renamed somewhere in the past and it now relies on an
internal GitHub redirect. Change the URL to match the new repo name.
Since switching to systemd-resolved we've announced Home Assistant
Operating System as a workstation through _workstation._tcp DNS-SD. This
most likely came in to preserve what avahi announced by default.
However, the service has not a clear definition what it means and there
is no need for the service announcement really. The host name gets
announced even without a service announcement. This commit removes the
service announcement file from the rootfs.
* RaspberryPi: Update kernel to 6.18.32 - e165a3e0c5c6729d077c30c6d720c029d688d99d
* Update rpi-firmware to 1.20260521
* buildroot 1c0db348e3...c80dabe55e (1):
> package/rpi-firmware: update to 09267f5 (1.20260521)
* Use 6.18.y kernel config fragments, remove now unused 6.12.y
* Refresh patches and removed merged backports
* Update Yellow patches
Fix collision in the Makefile and add difference in phy1 fragment which
was added upstream in e6f13c8f14d9b776363ddd4966065eac3a8f7bb9:
ARM: dts: bcm2711: enable PHY link energy detect powerdown via DT
* Disable rtl8812au-aircrack-ng in Yellow defconfig
Yellow was the only one still including it and it doesn't build on 6.18.
* Drop removed symbols from RPi kernel config fragment
Give Supervisor enough time to gracefully stop Home Assistant Core, apps
and plugins when the host shuts down. The unit is already ordered
After=docker.service, so on a host reboot or power off it is stopped
before Docker tears containers down.
Supervisor should handle the SIGTERM from "docker stop" by running its
managed shutdown within 420 seconds, after that point it would be killed
by Docker, and ultimately 30 seconds later by Systemd.
Also, drop the delay after SIGTERM for ha-cli added in #2507. Once
Systemd shutdown is invoked, the ha-cli is no longer restarted.
Refs #4642, refs #4584
On CM4, rpi-eeprom-update only prints warning if the env variable
enabling self-update isn't set. In that case, also print bootloader info
so we can propagate it further.
Also, add patch making findBootFS faster, avoiding scan of all block
devices.
Refs #4631
Add firmware for MT7920, used by mt7921e and btmtk drivers. Note that
this card is also referred as MT7961_1a but the marked name is MT7920
(see [1]).
* buildroot 584f1d7531...1c0db348e3 (1):
> package/linux-firmware: add WiFi and BT firmware for MT7920
[1] https://lists.infradead.org/pipermail/linux-mediatek/2024-November/085899.htmlCloses#4460
The AppArmor patch can be dropped as it's been included upstream.
* buildroot 562e8f4491...584f1d7531 (3):
> package/containerd: bump version to v2.2.4
> package/docker-cli: bump version to v29.5.2
> package/docker-engine: bump version to v29.5.2
Previously we needed to call rpi-eeprom-update -b to learn if flashrom
must be used (which returned an error in that case) and there was no
info if flashrom update is available. Extend the output of the default
printVersions output to show this information as well, as it's rather
inexpensive to check it and it makes it easier to offer relevant update
entities based on that.
Part of #4631
Squash all the patches to a single file per DTS without making any other
changes. The long patch series makes it harder to understand how the DTS
looks like without applying them all. We still have the repo history and
in-file comments if we need to understand individual changes.
This backports patch currently waiting for a merge upstream that fixes
issue we saw with CM5 on Yellow, where the SD card init took over 120
seconds. We added a workaround in #3700 lowering this roughly to 20
seconds, but this is no longer needed, so revert this patch as well.
Standard pciutils are required by rpi-eeprom-update. The Busybox version
is missing the -d flag, failing to show VL805 version. Enable pciutils
to fix it, to avoid adding HAOS-specific patch to rpi-eeprom-update.
Previously the watchdog timeout was set to "default", which makes
systemd adopt whatever timeout the underlying hardware driver
advertises. In practice this means very different behavior across
platforms: common x86-64 watchdogs (iTCO_wdt, i6300esb on virtual
systems) default to around 30 seconds, while the Raspberry Pi BCM2835
watchdog uses 15 seconds.
These short timeouts have proven too aggressive in the presence of
stalled network storage. PID1 enters the kernel through paths that can
park it in D-state on a dead NFS mount: mount_enter_mounting() calls
chase()/open_tree(), is_dir()/mkdir_p_label() on bind mount sources,
and mkdir_p_label()/unit_warn_if_dir_nonempty() on destinations all
end up in nfs_lookup/nfs_getattr/nfs_readdir, waiting for an RPC major
timeout. While PID1 is blocked it cannot ping the watchdog, and the
system reboots even though the underlying issue is a network storage
stall, not a kernel hang. Reported upstream as
https://github.com/systemd/systemd/issues/42050.
Set RuntimeWatchdogSec to 5 minutes to align all platforms on a
single, conservative value that tolerates NFS/CIFS RPC timeouts while
still recovering from genuine PID1 hangs.
A note on hardware limits: some watchdog drivers expose a
max_hw_heartbeat_ms instead of max_timeout. In that case the watchdog
core in drivers/watchdog/watchdog_dev.c arms a kernel timer that pings
the hardware in the background and multiplexes a longer userspace
timeout on top, so a 300s request is accepted even when the silicon
counter cannot represent it. The BCM2835 watchdog used on all
Raspberry Pi variants is exactly this case: the PM_WDOG_TIME_SET
register caps at ~16s of hardware heartbeat, but the driver migrated
to the max_hw_heartbeat_ms path in v6.8 (commit f33f5b1fd1be
"watchdog: bcm2835_wdt: Fix WDIOC_SETTIMEOUT handling", Dec 2023), so
WDIOC_SETTIMEOUT(300) is honored — the core re-pings the chip every
~15s automatically and only stops once userspace has been silent for
the full 300s. Drivers that still use max_timeout directly will reject
300s with -EINVAL and systemd falls back to the driver's own value;
this is no worse than the previous "default" behavior.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Rebase fileenv on U-Boot v2026.04
* Update Green U-Boot to v2026.04, refresh patches
* Update U-Boot to v2026.04 on meson-based ODROIDs
* Update U-Boot to v2026.04 on Raspberry Pi
0013-configs-rpi-set-NR_DRAM_BANKS-to-8-to-accommodate-RA.patch was
merged upstream.
* Update Yellow U-Boot to v2026.04
* Update U-Boot to v2026.04 on Rockchip-based ODROIDs
* Update VIM3 U-Boot to v2026.04