Adding a userspace tool
Use the Buildroot external tree to include an application in the image. Follow Writing applications for a first C program and a build-to-board example. The commands here run from the parent project root unless marked as board commands.
Add a shell script
Place a user command under
buildroot-external/board/esp32-s31/overlay/usr/bin/; use usr/sbin/ for an
administrative command. Start the script with its interpreter, such as
#!/bin/sh, and make it executable. Buildroot copies this filesystem overlay
into the image during the rootfs build.
Add a Buildroot package
This example adds a small s31-hello program using the same local-source package
mechanism as s31-tools.
1. Add the source
Create rootfs/s31-hello/hello.c:
#include <stdio.h>
int main(void)
{
puts("Hello from the s31-hello package!");
return 0;
}
2. Add the package definition
Create buildroot-external/package/s31-hello/Config.in:
config BR2_PACKAGE_S31_HELLO
bool "s31-hello"
help
Small example application for ESP32-S31 Linux.
Create buildroot-external/package/s31-hello/s31-hello.mk. The command lines
inside the define blocks start with a tab:
S31_HELLO_VERSION = 1.0
S31_HELLO_SITE = $(BR2_EXTERNAL_ESP32_S31_PATH)/../rootfs/s31-hello
S31_HELLO_SITE_METHOD = local
define S31_HELLO_BUILD_CMDS
$(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \
$(@D)/hello.c -o $(@D)/s31-hello
endef
define S31_HELLO_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 0755 $(@D)/s31-hello \
$(TARGET_DIR)/usr/bin/s31-hello
endef
$(eval $(generic-package))
Add this line inside the existing menu in buildroot-external/Config.in:
source "$BR2_EXTERNAL_ESP32_S31_PATH/package/s31-hello/Config.in"
buildroot-external/external.mk already includes package/*/*.mk, so the new
Makefile is found automatically. For a larger application, add its build
dependencies and corresponding Kconfig dependencies or selections. Record its
actual license and license files in the package metadata when preparing it for
distribution. s31-tools and esp-simd are local examples.
3. Select and save the package
After make fetch has prepared the Buildroot output, open its menu:
make buildroot-menuconfig
Find s31-hello under the external ESP32-S31 packages menu and enable it. Exit
with the configuration saved, then use Buildroot’s savedefconfig target to export a review copy:
make -C buildroot O="$PWD/out/buildroot" \
BR2_EXTERNAL="$PWD/buildroot-external" \
savedefconfig DEFCONFIG="$PWD/out/generated/buildroot-menu.defconfig"
Merge the intended package selections into
buildroot-external/configs/esp32s31_rootfs_defconfig; this example adds
BR2_PACKAGE_S31_HELLO=y. Preserve the source expressions for
BR2_TOOLCHAIN_EXTERNAL_PATH and BR2_ROOTFS_OVERLAY: the review copy contains
resolved host/toolchain and staging paths injected by the parent, so do not
replace the portable source defconfig with that whole file.
Review the source diff before reconfiguring. A populated Buildroot output rejects manually changed output configuration and changed package/toolchain inputs. Reconfiguration discards that output while retaining download caches.
4. Build, flash, and run
The application is deployed as part of a verified matched image set. With the ESP-IDF environment active, run on the host:
make buildroot-reconfigure
make fetch-rootfs
make image
ls -l out/buildroot/target/usr/bin/s31-hello
make flash-existing-all PORT=/dev/ttyUSB0
Replace the port and close its serial monitor before flashing. This updates kernel, rootfs/module and radio together; partial flash targets are disabled. After restart, log in through the serial console and run on the board:
s31-hello
It prints Hello from the s31-hello package!. This process does not require an
SSH server on the board.
5. Rebuild after changing local source
The parent tracks changed inputs for its existing local utility packages; your
new package is not in that list. After editing rootfs/s31-hello/hello.c, remove this
package’s build directory before rebuilding the image:
make -C buildroot O="$PWD/out/buildroot" \
BR2_EXTERNAL="$PWD/buildroot-external" s31-hello-dirclean
make image
make flash-existing-all PORT=/dev/ttyUSB0
This makes Buildroot copy and compile the updated local source. Repeat the board run command after flashing.
Keep the application and its dependencies in the image
The post-build script prunes selected programs and
shared libraries after package installation. Check out/buildroot/target
after make rootfs, including the libraries your executable needs. A successful
package build alone does not show that its runtime files remain in the image.
For example, the script removes libstdc++, libatomic, BlueZ tools and daemon,
and D-Bus/GLib/BlueALSA files. Adding a C++ application or a BlueZ-based system
therefore needs a corresponding review of those removal rules. The current
script checks essential runtime executables, including s31-btstack-a2dp,
s31-ext-test, s31-gpio, s31-config-archive, esp32-config, and the BTstack
startup script /etc/init.d/S40btstack. Replacing a required file needs a
corresponding update to that check and the services or commands that use it.
The parent build checks that the finished rootfs fits its flash partition.
Deploy files that must survive reboot
Ordinary persistence is covered by Configuration. Two startup cleanup rules matter when uploading replacements for packaged files. Before mounting the writable root layer, the init script removes writable copies of:
/usr/sbin/s31-btstack-a2dp
/etc/init.d/S40btstack
/etc/init.d/S40bluetoothd
/etc/init.d/S42s31-a2dp
/usr/sbin/bluetoothd
/usr/bin/bluealsa
/usr/sbin/s31-bt-agent
/etc/bluetooth/main.conf
It also removes writable copies of .dtbo filenames shipped in
/usr/lib/s31-overlays by the current rootfs. A replacement uploaded to one of
these paths can work during the current session and disappear at the next boot.
To retain changes to these packaged files, rebuild and flash the rootfs. For a
temporary experiment, use a separate filename and invoke it explicitly. Pairing
keys and /etc/esp32-conf are outside these cleanup rules.