#!/bin/sh
# ALARM post-handover init, run as PID 1 after /sbin/init has mounted the
# filesystems and built the USB console gadget.
#
# Installed into the root filesystem by alarm-build. Everything is logged to
# /dev/kmsg (so it appears in dmesg and in the ramoops pstore region) and to
# /var/log/alarm-init.log on the root filesystem, and the full state is
# published to the FAT boot partition where a PC can read it.
LOG=/var/log/alarm-init.log
FAT=/mnt/boot
mkdir -p /var/log 2>/dev/null
say() {
echo "[alarm-up] $*" > /dev/kmsg 2>/dev/null
echo "[alarm-up] $*" >> "$LOG" 2>/dev/null
}
publish() {
mkdir -p "$FAT" 2>/dev/null
if mount /dev/mmcblk0p1 "$FAT" 2>/dev/null; then
{
echo "=== alarm-up: $1 ==="
echo "uptime : $(cat /proc/uptime)"
echo
echo "--- processes ---"
for p in /proc/[0-9]*; do
printf '%-8s %s\n' "${p#/proc/}" "$(cat "$p/comm" 2>/dev/null)"
done
echo
echo "--- ttyGS ---"
ls -l /dev/ttyGS* 2>&1
echo
echo "--- UDC state ---"
cat /sys/class/udc/*/state 2>&1
echo
echo "--- log ---"
cat "$LOG" 2>/dev/null
echo
echo "--- dmesg tail ---"
dmesg | tail -40
} > "$FAT/ALARM_UP.txt" 2>&1
sync
umount "$FAT" 2>/dev/null
fi
}
say "starting, uptime $(cat /proc/uptime)"
say "ttyGS nodes: $(ls /dev/ttyGS* 2>&1)"
# --- serial console ---------------------------------------------------------
# Run an interactive shell with stdin, stdout and stderr all bound explicitly to
# the gadget serial port.
#
# This replaces `agetty -n -l /bin/bash ttyGS0`, which produced a prompt but no
# command output: input reached the shell, but its output never came back down
# the port. Binding the three descriptors explicitly is far more predictable.
#
# stty sane restores the default line discipline, including ICRNL, so a carriage
# return from the host terminal is translated to a newline and actually submits
# the line. Without it a CR-only terminal leaves every command unsubmitted.
if [ -e /dev/ttyGS0 ]; then
if command -v stty >/dev/null 2>&1; then
stty -F /dev/ttyGS0 sane 2>/dev/null
say "stty sane applied to ttyGS0"
fi
# A startup file for the console shell. Bash enables bracketed paste by
# emitting ESC[?2004h; minicom echoes that partially and the stray fragment
# gets executed as a command (it shows up as a bogus ":s" substitution
# error on connect). Turning it off keeps the session clean.
printf "bind 'set enable-bracketed-paste off' 2>/dev/null\n" \
> /etc/alarm-console.bashrc 2>/dev/null
if command -v setsid >/dev/null 2>&1; then
setsid /bin/bash --rcfile /etc/alarm-console.bashrc -i \
< /dev/ttyGS0 > /dev/ttyGS0 2>&1 &
say "started bash on ttyGS0 via setsid"
else
( /bin/bash --rcfile /etc/alarm-console.bashrc -i \
< /dev/ttyGS0 > /dev/ttyGS0 2>&1 ) &
say "started bash on ttyGS0 in the background"
fi
else
say "no /dev/ttyGS0 - the USB gadget produced no serial port"
fi
publish "after console start"
# --- network ----------------------------------------------------------------
say "bringing up WiFi"
modprobe brcmfmac 2>/dev/null
if [ -f /etc/wpa_supplicant/wpa_supplicant.conf ]; then
pkill wpa_supplicant 2>/dev/null
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
say "wpa_supplicant started"
else
say "no /etc/wpa_supplicant/wpa_supplicant.conf - skipping WiFi"
fi
# dhcpcd blocks until it has a lease, so run it detached.
( dhcpcd wlan0 >/dev/null 2>&1 & )
say "dhcpcd started detached"
# --- ssh --------------------------------------------------------------------
mkdir -p /run/sshd
pkill sshd 2>/dev/null
/usr/sbin/sshd 2>/dev/null
say "sshd exit code: $?"
publish "final"
say "ALARM up at $(date)"
exec /bin/sh