blob: 33c4620da17c89c354df055f7b2f129d3a7fc9fe [file] [log] [blame]
#!/bin/sh
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Finds and prepares (if needed) best terminal consoles for factory software.
# Usage:
# . /usr/sbin/factory_tty.sh
# tty_init
# echo something >>"${TTY}"
# [ -n "${LOG_TTY}" ] && echo "some log" >"${LOG_TTY}"
# TTY_CONSOLE will be changed by build script (values from make.conf).
TTY_CONSOLE=""
export TTY=""
export LOG_TTY=""
export INFO_TTY=""
export DEBUG_TTY=""
: ${FRECON_LITE_PATH:=/sbin/frecon-lite}
: ${FRECON_PATH:=/sbin/frecon}
: ${FRECON_TTY:=/run/frecon/vt0}
: ${FRECON_PID:=/run/frecon/pid}
: ${FRECON_EXTRA_TTY:=/run/frecon/vt1}
: ${FBDEV:=/sys/class/graphics/fb0}
: ${FBCON:=/sys/class/graphics/fbcon}
# Prints to kernel message (for debugging before TTY is setup).
kernel_msg () {
if [ -e "/dev/kmsg" ]; then
echo "$0: $*" >>/dev/kmsg || true
fi
}
# Extracts tokens from kernel command line.
kernel_get_var() {
local token="$1="
local entry="$(cat /proc/cmdline)"
local result=""
while echo "${entry}" | grep -q "${token}" ; do
entry="${entry#*${token}}"
result="${entry%%[ ,]*} ${result}"
entry="${entry#* }"
done
echo "${result}"
}
# Checks if given parameter is a valid TTY (or PTS) device file.
tty_is_valid() {
[ -c "$1" ] && (echo "" >"$1") 2>/dev/null
}
# Kills running frecon sessions.
kill_frecon() {
kill "$(cat "${FRECON_PID}")" || true
killall frecon-lite || true
killall frecon || true
}
# Starts the 'frecon' daemon.
tty_start_frecon() {
if [ -e "${FRECON_TTY}" ]; then
# Some devices may have frecon "failed" after switch_root, so we do want to
# make sure the frecon TTYs are "good". Can't trust FRECON_TTY since it's
# always "valid" even if there's nothing on screen...
if tty_is_valid "${FRECON_EXTRA_TTY}"; then
kernel_msg "Reuse existing Frecon instance."
return
fi
# frecon[-lite] seems broken, let's try to restart again.
kill_frecon
fi
kernel_msg "Starting frecon..."
udevd --daemon
udevadm trigger
udevadm settle
"${FRECON_PATH}" --enable-vt1 --daemon --no-login --enable-vts \
--pre-create-vts --num-vts=8 --enable-gfx
local loop_time=30
while [ ! -e "${FRECON_TTY}" -a ${loop_time} -gt 0 ]; do
kernel_msg " ${FRECON_TTY} does not exist. Retry for ${loop_time} seconds."
sleep 1s
loop_time=$((loop_time - 1))
done
if [ ! -e "${FRECON_TTY}" ]; then
kernel_msg "Frecon failed to start."
else
kernel_msg "Frecon is ready."
fi
}
# Finds if the TTY can be enumerated with given index.
tty_find_relative() {
local tty="$1"
local offset="$2"
# dash does not support [^0-9].
local tty_num="${tty##*[a-zA-Z_/]}"
local tty_base="${tty%${tty_num}}"
if [ -z "${tty_num}" ]; then
return
fi
local new_tty="${tty_base}$((tty_num + offset))"
if tty_is_valid "${new_tty}"; then
echo "${new_tty}"
fi
}
# Determine and setup (if needed) TTYs (TTY, LOG_TTY, INFO_TTY, DEBUG_TTY).
# TTY is detected by following order:
# - The last non-empty console= from cmdline.
# - If fbdev and fbcon both exist, try /dev/tty1.
# - ${FRECON_TTY} if available.
# - If frecon-lite is available, start frecon-lite and try ${FRECON_TTY}.
# - ${TTY_CONSOLE} if non-empty (which may be a list).
# - /dev/null if nothing else.
tty_init() {
local ttys="$(kernel_get_var console)"
local tty_name="" tty_path=""
TTY=""
LOG_TTY=""
# Always use frecon-lite if possible.
if [ -x "${FRECON_LITE_PATH}" ]; then
FRECON_PATH="${FRECON_LITE_PATH}"
fi
# /dev/tty1 should be tried earlier if the device has fbdev and fbcon.
if [ -e ${FBDEV} ] && [ -e ${FBCON} ]; then
ttys="${ttys} tty1"
elif [ -e ${FRECON_TTY} ] || [ -x ${FRECON_PATH} ]; then
tty_start_frecon
local frecon_tty="$(readlink -f ${FRECON_TTY})"
ttys="${ttys} ${frecon_tty#/dev/}"
fi
ttys="${ttys} ${TTY_CONSOLE} null"
kernel_msg "Finding best TTY from ${ttys}..."
for tty_name in ${ttys}; do
tty_path="/dev/${tty_name}"
if tty_is_valid "${tty_path}"; then
TTY="${tty_path}"
break
fi
done
# Devices using tty2 are actually using tty1 as default console.
[ "${TTY}" = /dev/tty2 ] && TTY=/dev/tty1
LOG_TTY="$(tty_find_relative "${TTY}" 1)"
INFO_TTY="$(tty_find_relative "${TTY}" 2)"
DEBUG_TTY="$(tty_find_relative "${TTY}" 3)"
kernel_msg "TTY=${TTY} LOG=${LOG_TTY} INFO=${INFO_TTY} DEBUG=${DEBUG_TTY}"
}