Вопрос или проблема
Я бы хотел загружать некоторые дополнительные модули при запуске.
Это отлично работает из командной строки:
modprobe -a i2c-dev
modprobe -a snd-soc-pcm512x
modprobe -a snd-soc-wm8804
Но я хочу, чтобы это выполнялось при запуске. Я пробовал создавать /etc/modules
, /etc/modprobe.conf
и /etc/modprobe.d/i2c-dev.conf
и т.д. с именем модуля, но безуспешно.
Я использую buildroot-2017-08, который, как я полагаю, использует kmod, с инициализацией BusyBox.
Я могу просто создать скрипт init.d, но думаю, что существует конкретное место, где должен находиться список модулей для загрузки.
Это зависит от того, какую систему инициализации вы используете. Если у вас Buildroot настроен на использование Busybox init или SysV init, то правильный способ решения этой задачи, вероятно, через инициализационный скрипт. Однако, если он настроен на использование Systemd, вы можете просто поместить файл с расширением .conf
в /etc/modules-load.d/
или /usr/lib/modules-load.d/
с каждым модулем, который вы хотите загрузить, указав его на отдельной строке, и systemd загрузит их при запуске.
Не удалось найти много готовых и отточенных скриптов. Оказалось, что в Linux From Scratch (LFS) есть скрипты, которые выглядят хорошо и просты в использовании.
Мое решение для загрузки модулей для простой инициализации BusyBox:
/etc/init.d/S02modules
#!/bin/sh
########################################################################
#
# Описание: Скрипт автозагрузки модулей
#
# Авторы: Зак Уинклс
#
# Версия: 00.00
#
# Примечания:
#
########################################################################
. /etc/sysconfig/functions
# Убедитесь, что ядро поддерживает модули.
[ -e /proc/ksyms -o -e /proc/modules ] || exit 0
case "${1}" in
start)
# Выйти, если нет файла модулей или нет
# допустимых записей
[ -r /etc/sysconfig/modules ] &&
egrep -qv '^($|#)' /etc/sysconfig/modules ||
exit 0
boot_mesg -n "Загрузка модулей:" ${INFO}
# Пытаться загружать модули только если пользователь
# действительно указал модули для загрузки.
while read module args; do
# Игнорировать комментарии и пустые строки.
case "$module" in
""|"#"*) continue ;;
esac
# Пытаться загрузить модуль,
# передавая любые предоставленные аргументы.
modprobe ${module} ${args} >/dev/null
# Печатать имя модуля в случае успеха,
# в противном случае отметить.
if [ $? -eq 0 ]; then
boot_mesg -n " ${module}" ${NORMAL}
else
failedmod="${failedmod} ${module}"
fi
done < /etc/sysconfig/modules
boot_mesg "" ${NORMAL}
# Печатает сообщение об успешно загруженных
# модулях на правильной строке.
echo_ok
# Печатает сообщение о сбое
# с перечнем модулей, которые могли не загрузиться.
if [ -n "${failedmod}" ]; then
boot_mesg "Не удалось загрузить модули:${failedmod}" ${FAILURE}
echo_failure
fi
;;
*)
echo "Использование: ${0} {start}"
exit 1
;;
esac
Основано на этом скрипте LFS:
http://www.linuxfromscratch.org/lfs/view/6.5/scripts/apds05.html
/etc/sysconfig/functions
#!/bin/sh
#######################################################################
#
# Описание: Функции управления уровнем запуска
#
# Авторы: Джерард Бикманс - [email protected]
#
# Версия: 00.00
#
# Примечания: Код основан на простоинициализации Матиаса Бенкманна
# http://winterdrache.de/linux/newboot/index.html
#
########################################################################
## Настройка среды
# Установить значения по умолчанию для окружающей среды
umask 022
export PATH="/bin:/usr/bin:/sbin:/usr/sbin"
# Сигнал, отправляемый работающим процессам для обновления их конфигурации
RELOADSIG="HUP"
# Количество секунд между STOPSIG и FALLBACK при остановке процессов
KILLDELAY="3"
## Размеры экрана
# Найти текущий размер экрана
if [ -z "${COLUMNS}" ]; then
COLUMNS=$(stty size)
COLUMNS=${COLUMNS##* }
fi
# При использовании удаленных соединений, таких как последовательный порт, stty size возвращает 0
if [ "${COLUMNS}" = "0" ]; then
COLUMNS=80
fi
## Измерения для позиционирования сообщений о результатах
COL=$((${COLUMNS} - 8))
WCOL=$((${COL} - 2))
## Предоставить echo, который поддерживает -e и -n
# Если требуется форматирование, следует использовать $ECHO
case "`echo -e -n test`" in
-[en]*)
ECHO=/bin/echo
;;
*)
ECHO=echo
;;
esac
## Установить команды позиции курсора, используемые через $ECHO
SET_COL="\\033[${COL}G" # на символе $COL
SET_WCOL="\\033[${WCOL}G" # на символе $WCOL
CURS_UP="\\033[1A\\033[0G" # На одну строку вверх, на нулевую позицию символа
## Установить команды цвета, используемые через $ECHO
# Пожалуйста, обратитесь к `man console_codes для получения дополнительной информации
# в разделе "ECMA-48 Set Graphics Rendition"
#
# Внимание: при переключении с 8-битного на 9-битный шрифт,
# консоль Linux интерпретирует жирные (1;) в верхние 256 глифов 9-битного шрифта.
# Это не влияет на консоли с фреймбуфером
NORMAL="\\033[0;39m" # Стандартный серый цвет консоли
SUCCESS="\\033[1;32m" # Успех обозначается зеленым
WARNING="\\033[1;33m" # Предупреждения желтые
FAILURE="\\033[1;31m" # Ошибки обозначаются красным
INFO="\\033[1;36m" # Информация отображается светло-голубым
BRACKET="\\033[1;34m" # Скобки синие
STRING_LENGTH="0" # длина текущего сообщения
#*******************************************************************************
# Функция - boot_mesg()
#
# Назначение: Отправка информации из скриптов загрузки в консоль
#
# Входные данные: $1 - это сообщение
# $2 - код цвета для консоли
#
# Выходные данные: Стандартный выход
#
# Зависимости: - sed для разборки строк.
# - grep для подсчета длины строки.
#
# Задача:
#*******************************************************************************
boot_mesg()
{
local ECHOPARM=""
while true
do
case "${1}" in
-н)
ECHOPARM=" -n "
shift 1
;;
-*)
echo "Неизвестный параметр: ${1}"
return 1
;;
*)
break
;;
esac
done
## Вычислить длину того, что должно быть напечатано,
## для использования в сообщениях с предупреждением.
STRING_LENGTH=$((${#1} + 1))
# Вывести сообщение на экран
${ECHO} ${ECHOPARM} -e "${2}${1}"
}
boot_mesg_flush()
{
# Сбросить STRING_LENGTH для следующего сообщения
STRING_LENGTH="0"
}
echo_ok()
{
${ECHO} -n -e "${CURS_UP}${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]"
${ECHO} -e "${NORMAL}"
boot_mesg_flush
}
echo_failure()
{
${ECHO} -n -e "${CURS_UP}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]"
${ECHO} -e "${NORMAL}"
boot_mesg_flush
}
echo_warning()
{
${ECHO} -n -e "${CURS_UP}${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]"
${ECHO} -e "${NORMAL}"
boot_mesg_flush
}
Основано на этом скрипте LFS:
http://www.linuxfromscratch.org/lfs/view/6.5/scripts/apds02.html
/etc/sysconfig/modules
i2c-dev
snd-soc-pcm512x
snd-soc-wm8804
snd-soc-hifiberry_dac
(или любой модуль, который вы хотите загрузить, очевидно)
Если возникнут какие-либо проблемы или сложности с загрузкой модулей таким образом в BusyBox init, я уверен, что они появятся в комментариях ниже ;-).
Отличный ответ от @svenema! Я только хотел бы добавить, что мне пришлось изменить права доступа и сделать файл S02modules
исполняемым, чтобы это работало:
chmod u+x /etc/init.d/S02modules
.
Ответ или решение
Вопрос касается автоматической загрузки модулей в системе, использующей Buildroot и инициализацию через BusyBox. В данном случае, требуется обеспечить автоматическую загрузку определённых модулей ядра при старте системы, что в некоторых ситуациях может быть критически важным для функционирования специфичного оборудования или обеспечения определённых функций системы.
Теоретическая основа
Когда операционная система загружается, она может потребовать загрузку различных модулей, которые обычно управляются через команду modprobe
. Эти модули могут касаться драйверов устройств, файловых систем, сетевых протоколов и многого другого. Чтобы не загружать каждый модуль вручную после старта системы, существует возможность автоматизировать процесс, создавая скрипты или конфигурации, которые помогут при инициализации.
В системе, использующей BusyBox для инициализации, возможности автоматической конфигурации ограничены в сравнении с более сложными системами инициализации, такими как Systemd. Тем не менее, есть решения для управления модулями при старте системы.
Пример практического решения
Рассмотрим предложенное решение из вашего описания. Был использован скрипт инициализации /etc/init.d/S02modules
, который дублирует логическое поведение более сложных систем, но адаптирован для работы с BusyBox. Этот скрипт проверяет доступность модулей и загружает их непосредственно при старте системы, используя информацию из файла конфигурации /etc/sysconfig/modules
.
Вот краткое пояснение к коду скрипта:
-
Инициализация и проверка условий: В начале проверяется наличие необходимых структур в
/proc
, что указывает на поддержку модулей ядра. Без этого скрипт завершит свою работу. -
Чтение конфигурации: Из файла
/etc/sysconfig/modules
берутся имена модулей и их аргументы, после чего они итеративно загружаются. -
Загрузка модулей: Сначала игнорируются пустые строки и комментарии, после чего каждый модуль загружается с помощью
modprobe
. В случае успешной загрузки выводится позитивное подтверждение. -
Обработка ошибок: Если модуль не удалось загрузить, информация об ошибке выводится пользователю.
Применение в вашем контексте
Чтобы применить это решение, скопируйте указанный скрипт в директорию /etc/init.d/
, убедитесь, что он имеет разрешение на выполнение, используя команду chmod u+x /etc/init.d/S02modules
. Затем создайте или отредактируйте файл /etc/sysconfig/modules
, добавив туда необходимые модули, например:
i2c-dev
snd-soc-pcm512x
snd-soc-wm8804
snd-soc-hifiberry_dac
Этот метод обеспечивает гибкость и лёгкость в управлении модулями, поскольку позволит вам легко добавлять или удалять модули без изменения всего процесса инициализации системы.
Заключение
Автоматическая загрузка модулей посредством скрипта представляет собой подходящий компромисс между функциональностью и простотой реализации для систем, использующих BusyBox и Buildroot. Это решение позволяет избежать ручной работы с модулями после каждого перезапуска системы, что может значительно облегчить настройку и эксплуатацию системы. Учитывая особенности вашей системы и требований к модульной поддержке, описанный метод можно считать оптимальным и эффективным. Это позволит управлять интеграцией низкоуровневых компонентов и сервисов вашего устройства с минимальными затратами на администрирование, сохраняя при этом гибкость в процессе конфигурирования системы.