#!/bin/sh # /etc/rc for an embedded Linux system # Copyright (C)2013-2024, Philip Munts dba Munts Technologies. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # Boot time options are passed via OPTIONS=0x0XXXX on the kernel command line. # Boot time options bit definitions: # Bit 0 -- Enable USB serial gadget with getty # Bit 1 -- Enable USB network gadget with DHCP server # Bit 2 -- Run crond # Bit 3 -- Run ntpd # Bit 4 -- Run rpcbind # Bit 5 -- Run sshd # Bit 6 -- Run httpd # Bit 7 -- Enable USB serial gadget without getty # Bit 8 -- Run autoexec.script # Bit 9 -- Run mdnsd # Bit 10 -- Run inetd # Bit 11 -- Enable USB network gadget with DHCP client # Bit 12 -- Enable USB raw HID gadget # Bit 13 -- Enable /etc/rc debugging # Define a function to wait for a file or device node to be created WaitForFile() { while [ ! $1 $2 ] do test $((OPTIONS & 0x2000)) -ne 0 && echo "DEBUG: Wait for $2" usleep 100000 done } # Define a function to wait for a network interface to be created WaitForNetIF() { grep -q ${1}: /proc/net/dev while [ $? -ne 0 ] do test $((OPTIONS & 0x2000)) -ne 0 && echo "DEBUG: Wait for $1" usleep 100000 grep -q ${1}: /proc/net/dev done } # Here we go echo "Starting MuntsOS Embedded Linux" # Configure path for this script export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin # Fix root file system permissions chmod 755 / # Mount all file systems mount -a WaitForFile -d /dev/shm WaitForFile -d /dev/pts WaitForFile -d /proc WaitForFile -d /sys WaitForFile -d /sys/kernel/config WaitForFile -d /sys/kernel/debug touch /tmp/booting.flag # Create initial devices mdev -s # Start hotplug helper mdev -d # Create a symbolic link to the boot partition if [ -n "${BOOTPART}" ]; then WaitForFile -b /dev/${BOOTPART} ln -s ${BOOTPART} /dev/bootdisk unset BOOTPART fi # Set CPU frequency governor if [ -f /etc/scaling_governor ]; then GUV=/sys/devices/system/cpu/cpufreq/policy0/scaling_governor WaitForFile -f ${GUV} cat /etc/scaling_governor >${GUV} unset GUV fi # Initialize user LED WaitForFile -f @@USERLED@@/trigger echo none > @@USERLED@@/trigger WaitForFile -f @@USERLED@@/brightness echo 0 > @@USERLED@@/brightness chown root.led @@USERLED@@/brightness chmod 660 @@USERLED@@/brightness ln -s @@USERLED@@/brightness /dev/userled # Set platform identification environment variables export BOARDBASE=@@BOARDBASE@@ export BOARDNAME=${BOARDNAME:-@@BOARDNAME@@} export BOARDARCH=@@BOARDARCH@@ # Create /etc/platform echo "OSNAME=MuntsOS" >/etc/platform echo "OSREVISION=@@REVISION@@" >>/etc/platform echo "BOARDBASE=${BOARDBASE}" >>/etc/platform echo "BOARDNAME=${BOARDNAME}" >>/etc/platform echo "BOARDARCH=${BOARDARCH}" >>/etc/platform echo "KERNELREPO=@@KERNELREPO@@" >>/etc/platform echo "KERNELBRANCH=@@KERNELBRANCH@@" >>/etc/platform echo "KERNELCOMMIT=@@KERNELCOMMIT@@" >>/etc/platform echo "OPTIONS=${OPTIONS}" >>/etc/platform echo "SERIALNUMBER=`serialnumber`" >>/etc/platform echo "TOOLCHAINBUILDER=@@TOOLCHAINBUILDER@@" >>/etc/platform echo "TOOLCHAINREVISION=@@TOOLCHAINREVISION@@" >>/etc/platform if [ -n "${SHIELDNAME}" ]; then echo "SHIELDNAME=${SHIELDNAME}" >>/etc/platform fi chmod 444 /etc/platform # Symlink /dev/gpiochip-rpi to proper /dev/gpiochipN for Raspberry Pi # expansion header GPIO pins test -x /usr/libexec/link-gpiochip && /usr/libexec/link-gpiochip # Scan shared libraries linklibs ldconfig # Configure localhost interface ifconfig lo 127.0.0.1 netmask 255.255.255.0 # Block everything coming in iptables -w -P INPUT DROP iptables -w -P FORWARD DROP # Allow unrestricted access to localhost iptables -w -I INPUT -i lo -j ACCEPT # Allow established or related iptables -w -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Allow ping iptables -w -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT # Allow mdns if [ $((OPTIONS & 0x200)) -ne 0 ]; then iptables -w -A INPUT -p udp -m pkttype --pkt-type multicast -d 224.0.0.251 --dport 5353 -j ACCEPT fi # Allow everything going out iptables -w -P OUTPUT ACCEPT # Mount /boot and look for device tree overlays, tarballs and packages mount -o ro /boot >/dev/null 2>&1 if [ $? -eq 0 ]; then # Install the device tree overlays requested in /boot/overlays.txt /usr/libexec/install-overlays # Extract tarballs, if any for t in /boot/tarballs/*gz ; do if [ -f $t ]; then tar xzf $t --directory=/ fi done # Configure initial hostname if /etc/hostname came from a tarball test -f /etc/hostname && hostname -F /etc/hostname # Configure GPIO pin modes if [ -x /sbin/config-pin -a -f /etc/pinmux.conf ]; then config-pin -c /etc/pinmux.conf fi if [ -x /sbin/pinctrl -a -f /etc/pinmux.conf ]; then awk '{ sub("[ \t]*[#].*$",""); gsub("[ \t]+", " "); if ($0 != "") printf("pinctrl set %s\n", $0); }' /etc/pinmux.conf | sh fi # Install packages, if any for p in /boot/packages/*.deb ; do if [ -f $p ]; then dpkg -i $p >/dev/null fi done for p in /boot/packages/*.rpm ; do if [ -f $p ]; then rpm -i $p >/dev/null fi done for p in /boot/packages/*.nupkg ; do if [ -f $p ]; then nupkg $p fi done # Pick up any new libraries linklibs ldconfig # Pick up any new environment variables if [ -f /etc/environment ]; then for e in `cat /etc/environment` ; do export $e done fi if [ -f /var/run/environment ]; then for e in `cat /var/run/environment` ; do export $e done fi umount /boot fi # Configure initial hostname if [ -f /etc/hostname ]; then hostname -F /etc/hostname else hostname `uname -r | awk -F '-' '{ printf("%s-%s\n", $2, $3); }'` fi # Load kernel modules specified in /etc/modules if [ -f /etc/modules ]; then sed -e 's/#.*$//g' -e 's/^\s*//g' -e 's/\s*$//g' -e '/^$/d' -e 's/^/modprobe /' /etc/modules | sh fi # Load kernel modules for built-in wireless network interfaces grep -q -i "BeagleBone Black Wireless" /proc/device-tree/model if [ $? -eq 0 ]; then modprobe wl18xx modprobe wlcore_sdio WaitForNetIF wlan0 fi grep -q -i "BeagleBone Green Wireless" /proc/device-tree/model if [ $? -eq 0 ]; then modprobe wl18xx modprobe wlcore_sdio WaitForNetIF wlan0 fi grep -q -i "Raspberry Pi Zero W" /proc/device-tree/model if [ $? -eq 0 -a -f /sys/bus/sdio/devices/mmc1:0001:1/vendor ]; then modprobe brcmfmac WaitForNetIF wlan0 fi grep -q -i "Raspberry Pi Zero 2" /proc/device-tree/model if [ $? -eq 0 -a -f /sys/bus/sdio/devices/mmc1:0001:1/vendor ]; then modprobe brcmfmac WaitForNetIF wlan0 fi grep -q -i "Raspberry Pi 3 Model A" /proc/device-tree/model if [ $? -eq 0 -a -f /sys/bus/sdio/devices/mmc1:0001:1/vendor ]; then modprobe brcmfmac WaitForNetIF wlan0 fi grep -q -i "Raspberry Pi 3 Model B" /proc/device-tree/model if [ $? -eq 0 -a -f /sys/bus/sdio/devices/mmc1:0001:1/vendor ]; then modprobe brcmfmac WaitForNetIF wlan0 fi grep -q -i "Raspberry Pi 4 Model B" /proc/device-tree/model if [ $? -eq 0 -a -f /sys/bus/sdio/devices/mmc1:0001:1/vendor ]; then modprobe brcmfmac WaitForNetIF wlan0 fi grep -q -i "Raspberry Pi Compute Module 4" /proc/device-tree/model if [ $? -eq 0 -a -f /sys/bus/sdio/devices/mmc1:0001:1/vendor ]; then modprobe brcmfmac WaitForNetIF wlan0 fi grep -q -i "Raspberry Pi 5 Model B" /proc/device-tree/model if [ $? -eq 0 -a -f /sys/bus/sdio/devices/mmc1:0001:1/vendor ]; then modprobe brcmfmac WaitForNetIF wlan0 fi # Load USB Gadget Network module if [ $((OPTIONS & 0x802)) -ne 0 ]; then if [ -f /etc/g_ether.conf ]; then . /etc/g_ether.conf fi modprobe g_ether dev_addr=${GETHMACADDR:-02:00:00:00:00:01} host_addr=${GETHMACADDRHOST:-02:00:00:00:00:02} WaitForNetIF usb0 fi # Load USB Gadget Raw HID module if [ $((OPTIONS & 0x1000)) -ne 0 ]; then if [ -f /etc/g_hid.conf ]; then . /etc/g_hid.conf fi modprobe g_hid idVendor=${GHIDVID:-0x16D0} idProduct=${GHIDPID:-0x0AFA} iManufacturer="${GHIDMFG:-Munts Technologies}" iProduct="${GHIDPROD:-USB HID Device}" iSerialNumber="${GHIDSERIAL:-`serialnumber`}" WaitForFile -c /dev/hidg0 fi # Load USB Gadget Serial module if [ $((OPTIONS & 0x81)) -ne 0 ]; then modprobe g_serial WaitForFile -c /dev/ttyGS0 fi # Run getty on USB Gadget Serial interface, if requested if [ -c /dev/ttyGS0 -a $((OPTIONS & 0x01)) -ne 0 ]; then runsv /usr/libexec/services/ttyGS0 & fi # Prod network interfaces for E in /sys/class/net/*/uevent ; do test -f $E && echo add >$E done # Start system logger syslogd # Start crond if [ $((OPTIONS & 0x04)) -ne 0 -a -d /var/spool/cron/crontabs ]; then crond fi # Start ONC/RPC endpoint mapper if [ $((OPTIONS & 0x10)) -ne 0 ]; then iptables -w -A INPUT -p tcp -m conntrack --ctstate NEW --dport 111 -j ACCEPT iptables -w -A INPUT -p udp -m conntrack --ctstate NEW --dport 111 -j ACCEPT rpcbind fi # Start SSH server if [ $((OPTIONS & 0x20)) -ne 0 -a -d /etc/ssh ]; then iptables -w -A INPUT -p tcp -m conntrack --ctstate NEW --dport 22 -j ACCEPT test -f /etc/ssh/ssh_host_rsa_key || ssh-keygen -q -C "`hostname`" -N "" -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key && sysconfig --save /usr/sbin/sshd fi # Start web server if [ $((OPTIONS & 0x40)) -ne 0 -a -f /etc/httpd.conf -a -d /www ]; then iptables -w -A INPUT -p tcp -m conntrack --ctstate NEW --dport 80 -j ACCEPT httpd -c /etc/httpd.conf -u 65534:65534 -h /www fi # Register dynamic IP address, if applicable for noip2config in /usr/local/etc/noip2*.conf ; do if [ -f $noip2config ]; then noip2 -M -c $noip2config fi done # Start inetd if [ $((OPTIONS & 0x400)) -ne 0 -a -f /etc/inetd.conf ]; then inetd fi # Run package startup scripts in /etc/rc.d; if present for s in /etc/rc.d/* ; do if [ -x $s ]; then $s fi done # Run /etc/rc.local, if it is available if [ -x /etc/rc.local ]; then /etc/rc.local fi # Run application software on other media if [ $((OPTIONS & 0x100)) -ne 0 -a -x /usr/libexec/autoexec.script ]; then /usr/libexec/autoexec.script fi # Scan USB devices one last time, to pick up any newly installed kernel modules, # configuration files, etc. if [ -d /sys/bus/usb/devices ]; then lsusb | awk '{ printf("modprobe usb:v%sp%sd*dc*dsc*dp*ic*isc*ip*in*\n", toupper(substr($6, 1, 4)), toupper(substr($6, 6, 4))); }' | sh 2>&1 | grep -v 'not found' fi # Reload /etc/inittab, in case it has been changed kill -HUP 1 # Turn on the user LED to indicate startup is finished. echo 1 >/dev/userled rm /tmp/booting.flag