wiki:OpenWrt/init

OpenWrt Init System

The OpenWrt Linux Distro uses an init system similar to sysvinit common on most Linux Distros.

Here is the boot process in a nutshell:

  1. bootloader configures enough low level hardware to load kernel and jump to it with a kernel cmdline
  2. kernel inits hardware for everything built 'static' in the kernel
  3. kernel mounts the root filesystem (via the root= rootfstype= etc parameters in the kernel cmdline)
  4. kernel executes the 'init' process (PID 1).
    • this is done in the kernel's init_post function in init/main.c and typically will execute whichever is found first: /sbin/init, /etc/init, /bin/init, /bin/sh
    • for OpenWrt this function is patched so that it looks for and executes only /etc/preinit
  5. /etc/preinit does some low level work such as mounting filesystems etc
  6. /etc/init.d/rcS is run which executes all scripts in /etc/rc.d/S*
    • files here are typically symlinks to scripts in /etc/init.d and have a number preceeding the name to dictate a priority affects order of execution
    • /etc/init.d/ scripts include /etc/rc.common which implements enable/disable functions which create the symlinks. The start/stop priority numbers are defined in the init scripts

For more info see OpenWrt documentation:

Failsafe bootup

The /etc/preinit script has a 'failsafe' mechanism which allows you a few seconds to answer a prompt to go into 'failsafe mode'. This simply stops execution of the init scripts in case you have a mis-configuration or other issue that is keeping you from configuring the target board. There are many configurations for the failsafe mechanism at the top of /etc/preinit (network config, timeout, messages, etc)

Adding an init script

If you want something simple to be done 'near the end of every boot' a good place to put it may be in /etc/rc.local as this is executed by the /etc/init.d/done script which is symlinked to /etc/rc.d/S95done. Note that this isn't the 'last' init script run but is for sure near the end. You can see all the startup scripts in order with 'ls /etc/rc.d/S*'

Keep in mind that init scripts run with stdout/stderr supressed from the linux serial console. If you want to disable this supression you can put the following in your init script to redirect stdout/stderr to the serial console:

exec 1>/dev/console  ;# redirect stdout to serial console
exec 2>/dev/console  ;# redirect stderr to serial console

If you want to add a more complex init process that perhaps has a start/stop and a priority you can easily create your own init script by following the examples in /etc/init.d.

Note that if using 'sysupgrade' there is a specified set of files that get backed up and restored to the newly upgraded image along with all of UCI. This is configured in /etc/sysupgrade.conf. If you want your init changes to persist across a sysupgrade be sure to configure things properly. You may want to create an OpenWrt package and use UCI configuration to help do that for you.

Example

Below is an example of a simple script placed on OpenWrt at /etc/init.d/gst-httpd-watchdog. This script basically checks if a process is running, and if it doesn't find it, then it restarts it.

The key once creating this script is to then enable it by typing

/etc/init.d/gst-httpd-watchdog enable

This will place a symlink in /etc/rc.d/ as noted below

S55gst-httpd-watchdog

Here is the actual code /etc/init.d/ryantest

root@OpenWrt:/etc/init.d# cat ryantest 
#!/bin/sh /etc/rc.common

NAME=gst-httpd-watchdog
START=55
STOP=55

watchdog()
{
ps -aef | grep gst | grep -v grep

while [ 1 ] 
do

proc=$(ps -aef | grep gst | grep -v grep )

echo 'proc='$proc

if [ -z "$proc" ]
then
{
        echo 'gst process is not found, now restarting'
        /etc/init.d/gst-httpd restart
}
else
        echo 'gst process is running'
fi
sleep 10s;

done

}

start()
{
( watchdog ) &
}
Last modified 2 years ago Last modified on 11/15/2021 05:25:28 PM
Note: See TracWiki for help on using the wiki.