В Linux используется специальное средство загрузки под названием SysVinit, основанное на концепции уровней выполнения (run-levels). Его настройка может сильно отличаться от одной системы к другой, и корректная работа в одном дистрибутиве Linux, не гарантирует работоспособность в LFS. LFS работает по-своему, но соблюдает общепринятые стандарты.
SysVinit (в дальнейшем именуемый «init») работает по схеме уровней выполнения.
Существует семь (пронумерованных от 0 до 6) уровней выполнения (на
самом деле уровней больше, но они предназначены для особых случаев
и обычно не используются. Подробности смотрите в руководстве
init(8)
), и каждый из них
соответствует действиям, которые компьютер должен выполнить при
запуске. Уровень выполнения по умолчанию — 3. Ниже приведены
описания различных уровней в том виде, в каком они реализованы в
LFS:
0: выключение компьютера
1: однопользовательский режим
2: зарезервировано для настройки, в остальном аналогично 3
3: многопользовательский режим с поддержкой сети
4: зарезервировано для настройки, в остальном аналогично 3
5: то же, что и 4, обычно используется для входа в систему с графическим интерфейсом (например,
gdm от GNOME или lxdm от LXDE)
6: перезагрузка компьютера
Раньше, много лет назад, уровень выполнения 2 обозначался как "многопользовательский режим без поддержки сети", тогда несколько пользователей могли войти в систему, подключившись через последовательные порты. В сегодняшних условиях это не имеет смысла, и мы обозначаем этот уровень как "зарезервировано".
Во время инициализации ядра первая запущенная программа указывается
либо в командной строке, либо по умолчанию в init. Эта программа читает файл
инициализации /etc/inittab
. Создайте
этот файл:
cat > /etc/inittab << "EOF"
# Begin /etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/init.d/rc S
l0:0:wait:/etc/rc.d/init.d/rc 0
l1:S1:wait:/etc/rc.d/init.d/rc 1
l2:2:wait:/etc/rc.d/init.d/rc 2
l3:3:wait:/etc/rc.d/init.d/rc 3
l4:4:wait:/etc/rc.d/init.d/rc 4
l5:5:wait:/etc/rc.d/init.d/rc 5
l6:6:wait:/etc/rc.d/init.d/rc 6
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
su:S06:once:/sbin/sulogin
s1:1:respawn:/sbin/sulogin
1:2345:respawn:/sbin/agetty --noclear tty1 9600
2:2345:respawn:/sbin/agetty tty2 9600
3:2345:respawn:/sbin/agetty tty3 9600
4:2345:respawn:/sbin/agetty tty4 9600
5:2345:respawn:/sbin/agetty tty5 9600
6:2345:respawn:/sbin/agetty tty6 9600
# End /etc/inittab
EOF
Пояснения по содержимому этого файла инициализации находится на
справочной странице inittab.
Для LFS ключевой командой является rc. В приведенном выше файле
инициализации, rc
будет выполнять все сценарии, начинающиеся с символа S в каталоге
/etc/rc.d/rcS.d
, за которыми следуют
все скрипты, начинающиеся с S в каталоге /etc/rc.d/rc?.d
, где знак вопроса задается
значением initdefault.
Для удобства, скрипт rc читает функции из библиотеки
/lib/lsb/init-functions
. Эта
библиотека также читает необязательный файл конфигурации
/etc/sysconfig/rc.site
. Любой из
параметров файла конфигурации системы, описанный в последующих
разделах, можно поместить в этот файл, что позволит объединить все
системные параметры в одном файле.
Для удобства отладки скрипт functions также записывает весь вывод в
/run/var/bootlog
. Поскольку каталог
/run
является tmpfs, этого файла
может не быть при загрузке, однако его содержимое добавляется к
файлу /var/log/boot.log
по окончании
процесса загрузки.
Изменить уровень выполнения можно с помощью команды init <runlevel>
,
где <runlevel>
-
это целевой уровнем выполнения. Например, чтобы перезагрузить
компьютер, пользователь должен выполнить команду init 6, которая является
псевдонимом для команды reboot. Аналогично, init 0
является псевдонимом для команды halt.
В каталоге /etc/rc.d
есть ещё
несколько каталогов, которые выглядят как rc?.d
(где ? - номер уровня выполнения), все
они содержат ряд символических ссылок. Некоторые начинаются с
K, другие начинаются с
S, и все они содержат две
цифры после начальной буквы. K означает остановить (убить)
службу, а S означает запустить службу. Числа определяют порядок
выполнения сценариев от 00 до 99—чем меньше число, тем раньше он
запустится. Когда init переключается на другой
уровень выполнения, соответствующие службы запускаются или
останавливаются в зависимости от выбранного уровня.
Реальные скрипты находятся в каталоге /etc/rc.d/init.d
. Они выполняют фактическую
работу, и символические ссылки указывают на них. Ссылки К и S
указывают на один и тот же скрипт в /etc/rc.d/init.d
. Это связано с тем, что
скрипты могут вызываться с разными параметрами, такими как
start
, stop
, restart
, reload
, и status
. Когда встречается ссылка K,
соответствующий скрипт запускается с аргументом stop
. Когда встречается S-ссылка,
соответствующий скрипт запускается с аргументом start
.
Ниже приведено описание к аргументам скриптов:
start
Служба запущена.
stop
Служба остановлена.
restart
Служба остановлена и снова запущена.
reload
Конфигурация сервиса обновлена. Используется после изменения файла конфигурации службы, когда перезапуск не требуется.
status
Сообщает, запущена ли служба и с какими ИД процессов.
Не стесняйтесь изменять работу процесса загрузки (в конце концов, это ваша собственная система LFS). Приведенные здесь файлы являются примером того, как это можно сделать.
Инит-скрипт /etc/rc.d/init.d/udev
запускает udevd,
который инициализирует все устройства "холодного подключения",
которые уже были созданы ядром, и ожидает выполнения всех правил.
Скрипт также отключает обработчик uevent по умолчанию /sbin/hotplug
. Это сделано потому, что ядру
больше не нужно обращаться к внешнему бинарному файлу. Вместо этого
udevd будет
прослушивать сокет netlink для событий uevents, которые вызывает
ядро.
Инит-скрипт /etc/rc.d/init.d/udev_retry
решает задачу повторного запуска событий для подсистем, правила
которых могут зависеть от файловых систем, которые не монтируются
до запуска скрипта mountfs (в частности, его
вызывают /usr
и /var
). Этот скрипт запускается после скрипта
mountfs, поэтому
правила (при повторном запуске) должны выполняться успешно. Он
настраивается из файла /etc/sysconfig/udev_retry
; любые слова в этом
файле, кроме комментариев, являются именами подсистем, которые
могут выполняться повторно. Чтобы найти подсистему устройства,
используйте udevadm info
--attribute-walk <device>, где <device>
- это абсолютный путь в /dev или /sys, такой как /dev/sr0 или
/sys/class/rtc.
Для получения информации о загрузке модуля ядра и udev смотрите Раздел 9.3.2.3, «Загрузка модуля».
Скрипт setclock
считывает время с аппаратных часов, также известных как часы BIOS
или CMOS (Complementary Metal Oxide Semiconductor). Если на
аппаратных часах установлено время UTC (всемирное скоординированное
время), этот скрипт преобразует полученное значение в локальное
время, используя файл /etc/localtime
(который сообщает программе hwclock, в какой временной зоне
находится пользователь). Невозможно определить, установлено на
аппаратных часах UTC или же локальное время, поэтому необходимо
указать его вручную.
Скрипт setclock запускается системой udev при загрузке, когда ядро определяет возможности аппаратного обеспечения. Также его можно запустить вручную с параметром stop, чтобы сохранить системное время в аппаратные часы CMOS.
Если Вы не можете вспомнить, установлено на аппаратных часах UTC
или локальное время, запустите команду hwclock --localtime --show
. Она
отобразит текущее время в соответствии с аппаратными часами. Если
оно совпадает с тем, что показывают ваши настенные/наручные часы,
значит на часах CMOS установлено локальное время. Если вывод
hwclock не совпадает
с локальным временем, скорее всего, это UTC. Проверьте это,
добавляя или вычитая правильное смещение к времени, выводимому
hwclock. Например,
если ваш часовй пояс это MSK, так же известный как GMT +0300, то
нужно вычесть три часа из локального времени.
Измените значение переменной UTC
ниже на
0
(ноль), если на
аппаратных часах установлено НЕ UTC.
Создайте новый файл /etc/sysconfig/clock
выполнив:
cat > /etc/sysconfig/clock << "EOF"
# Begin /etc/sysconfig/clock
UTC=1
# Set this to any options you might need to give to hwclock,
# such as machine hardware clock type for Alphas.
CLOCKPARAMS=
# End /etc/sysconfig/clock
EOF
Хороший совет, объясняющий, как обращаться с временем в LFS,
доступен по адресу
https://mirror.linuxfromscratch.ru/hints/downloads/files/time.txt.
Там объясняются такие вопросы, как часовые пояса, UTC и переменная
окружения TZ
.
Параметры CLOCKPARAMS и UTC также могут быть указаны в файле
/etc/sysconfig/rc.site
.
Эта секция описывает настройку скрипта console, который устанавливает
раскладку клавиатуры, шрифт консоли и уровень подробности
информации, выводимой ядром на консоль. Если Вы не планируете
использовать символы, не соответствующие стандарту ASCII (например,
знак копирайта, символы фунта и евро), и собираетесь печатать
только в английской раскладке, то можете пропустить большую часть
секции. Без файла конфигурации (или эквивалентных настроек в
rc.site
), скрипт console не будет ничего делать.
Скрипт console
считывает конфигурацию из файла /etc/sysconfig/console
. Решите для себя, какую
раскладку клавиатуры и какой шрифт намерены использовать. В этом
также могут помочь различные HOWTO для конкретных языков, смотрите
https://tldp.org/HOWTO/HOWTO-INDEX/other-lang.html.
Если вы все еще сомневаетесь, посмотрите в каталогах /usr/share/keymaps
и /usr/share/consolefonts
допустимые раскладки и
экранные шрифты. Прочтите справочные страницы loadkeys(1)
и setfont(8)
, чтобы определить правильные аргументы
для этих программ.
Файл /etc/sysconfig/console
должен
содержать строки вида: ПЕРЕМЕННАЯ="значение". Допустимы следующие
переменные:
Эта переменная задает уровень подробности сообщений, посылаемых ядром на системную консоль. Значение этой переменной передается в качестве аргумента утилите dmesg -n. Допустимы уровни от "1" (нет сообщений) до "8". По умолчанию "7".
Эта переменная указывает аргументы для программы loadkeys, обычно это имя загружаемой раскладки, например, «it». Если эта переменная не установлена, загрузочный скрипт не будет запускать программу loadkeys, и будет использоваться раскладка по умолчанию. Обратите внимание, что некоторые раскладки имеют несколько версий с одним и тем же именем (cz и его варианты в qwerty/ и qwertz/, es в olpc/ и qwerty/ и trf в fgGIod/ и qwerty/). В этих случаях также следует указать родительский каталог (например, qwerty/es), чтобы обеспечить загрузку правильной раскладки.
Эта (крайне редко используемая) переменная задает аргументы для второго вызова программы loadkeys. Она полезна, если стандартная раскладка вас не совсем устраивает и необходимо внести небольшую корректировку. Например, чтобы добавить символ евро в раскладку, которая его не содержит, присвойте этой переменной значение «euro2».
Эта переменная определяет аргументы для программы setfont. Обычно она включает в себя имя шрифта «-m» и имя загружаемой таблицы символов. Например, чтобы загрузить шрифт «lat1-16» вместе с таблицей символов «8859-1» (подходящий для США), установите эту переменную в «lat1-16 -m 8859-1». В режиме UTF-8 ядро использует таблицу символов для преобразования 8-битных кодов клавиш в раскладку UTF-8, поэтому аргумент параметра "-m" должен быть указывать кодировку таблицы символов в раскладке.
Присвойте этой переменной значение «1», «yes» или «true», чтобы переключить консоль в режим UTF-8. Это полезно при использовании локали, основанной на UTF-8, и не рекомендуется в иных случаях.
Для многих раскладок клавиатуры в пакете Kbd не существует готового Unicode-варианта. Скрипт console будет на лету конвертировать имеющуюся раскладку в UTF-8, если присвоить этой переменной имя доступной не-UTF-8 раскладки.
Несколько примеров:
Для не-Unicode настройки необходимы только переменные KEYMAP и FONT. Например, для польских пользователей может подойти такой вариант:
cat > /etc/sysconfig/console << "EOF"
# Begin /etc/sysconfig/console
KEYMAP="pl2"
FONT="lat2a-16 -m 8859-2"
# End /etc/sysconfig/console
EOF
Как упоминалось выше, иногда бывает необходимо подкорректировать раскладку. Следующий пример добавляет символ евро к немецкой раскладке:
cat > /etc/sysconfig/console << "EOF"
# Begin /etc/sysconfig/console
KEYMAP="de-latin1"
KEYMAP_CORRECTIONS="euro2"
FONT="lat0-16 -m 8859-15"
UNICODE="1"
# End /etc/sysconfig/console
EOF
Ниже приведен пример с поддержкой Unicode для болгарского языка, где существует стандартная раскладка UTF-8:
cat > /etc/sysconfig/console << "EOF"
# Begin /etc/sysconfig/console
UNICODE="1"
KEYMAP="bg_bds-utf8"
FONT="LatArCyrHeb-16"
# End /etc/sysconfig/console
EOF
Из-за использования 512-символьного шрифта LatArCyrHeb-16 в предыдущем примере, яркие цвета больше не доступны в консоли Linux, если используется фреймбуфер. Если Вы хотите использовать яркие цвета без фреймбуфера и можете обходиться без символов, не относящихся к вашему языку, тогда можно использовать специфичный для вашего языка 256-символьный шрифт, как показано ниже:
cat > /etc/sysconfig/console << "EOF"
# Begin /etc/sysconfig/console
UNICODE="1"
KEYMAP="bg_bds-utf8"
FONT="cyr-sun16"
# End /etc/sysconfig/console
EOF
Следующий пример демонстрирует автоматическое преобразование раскладки из ISO-8859-15 в UTF-8 и включает "мертвые" клавиши в режиме Unicode:
cat > /etc/sysconfig/console << "EOF"
# Begin /etc/sysconfig/console
UNICODE="1"
KEYMAP="de-latin1"
KEYMAP_CORRECTIONS="euro2"
LEGACY_CHARSET="iso-8859-15"
FONT="LatArCyrHeb-16 -m 8859-15"
# End /etc/sysconfig/console
EOF
Некоторые раскладки включают в себя "мертвые" клавиши (то есть клавиши, нажатие которых само по себе не приводит к появлению на экране символа, но которые влияют на символ, генерируемый следующей клавишей) или определяют слияние символов (например: «нажмите Ctrl+. A E чтобы получить Æ» в раскладке по умолчанию). Linux-5.19.2 правильно интерпретирует "мертвые" клавиши и слияния, только когда исходные символы имеют 8-битные коды. Эта особенность не влияет на раскладки для европейских языков, поскольку в них "сливаются" два ASCII-символа или добавляются подчеркивания к неподчеркнутым ASCII-символам. Однако, в режиме UTF-8 могут быть проблемы, например, для греческого языка, когда необходимо подчеркнуть символ «alpha». Решением в этой ситуации будет отказ от использования UTF-8 или установка графической системы X Window, не имеющих подобных ограничений.
Для китайского, японского, корейского и некоторых других языков невозможно насторить консоль Linux так, чтобы она отображала все необходимые символы. Пользователи, которым требуются эти языки, должны установить систему X Window, шрифты, покрывающие необходимый диапазон символов, и правильный метод ввода (например, SCIM, он поддерживает большое число разнообразных языков).
Файл /etc/sysconfig/console
управляет только локализацией текстовой консоли Linux. Он никак
не влияет на настройки раскладки клавиатуры и шрифтов в системе X
Window, в сессиях SSH или на последовательном терминале. В этих
ситуациях ограничения, описанные в двух расположенных выше
абзацах, не применяются.
Иногда необходимо создавать файлы во время загрузки. Например,
часто требуется каталог /tmp/.ICE-unix
. Это можно сделать, создав запись
в скрипте /etc/sysconfig/createfiles
.
Формат этого файла описан в комментариях файла конфигурации по
умолчанию.
Скрипт sysklogd
вызывает программу
syslogd как часть
инициализации System V. Параметр -m
0
отключает периодическую (по умолчанию - каждые 20
минут) запись временных меток в файлы журналов, производимую
syslogd. Если Вам
необходимо включить периодическую запись временных меток,
отредактируйте файл /etc/sysconfig/rc.site
и присвойте переменной
SYSKLOGD_PARMS требуемое значение. Например, чтобы сбросить все
параметры, присвойте переменной пустое значение:
SYSKLOGD_PARMS=
Дополнительные параметры смотрите в man syslogd
.
Необязательный файл /etc/sysconfig/rc.site
содержит настройки,
автоматически применяемые всеми загрузочными скриптами. Этот файл
может содержать парамеры, обычно указываемые в файлах hostname
, console
и
clock
из каталога /etc/sysconfig/
. Если значение одной и той же
переменной присваивается и в одном из этих файлов, и в rc.site
, приоритет имеет значение из
специализированного файла.
rc.site
также содержит параметры,
которые могут настраивать другие аспекты процесса загрузки.
Установка переменной IPROMPT позволит выборочно запускать
загрузочные скрипты. Другие параметры описаны в комментариях к
файлу. Версия файла по умолчанию выглядит следующим образом:
# rc.site # Optional parameters for boot scripts. # Distro Information # These values, if specified here, override the defaults #DISTRO="Linux From Scratch" # The distro name #DISTRO_CONTACT="lfs-dev@lists.linuxfromscratch.org" # Bug report address #DISTRO_MINI="LFS" # Short name used in filenames for distro config # Define custom colors used in messages printed to the screen # Please consult `man console_codes` for more information # under the "ECMA-48 Set Graphics Rendition" section # # Warning: when switching from a 8bit to a 9bit font, # the linux console will reinterpret the bold (1;) to # the top 256 glyphs of the 9bit font. This does # not affect framebuffer consoles # These values, if specified here, override the defaults #BRACKET="\\033[1;34m" # Blue #FAILURE="\\033[1;31m" # Red #INFO="\\033[1;36m" # Cyan #NORMAL="\\033[0;39m" # Grey #SUCCESS="\\033[1;32m" # Green #WARNING="\\033[1;33m" # Yellow # Use a colored prefix # These values, if specified here, override the defaults #BMPREFIX=" " #SUCCESS_PREFIX="${SUCCESS} * ${NORMAL} " #FAILURE_PREFIX="${FAILURE}*****${NORMAL} " #WARNING_PREFIX="${WARNING} *** ${NORMAL} " # Manually seet the right edge of message output (characters) # Useful when resetting console font during boot to override # automatic screen width detection #COLUMNS=120 # Interactive startup #IPROMPT="yes" # Whether to display the interactive boot prompt #itime="3" # The amount of time (in seconds) to display the prompt # The total length of the distro welcome string, without escape codes #wlen=$(echo "Welcome to ${DISTRO}" | wc -c ) #welcome_message="Welcome to ${INFO}${DISTRO}${NORMAL}" # The total length of the interactive string, without escape codes #ilen=$(echo "Press 'I' to enter interactive startup" | wc -c ) #i_message="Press '${FAILURE}I${NORMAL}' to enter interactive startup" # Set scripts to skip the file system check on reboot #FASTBOOT=yes # Skip reading from the console #HEADLESS=yes # Write out fsck progress if yes #VERBOSE_FSCK=no # Speed up boot without waiting for settle in udev #OMIT_UDEV_SETTLE=y # Speed up boot without waiting for settle in udev_retry #OMIT_UDEV_RETRY_SETTLE=yes # Skip cleaning /tmp if yes #SKIPTMPCLEAN=no # For setclock #UTC=1 #CLOCKPARAMS= # For consolelog (Note that the default, 7=debug, is noisy) #LOGLEVEL=7 # For network #HOSTNAME=mylfs # Delay between TERM and KILL signals at shutdown #KILLDELAY=3 # Optional sysklogd parameters #SYSKLOGD_PARMS="-m 0" # Console parameters #UNICODE=1 #KEYMAP="de-latin1" #KEYMAP_CORRECTIONS="euro2" #FONT="lat0-16 -m 8859-15" #LEGACY_CHARSET=
Загрузочные скрипты LFS загружают и завершают работу системы
довольно эффективно, но есть несколько настроек, которые вы
можете внести в файл rc.site, чтобы еще больше повысить скорость
и настроить сообщения в соответствии с вашими предпочтениями.
Чтобы сделать это, измените настройки в приведенном выше файле
/etc/sysconfig/rc.site
.
Во время работы загрузочного скрипта udev
происходит вызов udev settle, для
завершения которого требуется некоторое время. Это время
может и не потребоваться в зависимости от конфигурации
устройств в системе. Если у вас имеются только простые
разделы и одна сетевая карта, процессу загрузки, вероятно,
не нужно будет ждать завершения работы этой команды. Чтобы
пропустить её, установите переменную OMIT_UDEV_SETTLE=y.
Скрипт загрузки udev_retry
также по умолчанию запускает udev settle. Команда
требуется только тогда, когда каталог /var
смонтирован в отдельный раздел. Это
связано с тем, что часам нужен доступ к файлу /var/lib/hwclock/adjtime
. Пропустите
команду, установив переменную OMIT_UDEV_RETRY_SETTLE=y.
По умолчанию проверка файловой системы выполняется в "тихом" режиме. Это может показаться задержкой во время процесса загрузки. Чтобы включить вывод fsck, установите переменную VERBOSE_FSCK=y.
При перезагрузке вы, возможно, захотите полностью
пропустить проверку файловой системы, fsck. Чтобы сделать это,
либо создайте файл /fastboot
,
либо перезагрузите систему командой /sbin/shutdown -f -r now.
С другой стороны, вы можете принудительно проверить все
файловые системы, создав /forcefsck
или запустив shutdown с параметром
-F
вместо
-f
.
Установка переменной FASTBOOT=y отключит fsck во время процесса загрузки до тех пор, пока она не будет удалена. Это не рекомендуется делать на постоянной основе.
Обычно все файлы в каталоге /tmp
удаляются во время загрузки. В
зависимости от количества имеющихся файлов или каталогов
это может привести к заметной задержке в процессе загрузки.
Чтобы пропустить удаление этих файлов, установите
переменную SKIPTMPCLEAN=y.
Во время завершения работы, init отправляет сигнал TERM каждой запущенной программе (например, agetty), ожидает установленное время (по умолчанию 3 секунды), посылает каждому процессу сигнал завершения(KILL) и снова ждёт. Этот процесс повторяется в сценарии sendsignals для любых процессов, которые не завершаются их собственными скриптами. Задержка для init может быть установлена путем передачи параметра. Например, чтобы устранить задержку в init, передайте параметр -t0 при выключении или перезагрузке (например, /sbin/shutdown -t0 -r now). Задержку для скрипта sendsignals можно пропустить, установив параметр KILLDELAY=0.