Custom Development and Feature Extension
Creating a New OpenWRT Package
Overview:
- An OpenWRT package is a modular unit of software that can be installed, updated, or removed using the
opkg
package manager. - Packages typically include executables, libraries, scripts, or configuration files to extend OpenWRT’s functionality.
- Creating a package involves defining its build instructions and metadata in a structured format.
Package Structure:
- Makefile: Defines how the package is built, installed, and packaged.
- Files Directory: Contains configuration files, scripts, or data to be included in the package.
- Patches: Optional patches for modifying source code.
- Metadata: Includes package name, version, dependencies, and description.
Purpose:
- Enables developers to add custom applications, services, or drivers to OpenWRT.
- Integrates seamlessly with the OpenWRT build system for cross-compilation.
- Supports distribution via package repositories for easy installation.
Key Components:
- Source Code: Either included in the package or downloaded from a URL (e.g., GitHub, tarball).
- Dependencies: Specified in the Makefile to ensure required libraries or tools are installed.
- Installation Scripts: Define how files are placed in the filesystem (e.g.,
/usr/bin
,/etc/config
).
Benefits:
- Modular design allows independent updates without rebuilding the entire firmware.
- Community sharing through feeds and repositories.
- Compatibility with OpenWRT’s lightweight architecture.
Makefile and Build System Integration
Overview:
- OpenWRT’s build system uses Makefiles to compile and package software for specific architectures.
- A package Makefile defines build rules, dependencies, and installation steps, integrating with the OpenWRT buildroot system.
Makefile Structure:
- Package Metadata: Includes
PKG_NAME
,PKG_VERSION
,PKG_RELEASE
, andPKG_LICENSE
. - Source Definition: Specifies source code location (e.g.,
PKG_SOURCE_URL
,PKG_SOURCE
). - Build Rules: Defines compilation steps using
Build/Compile
andBuild/Install
. - Dependencies: Lists required packages via
DEPENDS
and build tools viaBUILD_DEPENDS
.
Build System Integration:
- Packages are placed in the
/package
directory of the OpenWRT source tree. - The build system uses
make menuconfig
to select packages for inclusion in the firmware. - Cross-compilation is handled automatically for the target architecture (e.g., ARM, MIPS).
Key Features:
- Supports incremental builds to reduce compilation time.
- Integrates with feeds for external package sources.
- Ensures compatibility with OpenWRT’s toolchain (e.g.,
musl
libc, GCC).
Benefits:
- Simplifies package development with standardized templates.
- Enables portability across supported devices.
- Facilitates upstream contributions to OpenWRT’s package repository.
C Program Skeleton using UBUS and UCI APIs
Overview:
- OpenWRT provides
libubus
andlibuci
for interacting with the UBUS interprocess communication framework and UCI configuration system. - A C program can use these APIs to create services, query system state, or modify configurations.
UBUS API:
- Purpose: Enables communication with OpenWRT components (e.g.,
netifd
,uci
) via the UBUS message bus. - Key Functions:
ubus_connect
: Establishes a connection toubusd
.ubus_call
: Invokes methods on UBUS objects (e.g.,network.interface.status
).ubus_register_object
: Registers a custom object to expose methods.
- Use Case: Querying network status or subscribing to events like interface changes.
UCI API:
- Purpose: Provides programmatic access to UCI configuration files (e.g.,
/etc/config/network
). - Key Functions:
uci_alloc_context
: Creates a UCI context.uci_lookup_ptr
: Retrieves configuration values.uci_set
: Modifies configuration settings.
- Use Case: Reading or updating network or wireless settings.
Skeleton Structure:
- Initialize
libubus
and connect toubusd
. - Register a UBUS object with methods (e.g., to expose custom functionality).
- Use
libuci
to read/write UCI configurations. - Handle events or method calls via UBUS callbacks.
Benefits:
- Tight integration with OpenWRT’s architecture.
- Lightweight and efficient for embedded systems.
- Enables dynamic system interactions (e.g., real-time configuration updates).
Adding a New Service to Procd
Overview:
procd
is OpenWRT’s process manager and init system, responsible for starting, monitoring, and restarting services.- Adding a new service involves creating a script and integrating it with
procd
for lifecycle management.
Service Creation:
- Init Script: Place a script in
/etc/init.d/
withstart
,stop
, andrestart
functions. - Procd Integration: Use
procd
utilities to define service parameters (e.g., command, respawn policy). - Configuration: Store service settings in UCI files (e.g.,
/etc/config/myservice
).
Key Components:
- Service Definition: Specify the executable, arguments, and environment via
procd_set_param
. - Watchdog: Enable
procd
watchdog for automatic restarts on failure. - UBUS Integration: Expose service status or methods via UBUS for interaction with other components.
Benefits:
- Ensures robust service management with automatic restarts.
- Integrates with OpenWRT’s event-driven architecture.
- Simplifies service configuration via UCI.
Extending LuCI with a Custom Page
Overview:
LuCI
is OpenWRT’s web interface, built using Lua and following an MVC (Model-View-Controller) architecture.- Extending
LuCI
involves adding a custom page to provide new functionality or configuration options.
Components:
- Model: Uses UCI or UBUS to fetch system data (e.g., network status).
- View: Lua templates or HTML for rendering the page.
- Controller: Lua script to handle user input and interact with UCI/UBUS.
Process:
- Create a new Lua module in
/usr/lib/lua/luci/controller/
. - Define routes to map URLs to controller functions.
- Add templates in
/usr/lib/lua/luci/view/
for the UI. - Integrate with UCI for configuration management.
Benefits:
- Seamless integration with
LuCI
’s existing interface. - Enables user-friendly configuration for custom services.
- Leverages OpenWRT’s lightweight web server (
uhttpd
).
Adding Configuration Parameters via UCI
Overview:
- The Unified Configuration Interface (UCI) allows centralized management of system settings in
/etc/config/
files. - Adding custom parameters involves defining a new UCI configuration file for a package or service.
Process:
- Create a file in
/etc/config/
(e.g.,/etc/config/myservice
). - Define sections and options (e.g.,
config myservice
withoption enabled '1'
). - Use
uci
CLI orlibuci
to read/write parameters. - Integrate with
LuCI
or UBUS for dynamic updates.
Structure:
- Sections: Group related settings (e.g.,
config interface 'lan'
). - Options: Key-value pairs for settings (e.g.,
option proto 'dhcp'
). - Lists: Support multiple values (e.g.,
list dns '8.8.8.8'
).
Benefits:
- Consistent configuration interface across OpenWRT.
- Supports CLI, API, and web-based management.
- Enables persistent and validated settings.
Debugging with Logread, GDB, and Strace
Overview:
- OpenWRT provides tools for debugging system and application issues on resource-constrained devices.
Logread:
- Purpose: Reads system logs from
procd
’s log buffer. - Usage: Access logs via
logread
CLI to diagnose service or system issues. - Features: Supports filtering and real-time monitoring (e.g.,
logread -f
).
GDB:
- Purpose: GNU Debugger for analyzing C/C++ programs.
- Usage: Debug user-space applications or services compiled with debug symbols.
- Limitations: Resource-intensive; requires sufficient RAM and storage.
Strace:
- Purpose: Traces system calls and signals for a process.
- Usage: Diagnose runtime issues by monitoring interactions with the kernel.
- Features: Lightweight and effective for pinpointing errors in system calls.
Benefits:
- Provides comprehensive debugging capabilities for embedded systems.
- Integrates with OpenWRT’s lightweight architecture.
- Enables rapid identification of issues in custom applications or services.