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
opkgpackage 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/CompileandBuild/Install. - Dependencies: Lists required packages via
DEPENDSand build tools viaBUILD_DEPENDS.
Build System Integration:
- Packages are placed in the
/packagedirectory of the OpenWRT source tree. - The build system uses
make menuconfigto 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.,
musllibc, 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
libubusandlibucifor 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
libubusand connect toubusd. - Register a UBUS object with methods (e.g., to expose custom functionality).
- Use
libucito 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:
procdis 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
procdfor lifecycle management.
Service Creation:
- Init Script: Place a script in
/etc/init.d/withstart,stop, andrestartfunctions. - Procd Integration: Use
procdutilities 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
procdwatchdog 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:
LuCIis OpenWRT’s web interface, built using Lua and following an MVC (Model-View-Controller) architecture.- Extending
LuCIinvolves 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 myservicewithoption enabled '1'). - Use
uciCLI orlibucito read/write parameters. - Integrate with
LuCIor 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
logreadCLI 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.