mirror of
https://salsa.debian.org/kernel-team/initramfs-tools.git
synced 2026-01-26 15:39:08 +00:00
The driver for coreboot firmware-initialized framebuffer can be built as a module. Debian kernels so far have it as built-in because they would not be probed automatically when built as a module. This is fixed now, likely with a patchset included in v6.9-rc1, so we might encounter it as a module either in Debian or with custom-built kernels. For MODULES=dep, check for the coreboot framebuffer in a different block from other platform drivers, and include the framebuffer_coreboot module if we find the device. For MODULES=most, add driver to the framebuffer modules list. Explicitly try to probe the module for break=top because it would not automatically probe there otherwise. Since it requires a driver for the "simple-framebuffer" device, add simpledrm and simplefb as its hidden dependencies. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
712 lines
15 KiB
Bash
712 lines
15 KiB
Bash
# -*- shell-script -*-
|
|
# shellcheck shell=sh
|
|
|
|
_log_msg()
|
|
{
|
|
if [ "${quiet?}" = "y" ]; then return; fi
|
|
# shellcheck disable=SC2059
|
|
printf "$@"
|
|
return 0 # Prevents error carry over in case of unavailable console
|
|
}
|
|
|
|
log_success_msg()
|
|
{
|
|
_log_msg "Success: %s\\n" "$*"
|
|
}
|
|
|
|
log_failure_msg()
|
|
{
|
|
_log_msg "Failure: %s\\n" "$*"
|
|
}
|
|
|
|
log_warning_msg()
|
|
{
|
|
_log_msg "Warning: %s\\n" "$*"
|
|
}
|
|
|
|
log_begin_msg()
|
|
{
|
|
_log_msg "Begin: %s ... " "$*"
|
|
}
|
|
|
|
log_end_msg()
|
|
{
|
|
_log_msg "done.\\n"
|
|
}
|
|
|
|
panic()
|
|
{
|
|
local console rest IFS
|
|
|
|
if command -v chvt >/dev/null 2>&1; then
|
|
chvt 1
|
|
fi
|
|
|
|
echo "$@"
|
|
|
|
# The panic= parameter implies we should disallow console access
|
|
if [ -n "${panic?}" ]; then
|
|
delay=
|
|
case "${panic?}" in
|
|
-*[![:digit:].]*) # invalid: wait forever
|
|
;;
|
|
-*) # timeout < 0: reboot immediately
|
|
delay=0
|
|
;;
|
|
0 | *[![:digit:].]*) # timeout = 0 or invalid: wait forever
|
|
;;
|
|
*) # timeout > 0: seconds before rebooting
|
|
delay="${panic}"
|
|
;;
|
|
esac
|
|
if [ -n "${delay}" ]; then
|
|
echo "Rebooting automatically due to panic= boot argument"
|
|
sleep "${delay}"
|
|
reboot -f
|
|
else
|
|
echo "Halting automatically due to panic= boot argument"
|
|
halt -f
|
|
fi
|
|
exit # in case reboot fails, force kernel panic
|
|
fi
|
|
|
|
run_scripts /scripts/panic
|
|
|
|
# Try to use setsid, which will enable job control in the shell
|
|
# and paging in more
|
|
if command -v setsid >/dev/null 2>&1; then
|
|
unset IFS
|
|
read -r console rest </proc/consoles
|
|
if [ "${console}" = "tty0" ]; then
|
|
# Need to choose a specific VT
|
|
console="tty1"
|
|
fi
|
|
# We don't have 'setsid -c' so we need to setsid, open
|
|
# the tty, and finally exec an interactive shell
|
|
REASON="$*" PS1='(initramfs) ' setsid sh -c "exec sh -i <>/dev/${console} 1>&0 2>&1"
|
|
else
|
|
REASON="$*" PS1='(initramfs) ' sh -i </dev/console >/dev/console 2>&1
|
|
fi
|
|
}
|
|
|
|
maybe_break()
|
|
{
|
|
case ",${break?}," in
|
|
*,$1,*)
|
|
if [ "$1" = "top" ]; then
|
|
# udev is not yet running, so load keyboard drivers
|
|
if [ "${quiet}" = "y" ]; then
|
|
opts="-q"
|
|
else
|
|
opts="-v"
|
|
fi
|
|
/sbin/modprobe ${opts} -a i8042 atkbd ehci-pci ehci-orion \
|
|
ehci-hcd ohci-hcd ohci-pci uhci-hcd usbhid xhci \
|
|
xhci-pci xhci-hcd
|
|
/sbin/modprobe ${opts} -a simpledrm simplefb framebuffer_coreboot
|
|
sleep 2
|
|
for modalias in /sys/bus/hid/devices/*/modalias; do
|
|
if [ -f "${modalias}" ]; then
|
|
/sbin/modprobe ${opts} -b "$(cat "${modalias}")"
|
|
fi
|
|
done
|
|
fi
|
|
panic "Spawning shell within the initramfs"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# For boot time only; this is overridden at build time in hook-functions
|
|
run_scripts()
|
|
{
|
|
initdir=${1}
|
|
[ ! -d "${initdir}" ] && return
|
|
|
|
shift
|
|
. "${initdir}/ORDER"
|
|
}
|
|
|
|
# Load custom modules first
|
|
load_modules()
|
|
{
|
|
if [ -e /conf/modules ]; then
|
|
while read -r m; do
|
|
# Skip empty lines
|
|
if [ -z "$m" ]; then
|
|
continue
|
|
fi
|
|
# Skip comments - d?ash removes whitespace prefix
|
|
com=$(printf "%.1s" "${m}")
|
|
if [ "$com" = "#" ]; then
|
|
continue
|
|
fi
|
|
# shellcheck disable=SC2086
|
|
/sbin/modprobe $m
|
|
done < /conf/modules
|
|
fi
|
|
}
|
|
|
|
_uptime() {
|
|
local uptime
|
|
uptime="$(cat /proc/uptime)"
|
|
uptime="${uptime%%[. ]*}"
|
|
echo "$uptime"
|
|
}
|
|
|
|
time_elapsed() {
|
|
if [ -z "${starttime-}" ]; then
|
|
log_failure_msg "time_elapsed() called before \$starttime initialized"
|
|
echo 0
|
|
fi
|
|
local delta
|
|
delta="$(_uptime)"
|
|
delta=$((delta - starttime))
|
|
echo "$delta"
|
|
}
|
|
|
|
# lilo compatibility
|
|
parse_numeric() {
|
|
case $1 in
|
|
*:*)
|
|
# Does it match /[0-9]*:[0-9]*/?
|
|
minor=${1#*:}
|
|
major=${1%:*}
|
|
case $major$minor in
|
|
*[!0-9]*)
|
|
# No.
|
|
return
|
|
;;
|
|
esac
|
|
;;
|
|
"" | *[!A-Fa-f0-9]*)
|
|
# "", "/*", etc.
|
|
return
|
|
;;
|
|
*)
|
|
# [A-Fa-f0-9]*
|
|
value=$(( 0x${1} ))
|
|
minor=$(( (value & 0xff) | (value >> 12) & 0xfff00 ))
|
|
major=$(( (value >> 8) & 0xfff ))
|
|
;;
|
|
esac
|
|
|
|
# shellcheck disable=SC2034
|
|
ROOT="/dev/block/${major}:${minor}"
|
|
}
|
|
|
|
# Parameter: device node to check
|
|
# Echos fstype to stdout
|
|
# Return value: indicates if an fs could be recognized
|
|
get_fstype ()
|
|
{
|
|
local FS FSTYPE
|
|
FS="${1}"
|
|
|
|
# blkid has a more complete list of file systems,
|
|
# but fstype is more robust
|
|
FSTYPE="unknown"
|
|
eval "$(fstype "${FS}" 2> /dev/null)"
|
|
if [ "$FSTYPE" = "unknown" ]; then
|
|
FSTYPE=$(blkid -o value -s TYPE "${FS}") || return
|
|
fi
|
|
echo "${FSTYPE}"
|
|
return 0
|
|
}
|
|
|
|
_set_netdev_from_ip_param()
|
|
{
|
|
# If the ip= parameter is present and specifies a device, use
|
|
# that in preference to any device name we already have
|
|
local IFS=:
|
|
set -f
|
|
# shellcheck disable=SC2086
|
|
set -- ${IP-}
|
|
set +f
|
|
if [ -n "${6-}" ]; then
|
|
DEVICE="$6"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
_set_netdev_from_hw_address()
|
|
{
|
|
local want_address="$1"
|
|
local device
|
|
for device in /sys/class/net/*; do
|
|
if [ -f "$device/address" ] &&
|
|
[ "$(cat "$device/address")" = "$want_address" ]; then
|
|
DEVICE="${device##*/}"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
_usable_netdev_exists()
|
|
{
|
|
# Look for a device with IFF_LOOPBACK clear and (IFF_BROADCAST
|
|
# or IFF_POINTTOPOINT) set. This is the same test the kernel
|
|
# and ipconfig apply to find a device.
|
|
local device
|
|
local flags
|
|
for device in /sys/class/net/*; do
|
|
if [ -f "${device}/flags" ]; then
|
|
flags="$(cat "${device}/flags")"
|
|
if [ "$((flags & 8))" -eq 0 ] &&
|
|
[ "$((flags & 0x12))" -ne 0 ]; then
|
|
return 0
|
|
fi
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
_update_ip_param()
|
|
{
|
|
# If the ip= parameter is present, and is a colon-separated list,
|
|
# but does not specify a device, substitute in the device name
|
|
# we have
|
|
local IFS=:
|
|
set -f
|
|
# shellcheck disable=SC2086
|
|
set -- ${IP}
|
|
set +f
|
|
if [ -z "${6-}" ] && [ $# -ge 2 ] && [ -n "${DEVICE-}" ]; then
|
|
IP="$1:$2:$3:$4:$5:${DEVICE}"
|
|
shift 6 || shift $#
|
|
IP="${IP}:$*"
|
|
fi
|
|
}
|
|
|
|
configure_networking()
|
|
{
|
|
local netdev_desc
|
|
|
|
# The order of precedence here is:
|
|
# 1. Device specified by ip= kernel parameter
|
|
# 2. Device matching MAC specified by BOOTIF= kernel parameter
|
|
# 3. Build-time DEVICE variable
|
|
# In case 2 we only discover the device name while waiting
|
|
# for a device.
|
|
if _set_netdev_from_ip_param; then
|
|
netdev_desc="${DEVICE}"
|
|
elif [ -n "${BOOTIF-}" ]; then
|
|
# pxelinux sets BOOTIF to a value based on the mac address of the
|
|
# network card used to PXE boot
|
|
# pxelinux sets BOOTIF to 01-$mac_address
|
|
|
|
# strip off the leading "01-", which isn't part of the mac
|
|
# address
|
|
temp_mac=${BOOTIF#*-}
|
|
|
|
# convert to typical mac address format by replacing "-" with ":"
|
|
bootif_mac=""
|
|
IFS='-'
|
|
for x in $temp_mac ; do
|
|
if [ -z "$bootif_mac" ]; then
|
|
bootif_mac="$x"
|
|
else
|
|
bootif_mac="$bootif_mac:$x"
|
|
fi
|
|
done
|
|
unset IFS
|
|
|
|
_set_netdev_from_hw_address "${bootif_mac}"
|
|
netdev_desc="device with address ${bootif_mac}"
|
|
elif [ -n "${DEVICE-}" ]; then
|
|
netdev_desc="${DEVICE}"
|
|
else
|
|
netdev_desc="any network device"
|
|
fi
|
|
|
|
# networking already configured thus bail out
|
|
[ -n "${DEVICE-}" ] && [ -e /run/net-"${DEVICE}".conf ] && return 0
|
|
|
|
local netdevwait=180
|
|
log_begin_msg "Waiting up to ${netdevwait} secs for ${netdev_desc} to become available"
|
|
while true; do
|
|
if [ "$(time_elapsed)" -ge "$netdevwait" ]; then
|
|
log_failure_msg "Network device did not appear in time"
|
|
break
|
|
fi
|
|
if [ -n "${DEVICE-}" ]; then
|
|
[ -e "/sys/class/net/${DEVICE}" ] && break
|
|
elif [ -n "${bootif_mac-}" ]; then
|
|
_set_netdev_from_hw_address "${bootif_mac}" && break
|
|
else
|
|
_usable_netdev_exists && break
|
|
fi
|
|
sleep 1
|
|
done
|
|
log_end_msg
|
|
|
|
_update_ip_param
|
|
|
|
wait_for_udev 10
|
|
|
|
# support ip options see linux sources
|
|
# Documentation/filesystems/nfs/nfsroot.txt
|
|
# Documentation/frv/booting.txt
|
|
|
|
for ROUNDTTT in 2 3 4 6 9 16 25 36 64 100; do
|
|
|
|
# The NIC is to be configured if this file does not exist.
|
|
# Ip-Config tries to create this file and when it succeds
|
|
# creating the file, ipconfig is not run again.
|
|
for x in /run/net-"${DEVICE-}".conf /run/net-*.conf ; do
|
|
[ -e "$x" ] && break 2
|
|
done
|
|
|
|
case "${IP-}" in
|
|
none|off)
|
|
# Do nothing
|
|
;;
|
|
""|on|any)
|
|
# Bring up device
|
|
ipconfig -t ${ROUNDTTT} "${DEVICE}"
|
|
;;
|
|
dhcp|bootp|rarp|both)
|
|
ipconfig -t ${ROUNDTTT} -c "${IP}" -d "${DEVICE}"
|
|
;;
|
|
*)
|
|
ipconfig -t ${ROUNDTTT} -d "$IP"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# source ipconfig output (first try specific bootdevice, then any
|
|
# interface...). ipconfig should have quit after first response
|
|
local file
|
|
for file in "/run/net-${DEVICE-}.conf" /run/net-*.conf; do
|
|
if [ -e "$file" ]; then
|
|
. "$file"
|
|
break
|
|
fi
|
|
done
|
|
|
|
netinfo_to_resolv_conf /etc/resolv.conf "/run/net-${DEVICE-}.conf" /run/net-*.conf
|
|
|
|
if test -n "${HOSTNAME-}"; then
|
|
persist_hostname "${HOSTNAME}" "${DNSDOMAIN-}"
|
|
fi
|
|
}
|
|
|
|
# Write resolv.conf from /run/net-<device> style files.
|
|
# $1=resolv.conf path (print to stdout if "-" is specified)
|
|
# remaining parameters: /run/net-<device> style files
|
|
netinfo_to_resolv_conf()
|
|
{
|
|
local domain="" n="" nameservers="" net_file="" resolv_conf="" search="" output="$1" CR="
|
|
"
|
|
shift
|
|
|
|
for net_file in "$@"; do
|
|
# Define sourced variables as local to avoid causing side effects.
|
|
# shellcheck disable=SC2034
|
|
local DEVICE="" PROTO="" IPV4ADDR="" IPV4BROADCAST="" IPV4NETMASK="" IPV4ROUTE0SUBNET="" \
|
|
IPV4ROUTE0GATEWAY="" IPV4ROUTE1SUBNET="" IPV4ROUTE1GATEWAY="" IPV4GATEWAY="" \
|
|
IPV4DNS0="" IPV4DNS1="" HOSTNAME="" DNSDOMAIN="" NISDOMAIN="" ROOTSERVER="" ROOTPATH="" \
|
|
filename="" UPTIME="" DHCPLEASETIME="" DOMAINSEARCH=""
|
|
[ -e "$net_file" ] || continue
|
|
. "$net_file" || { echo "Error: Failed to source $net_file" >&2; return 1; }
|
|
if test -n "${DNSDOMAIN}"; then
|
|
domain="${DNSDOMAIN}"
|
|
fi
|
|
for n in "${IPV4DNS0}" "${IPV4DNS1}"; do
|
|
if test -z "$n" -o "$n" = 0.0.0.0; then
|
|
continue
|
|
fi
|
|
# Remove duplicates
|
|
case " ${nameservers} " in
|
|
*\ $n\ *)
|
|
continue ;;
|
|
esac
|
|
nameservers="${nameservers} ${n}"
|
|
done
|
|
for n in ${DOMAINSEARCH}; do
|
|
[ -n "$n" ] || continue
|
|
# Remove duplicates
|
|
case " ${search} " in
|
|
*\ $n\ *)
|
|
continue ;;
|
|
esac
|
|
search="${search} ${n}"
|
|
done
|
|
done
|
|
|
|
# Construct content for resolv.conf
|
|
if test -n "${domain}"; then
|
|
resolv_conf="${resolv_conf}domain ${domain}${CR}"
|
|
fi
|
|
for n in ${nameservers}; do
|
|
resolv_conf="${resolv_conf}nameserver $n${CR}"
|
|
done
|
|
if test -n "${search}"; then
|
|
resolv_conf="${resolv_conf}search ${search# }${CR}"
|
|
fi
|
|
|
|
if test -z "$resolv_conf"; then
|
|
echo "no search or nameservers found in $*" 1>&2
|
|
return
|
|
fi
|
|
if test "$output" = "-"; then
|
|
printf "%s" "$resolv_conf"
|
|
else
|
|
printf "%s" "$resolv_conf" > "$output"
|
|
fi
|
|
}
|
|
|
|
_generate_hosts_content()
|
|
{
|
|
local hostname="$1"
|
|
local domain="$2"
|
|
local fqdn
|
|
|
|
if test -n "${domain}"; then
|
|
fqdn="${hostname}.${domain} "
|
|
else
|
|
fqdn=""
|
|
fi
|
|
cat <<EOF
|
|
127.0.0.1 localhost
|
|
127.0.1.1 ${fqdn}${hostname}
|
|
|
|
# The following lines are desirable for IPv6 capable hosts
|
|
::1 localhost ip6-localhost ip6-loopback
|
|
ff02::1 ip6-allnodes
|
|
ff02::2 ip6-allrouters
|
|
EOF
|
|
}
|
|
|
|
# Write hostname into /etc/hostname and /etc/hosts
|
|
# $1=hostname
|
|
# $2=domain (optional)
|
|
persist_hostname()
|
|
{
|
|
local hostname="$1"
|
|
local domain="${2-}"
|
|
|
|
echo "$hostname" > /etc/hostname
|
|
echo "$hostname" > /proc/sys/kernel/hostname
|
|
_generate_hosts_content "$hostname" "$domain" > /etc/hosts
|
|
}
|
|
|
|
# Wait for queued kernel/udev events
|
|
wait_for_udev()
|
|
{
|
|
command -v udevadm >/dev/null 2>&1 || return 0
|
|
udevadm settle ${1:+--timeout=$1}
|
|
}
|
|
|
|
# Find a specific fstab entry
|
|
# $1=mountpoint
|
|
# $2=fstype (optional)
|
|
# returns 0 on success, 1 on failure (not found or no fstab)
|
|
read_fstab_entry() {
|
|
# Not found by default.
|
|
found=1
|
|
|
|
for file in ${rootmnt?}/etc/fstab; do
|
|
if [ -f "$file" ]; then
|
|
# shellcheck disable=SC2034
|
|
while read -r MNT_FSNAME MNT_DIR MNT_TYPE MNT_OPTS MNT_FREQ MNT_PASS MNT_JUNK; do
|
|
case "$MNT_FSNAME" in
|
|
""|\#*)
|
|
continue;
|
|
;;
|
|
esac
|
|
if [ "$MNT_DIR" = "$1" ]; then
|
|
if [ -n "${2-}" ]; then
|
|
[ "$MNT_TYPE" = "$2" ] || continue;
|
|
fi
|
|
found=0
|
|
break 2
|
|
fi
|
|
done < "$file"
|
|
fi
|
|
done
|
|
|
|
return $found
|
|
}
|
|
|
|
# Resolve device node from a name. This expands any LABEL or UUID.
|
|
# $1=name
|
|
# Resolved name is echoed.
|
|
resolve_device() {
|
|
DEV="$1"
|
|
|
|
case "$DEV" in
|
|
LABEL=* | UUID=* | PARTLABEL=* | PARTUUID=*)
|
|
DEV="$(blkid -l -t "$DEV" -o device)" || return 1
|
|
;;
|
|
esac
|
|
[ -e "$DEV" ] && echo "$DEV"
|
|
}
|
|
|
|
# Check a file system.
|
|
# $1=device
|
|
# $2=mountpoint (for diagnostics only)
|
|
# $3=type (may be "auto")
|
|
_checkfs_once()
|
|
{
|
|
DEV="$1"
|
|
NAME="$2"
|
|
TYPE="$3"
|
|
if [ "$NAME" = "/" ] ; then
|
|
NAME="root"
|
|
fi
|
|
FSCK_LOGFILE=/run/initramfs/fsck.log
|
|
FSCK_STAMPFILE=/run/initramfs/fsck-${NAME#/}
|
|
|
|
if [ "${TYPE}" = "auto" ]; then
|
|
TYPE="$(get_fstype "${DEV}")"
|
|
fi
|
|
|
|
FSCKCODE=0
|
|
if [ -z "${TYPE}" ]; then
|
|
log_warning_msg "Type of $NAME file system is unknown, so skipping check."
|
|
return
|
|
fi
|
|
if ! command -v fsck >/dev/null 2>&1; then
|
|
log_warning_msg "fsck not present, so skipping $NAME file system"
|
|
return
|
|
fi
|
|
if [ "${fastboot?}" = "y" ] ; then
|
|
log_warning_msg "Fast boot enabled, so skipping $NAME file system check."
|
|
return
|
|
fi
|
|
|
|
if [ "${forcefsck?}" = "y" ]
|
|
then
|
|
force="-f"
|
|
else
|
|
force=""
|
|
fi
|
|
|
|
if [ "${fsckfix?}" = "y" ]
|
|
then
|
|
fix="-y"
|
|
elif [ "${fsckfix?}" = "n" ]
|
|
then
|
|
fix="-n"
|
|
else
|
|
fix="-a"
|
|
fi
|
|
|
|
spinner=""
|
|
if [ -z "${debug?}" ]; then
|
|
spinner="-C"
|
|
fi
|
|
|
|
if [ "${quiet}" = n ]
|
|
then
|
|
log_begin_msg "Will now check $NAME file system"
|
|
logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -V -t "$TYPE" "$DEV"
|
|
FSCKCODE=$?
|
|
log_end_msg
|
|
else
|
|
log_begin_msg "Checking $NAME file system"
|
|
logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -T -t "$TYPE" "$DEV"
|
|
FSCKCODE=$?
|
|
log_end_msg
|
|
fi
|
|
|
|
# NOTE: "failure" is defined as exiting with a return code of
|
|
# 4, possibly or-ed with other flags. A return code of 1
|
|
# indicates that file system errors were corrected but that
|
|
# the boot may proceed.
|
|
#
|
|
if [ "$FSCKCODE" -eq 32 ]
|
|
then
|
|
log_warning_msg "File system check was interrupted by user"
|
|
elif [ $((FSCKCODE & 4)) -eq 4 ]
|
|
then
|
|
log_failure_msg "File system check of the $NAME filesystem failed"
|
|
return 1
|
|
elif [ "$FSCKCODE" -gt 1 ]
|
|
then
|
|
log_warning_msg "File system check failed but did not detect errors"
|
|
sleep 5
|
|
else
|
|
true >"$FSCK_STAMPFILE"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
checkfs()
|
|
{
|
|
while ! _checkfs_once "$@"; do
|
|
panic "The $2 filesystem on $1 requires a manual fsck"
|
|
done
|
|
}
|
|
|
|
# Mount a file system. We parse the information from the fstab. This
|
|
# should be overridden by any boot script which can mount arbitrary
|
|
# filesystems such as /usr. This default implementation delegates to
|
|
# local or nfs based upon the filesystem type.
|
|
# $1=mountpoint mount location
|
|
mountfs()
|
|
{
|
|
type=local
|
|
read_fstab_entry "$1"
|
|
if [ "${MNT_TYPE}" = "nfs" ] || [ "${MNT_TYPE}" = "nfs4" ]; then
|
|
type=nfs
|
|
fi
|
|
|
|
${type}_mount_fs "$1"
|
|
}
|
|
|
|
# Filter matching items out of a comma-separated list.
|
|
# $1=list
|
|
# $2=pattern to match (may include shell wildcards)
|
|
list_filter_out()
|
|
{
|
|
local pattern="$2"
|
|
local item result
|
|
local IFS=,
|
|
set -f
|
|
# shellcheck disable=SC2086
|
|
set -- $1
|
|
set +f
|
|
for item in "$@"; do
|
|
# shellcheck disable=SC2254
|
|
case "$item" in
|
|
$pattern)
|
|
;;
|
|
*)
|
|
result="${result:+$result,}${item}"
|
|
;;
|
|
esac
|
|
done
|
|
echo "$result"
|
|
}
|
|
|
|
# Mount the root file system. It should be overridden by all
|
|
# boot scripts.
|
|
mountroot()
|
|
{
|
|
:
|
|
}
|
|
|
|
# Run /scripts/${boot}-top. This should be overridden by all boot
|
|
# scripts.
|
|
mount_top()
|
|
{
|
|
:
|
|
}
|
|
|
|
# Run /scripts/${boot}-premount. This should be overridden by all boot
|
|
# scripts.
|
|
mount_premount()
|
|
{
|
|
:
|
|
}
|
|
|
|
# Run /scripts/${boot}-bottom. This should be overridden by all boot
|
|
# scripts.
|
|
mount_bottom()
|
|
{
|
|
:
|
|
}
|