Загрузочные файлы линукс. Этапы загрузки: досистемная загрузка ОС Linux. Загрузчик операционной системы

Нажмите кнопку включения питания на вашем системнике, и спустя несколько секунд вы увидите окно входа в систему.

Посмею предположить, что каждого интересовало хоть когда-либо то, что происходит за занавесом заставок и загрузочных экранов с момента включения питания компьютера к моменту, когда предлагается войти в систему.

Я предлагаю вам познакомиться со следующими уровнями типичной загрузки Linux:

1. BIOS

  • BIOS отвечает за базовый ввод/вывод данных с устройств/на устройства.
  • Делает некоторые проверки целостности устройств. К тому же, за тестирование работоспособности электроники отвечает POST (Power-on self-test, он же «тест на адекватность себя самого», выполняющийся как этап пре-загрузки), который управляется BIOS
  • Ищет, загружает и выполняет программу-загрузчик ОС
  • Берет загрузчик из флопика, сидюка или жесткого диска. Во время загрузки BIOS"а вы можете нажать на кнопку (обычно это F12 или F2 или Del, зависит от платформы), если вам требуется внести некоторые изменения касательно настройки железа.
  • Как только загрузчик был обнаружен и загружен в память, BIOS передает управление ему.
  • Короче говоря, BIOS загружает и выполняет загрузочную запись (MBR).

2. MBR

  • MBR - это главная загрузочная запись, хранящаяся на жестком диске
  • Она размещена в 1-м секторе загрузочного диска, например /dev/hda или /dev/sda
  • MBR занимает меньше, чем 512 байтов. Она состоит из трех компонентов: 1) главная загрузочная информация, «живущая» в первых 446 байтах; 2) информация о таблице разделов - в следующих 64 байтах; 3) и последние 2 байта нужны для проверки корректности mbr.
  • Она содержит информацию о GRUB"е (или LILO).
  • Простыми словами - MBR загружает и выполняет загрузчик GRUB.

3. GRUB

  • GRUB - Grand Unified Bootloader.
  • Если в вашей системе установлено более, чем одно ядро, у вас есть возможность выбирать, которое из них должен выполняться
  • GRUB отображает красивую анимацию plymouth заставку, и, подождав несколько секунд интерактивного воздействия пользователя, если он не нажал ни одной клавиши, он загружает ядро, установленное по умолчанию в файле конфигурации grub.
  • GRUB понимает, что такое файловая система (древние загрузчики Linux"а, например, LILO этого не понимают).
  • Конфигурационный файл Grub обычно лежит по пути /boot/grub/grub.conf (так же /etc/grub.conf может быть символьной ссылкой на него). Вот пример файла конфигурации для CentOS:
    #boot=/dev/sda
    default=0
    timeout=5
    splashimage=(hd0,0)/boot/grub/splash.xpm.gz
    hiddenmenu
    title CentOS (2.6.18-194.el5PAE)
    root (hd0,0)
    kernel /boot/vmlinuz-2.6.18-194.el5PAE ro root=LABEL=/
    initrd /boot/initrd-2.6.18-194.el5PAE.img
  • В качестве примечания к информации выше, конфигурационный файл содержит путь к ядру и образу initrd
  • Если быть кратким, GRUB просто напросто загружает и выполняет образы ядра и initrd.

4. Ядро или Kernel

  • Ядро монтирует файловую систему в соответствии с настройкой «root=» в фале grub.conf
  • Выполняет программу /sbin/init
  • Поскольку init - это первый процесс, запущенный ядром Linux, поэтому она имеет идентификатор процесса (PID) №1. Можете выполнить «ps -ef | grep init» и убедиться в этом.
  • initrd - это Initial RAM Disk, он же временный диск в оперативной памяти
  • initrd используется самим ядром в качестве временной корневой файловой системы, пока kernel не загрузится в реальную примонтированную файловую систему. Этот временный диск также содержит необходимые для загрузки драйверы, позволяющие получить доступ к разделам дисков и другому оборудованию

5. Init

  • Смотрит в файл /etc/inittab для того, чтобы определить уровень выполнения (run level).
  • Есть следующие уровни выполнения:
    • 0 – прервать выполнение
    • 1 – Однопользовательский режим, так называемый «Single user mode», или иными словами, консоль восстановления
    • 2 – Многопользовательский режим без поддержки NFS
    • 3 – Полноценный многопользовательский режим
    • 4 – не используется
  • Init определяет уровень выполнения по умолчанию исходя из /etc/inittab и использует его для загрузки всех необходимых программ.
  • Выполните «grep initdefault /etc/inittab» на вашей системе, и вы узнаете, какой уровень по умолчанию у вас используется
  • Если у вас не получается жить спокойно, то можете установить стандартный уровень на 0 или 6. :)
  • В большинстве случаев вам будет достаточно уровня 3 или 5.

6. Уровень выполнения программ (Runlevel)

  • Когда Линукс выполняет свою загрузку, вы можете наблюдать загрузку различных служб. К примеру, это могут быть сообщения типа «starting Postfix … OK» (запускается Postfix). Эти службы - и называются программами уровня выполнения, выполняемые из директории, которая соответствует нужному уровню выполнения.
  • Исходя из настроек по умолчанию, система будет выполнять файлы в соответствии с нижеприведенными директориями.
    • Выполнение уровня 0 – /etc/rc.d/rc0.d/
    • Выполнение уровня 1 – /etc/rc.d/rc1.d/
    • Выполнение уровня 2 – /etc/rc.d/rc2.d/
    • Выполнение уровня 3 – /etc/rc.d/rc3.d/
    • Выполнение уровня 4 – /etc/rc.d/rc4.d/
    • Выполнение уровня 5 – /etc/rc.d/rc5.d/
    • Выполнение уровня 6 – /etc/rc.d/rc6.d/
  • Но имейте ввиду, что еще в каталоге /etc могут быть символические ссылки. Например, /etc/rc0.d залинкован на /etc/rc.d/rc0.d.
  • В каталогах /etc/rc.d/rc*.d/ вы можете увидеть список программ, имя которых начинается из букв S и K.
  • Программы, начинающиеся на S используются для запуска. S, потому что s tartup.
  • Программы, которые начинаются с литеры K используются - правильно - для завершения работы. K, потому что k ill.
  • Еще есть номера рядом с буквами S и K в именах программ. Эти номера используются для определения порядка запуска этих программ.
  • К примеру, S12syslog предназначен для запуска демона syslog, его порядковый номер 12. S80sendmail - для запуска демона sendmail, имеющего порядковый номер 80. Таким образом, программа syslog будет запущена перед sendmail.

Вот и все. Возможно, некоторым из вас это не ново и особого интереса не было при чтении статью, поскольку она более ориентирована на начально-средний уровень знакомства з Линуксом.
В таком случае могу лишь сказать, что «повторение - мать учения» (с).

Дополнения, исправления, уточнения

В комментариях неоднократно было апеллировано к тексту статьи, поэтому, думаю, стоит учесть некоторые важные комментарии хабрасообщества. (спасибо artemlight , 3al , Tishka17 , HhyperH , Next_Alex , Ilya_Shmelykh , Aux , soomrack , Xpeh)
  • artemlight: : «Ну скажем прямо - так грузятся далеко не все дистры». С ним согласилось большинство, отмечая и bsd-style init, u-boot, и хоть initrd в статье пропущен, стоить заметить, что он нужен ядру не во всех дистрибутивах. Также отмечено, что в slackware поддержка rc.d осуществляется только в качестве совместимости, а встраиваемые системы грузятся иначе. На декстопах иногда бывает EFI, а кроме того Linux популярен в мире embedded и там ещё куча разных платформ. Линукс в телефоне вообще иначе грузится.
  • soomrack , ссылая на википедию: Еще хочется сделать замечание по поводу MBR, первого сектора и пр. Все несколько усложнилось за последние годы. Сейчас уместней говорить о EFI.

    «GUID Partition Table (GPT) является стандартным форматом размещения таблиц разделов на физическом жестком диске. Он является частью Extensible Firmware Interface (EFI) (Расширяемый Микропрограммный Интерфейс) - стандарта, предложенного Intel на смену отжившего BIOS, одного из последних реликтов первозданной IBM PC. EFI использует GPT там, где BIOS использует Главную загрузочную запись (MBR)....»

  • Так же просили вспомнить о LILO. LILO, ми тебя помним! Привет!
  • Xpeh доплняет , что «BIOS (и не упомянутый тут (U)EFI) прежде всего занимается инициализацией устройств (в том числе загрузку собственных биосов PCI-устройств), про это ничего не написано. Хотя эта роль постепенно сокращается, так как всё больше железа инициализирует себя само и/или поддерживает горячее подключение и потому всё равно инициализируется ОС, но, например, инициализацию оперативной памяти он делает всегда. „
  • VolCh уточняет загрузку для ОС Debian-Ubuntu:
    Для Debian/Ubuntu:
    - каталога /etc/rc.d/ нет;
    - каталоги /etc/rc?.d/ настоящие каталоги, а не ссылки;
    - в этих каталогах хранятся ссылки на скрипты в каталоге /etc/init.d/

    Вручную лучше в /etc/rc?.d/ ничего не править, а использовать команду update-rc.d, которая позволяет создавать ссылки, удалять их, запрещать (фактически переименовывать c S* на K*) и разрешать (c K* на S*) запуск.

Если на вопрос: «как добавить программу в автозагрузку?» — начинающие пользователи находят ответ достаточно быстро, то вопрос о запуске скрипта, при выключении/перезагрузки, ставит их в тупик. В статье будет описан стандартный способ для автоматического выполнения команд при включении и выключении linux, а также более простой способ для пользователей, у которых установлен gdm и графический интерфейс, например ubuntu.

Консольный вариант.

Немного теории.
Следует знать, что в Linux существует 7 уровней запуска. Однако, использоваться могут только 6.
Как у всех уважающих себя программ отсчёт начинается с 0-ля.
0 — Остановка или выключение системы.
1 — Однопользовательский режим.
2 — Многопользовательский режим, но без поддержки сети.
3 — Тоже самое, но с сетью.
4 — Добавили для красоты Не используется.
5 — Графический режим с загрузкой X сервера.
6 — Перезагрузка.
Если перейти в папку /etc (В некоторых дистрибутивах /etc/rc.d) то можно увидеть папки с 7-мью уровнями запуска.

Например при выключении компьютера, выполнятся все скрипты из папки rc0.d


Тут следует остановится по подробнее. Дело в том, что самих скриптов (а точнее сценариев) в этой папке нету, а есть только ссылки на файлы, которые лежат в папке /etc/init.d. Эти сценарии выполняют различные задачи, в зависимости от параметра start или stop (например /etc/init.d/reboot start и /etc/init.d/reboot stop это разные команды, а /etc/init.d/reboot вообще не будет работать). Если в ссылке стоит первая буква S, то значит сценарию подаётся параметр start, а если стоит буква K(от слова kill), то параметр stop. Цифра после буквы обозначает порядок выполнения сценария.
Например, на выше вставленном скриншоте вначале выполниться команда /etc/init.d/hddtemp stop, а уже позже /etc/init.d/networking start.
Хватит теории. Переходим к практике.
Для того, чтобы добавить команду в автозагрузку, достаточно поместить её в файл /etc/rc.local.

В этой части статьи в качестве редактора будет использоваться nano, но вы можете пользоваться своим любимым редактором, например gedit.

sudo nano /etc/rc.local

И помещаем наши команды чуть выше строчки с exit 0.
Для того, что бы команды выполнялись перед выключением или перезагрузкой нам нужно создать сценарий в папке /etc/init.d

sudo nano /etc/init.d/имя_сценария

Вставляем следующий код:

#! /bin/sh
case "$1" in
start)
echo "подан сигнал start"
;;
stop)
echo "подан сигнал stop"
;; esac

Если будет подаваться только один сигнал, то просто закомментируйте строку поставив в начале команды знак #
Например

...
case "$1" in
start)
#
;;
...

Теперь делаем файл исполняемым:

sudo chmod +x /etc/init.d/имя_сценария

sudo update-rc.d имя_сценария start 20 0 6 . stop 1 0 6 .

Точки важны (обе). Исследуя просторы интернета, у меня сложилось впечатление, что синтаксис этой программы иногда меняется. Актуальные примеры можно посмотреть по команде «man update-rc.d». Примеры будут в низу.

Эта команда создаст по 2 ссылки в каталогах /etc/rc0 .d (второе число в команде) и /etc/rc6 .d (третье число в команде). Причём вначале будет выполняться сценарий с параметром stop (т.к. стоит 1), а уже потом с параметром start (т.к. стоит 20).
Если второй параметр не нужен, то можно выполнить команду:

sudo update-rc.d имя_сценария stop 1 0 6 .

Советую ставить приоритет повыше (т.е. число после start или stop должно быть маленьким), желательно меньше 20. В обратном случае у меня иногда зависал компьютер при попытке перезагрузиться.

Для пользователей ubuntu, да и многих других современных дистрибутивов с gdm можно воспользоваться…

Графический вариант.

Что касается автозагрузки то можно воспользоваться способом описанным .
Или просто открыть «автоматически запускаемые приложения» командой:

gnome-session-properties

Для выполнения скрипта при выключении компьютера, помещаем его в файл /etc/gdm/PostSession/Default

sudo gedit /etc/gdm/PostSession/Default

Прямо над строчкой exit 0.

Последовательность загрузки Linux системы состоит из следующих этапов:

BIOS (Basic Input-Output System - базовая система ввода вывода)

BIOS - это интерфейс самого низкого уровня между компьютером и периферией, который ищет и исполняет загрузочный сектор на каком-либо устройстве хранения данных подключённых к компьютеру.

Как правило это:

  • Привод CD-ROM
  • Жёсткий диск
  • Дисковод (используются всё реже)

Список зависит от возможностей конкретного BIOS"а, а также вашего оборудования.

Приоритет загрузки может быть изменён в BIOS"е. Войти в меню настройки BIOS"а, как правило, можно нажав Del, F1, F2 или F10 во время загрузки компьютера.

MBR (Master Boot Record - главная загрузочная запись)

Первый сектор загружаемого устройства хранения данных зарезервирован под главную загрузочную запись. Когда происходит загрузка с устройства, BIOS загружает и исполняет загрузчик операционной системы (boot loader), находящийся в MBR.

В большинстве случаев загрузчик достаточно сложен и не может вместиться в 512 байт отведённые MBR. В этом случае в MBR находится так называемый stage1, программа которая просто загружает программу второго этапа загрузки операционной системы - stage2 (иногда в качестве stage2 загружается загрузочный сектор активного раздела, boot manager или программа авторизации и защиты доступа).

В частности, stage2 загрузчика GRUB считывает данные из файла /boot/grub/grub.conf (или /boot/grub/menu.lst, в зависимости от версии), который содержит список всех доступных операционных систем и их параметры загрузки. После этого на экран выводится список операционных систем из которого пользователь выбирает ОС для загрузки.

Загрузчик операционной системы

В некоторых случаях stage1 загрузчика GRUB (GRand Unified Bootloader) производит загрузку stage1.5 код которого находится в первых тридцати килобайтах устройства хранения данных следующих сразу за MBR, и уже stage1.5 производит загрузку stage2.

Когда stage2 получает управление, на экран выводится (псевдо)графическое меню для выбора пользователем ОС для загрузки. Стоит отметить, что параметры загрузки могут быть изменены из этого же меню, что позволяет восстановить систему после того как menu.lst или grub.conf были случайно испорчены.

Как только параметры загрузки были выбраны, GRUB загружает выбранное ядро в память и передаёт управление ядру, которое уже само продолжает загрузку системы. Также GRUB может передать управление не ядру, а другому загрузчику, используя так называемую цепную загрузку (chain loading), например загрузчику ОС не поддерживающей стандарт Multiboot.

Ядро

В свою очередь, ядро проверяет конфигурацию оборудования, инициализирует устройства и запускает initrd (опционально), после чего монтирует с устройство указанное в параметрах загрузки как "root" как корневую файловую систему.

Файловая система устройства определяется автоматически. Если по каким либо причинам монтирование не удаётся, система выдаёт kernel panic и загрузка останавливается.

После успешного монтирования файловой системы, ядро запускает демон init, которая получает идентификатор процесса равный единице и запускает оставшуюся часть системы.

init

init - это последний шаг в последовательности загрузки системы. init является родителем (или же более далёким предком) для всех процессов исполняемых в системе. Этот процесс запускается первым в системе и его запуск производится непосредственно ядром. Он же запускает все системные процессы так как это указано в /etc/inittab.

Покуда система работает, init не будет завершён. Стоит отметить что init - пользовательский процесс, а не системный, не смотря на то что он запущен от root"а.

Уровни запуска (runlevel)

Каждая запись в /etc/inittab содержит так называемый "уровень запуска" для процесса, т.е. информацию о том на каком уровне запуска системы данный процесс должен быть запущен.

В Linux системах существует семь возможных значений для уровня запуска: от 0 до 6 включительно:

  1. Останов системы
  2. Однопользовательский режим
  3. Определяется пользователем, как правило это многопользовательский режим без поддержки сети и графической оболочки
  4. Многопользовательский режим без графической оболочки
  5. Определяется пользователем, как правило, не используется
  6. Многопользовательский режим с графической оболочкой

Основываясь на текущем уровне запуска, init запускает скрипты находящиеся в поддиректориях /etc/rc.d/, для каждого уровня запуска существует своя поддиректория, от /etc/rc.d/rc0.d до /etc/rc.d/rc6.d.

В действительности же запуск скриптов каждого уровня запуска выполняется скриптом /etc/rc который вызывается на каждом уровне запуска с параметром равным текущему уровню. Вызов же /etc/rc параметром прописан в /etc/inittab, для каждого из возможных уровней запуска.

Уровень запуска по умолчанию определяется записью в /etc/inittab:

Id:3:initdefault:

Текущий уровень запуска может быть изменён путём вызова:

/sbin/telinit #

Где # - желаемый уровень запуска. Т.е. вызов "/sbin/telinit 6" приведёт к перезагрузке системы.

Давайте разделим процесс загрузки ОС Linux на девять этапов, которые имеют место практически для любой конфигурации ОС Linux:

  1. Первый этап загрузки -- это считывание BOIS"ом компьютера или другими программно-аппаратными средствами MBR жесткого диска или другого загрузочного устройства (например, компакт-диска, гибкого диска или сетевого загрузочного устройства, etc.).
  2. Начинается работа загрузчика. Linux на архитектуре x86 обычно использует LILO или GRUB. Некоторые старые системы могут использовать loadlin чтобы загрузиться через вспомогательный DOS-раздел. В системах Power PC® это может быть BootX или yaboot. Вообще, загрузчик -- это простая программа, которая, тем не менее, знает, где искать ядро Linux, может выбрать, какую загружать из нескольких версий ядра или даже выбрать другую операционную систему на той же машине.
  3. Монтируется корневая файловая система. В некоторых случаях, временно монтируется начальная корневая файловая система из содержимого, например, RAM-диска, инициализируемого загрузчиком, чтобы дать возможность загружаться специальным драйверам и модулям, которые могут понадобиться для работы настоящей корневой файловой системы.

    Теперь у нас есть корневая файловая система, и мы можем начать собственно инициализацию.

  4. Запускается процесс init , прародитель всех остальных процессов в ОС Linux.
  5. Считывается содержание файла /etc/inittab, чтобы определиться с дальнейшим ходом загрузки. Особенно важно что прописано в файле /etc/inittab в строке, определяющей уровень запуска системы (и, следовательно, последующие этапы загрузки).

    Действительно, все происходящее после этого момента полностью определяется содержимым файла /etc/inittab. Фактически, скрипты и другие инструменты, которые работают, подчиняются соответствующим настройкам, но, в принципе, вы могли бы полностью изменить /etc/inittab, чтобы управлять работой различных инструментов по вашему желанию.

    Одна из установок в файле /etc/inittab особенно важна. Это строка, похожая на:

    id:5:initdefault:

    Обычно она находится ближе к началу файла и устанавливает уровень запуска системы. Уровень запуска определяет, какие действия будут предприняты в оставшихся предписаниях файла /etc/inittab.

    Что происходит, когда сценарий /etc/inittab отработан? И особенно, какие именно файлы и директории принимают участие в процессе?

  6. Инициализация, независимая от уровня запуска. Существуют ряд действий, которые будут выполняться независимо от установленного уровня запуска. Эти шаги обозначены в /etc/inittab строками, похожими на:

    # System initialization.
    si::sysinit:/etc/rc.d/rc.sysinit

    В некоторых системах Linux (в основном в системах на основе Debian), вы скорее увидите строчки, более похожие на следующие:

    si::sysinit:/etc/init.d/rcS

    В последнем случае файл /etc/init.d/rcS -- это просто скрипт, который по очереди запускает скрипты /etc/rcS.d/??*. С другой стороны, если в вашей системе используется /etc/rc.d/rc.sysinit, для выполнения инициализации достаточно одного длинного скрипта, содержащегося в этом файле.

  7. Инициализация, зависимая от уровня запуска. Фактически, вы можете определить столько действий, связанных с уровнем запуска, сколько захотите, и при этом каждое действие может относиться к одному или нескольким уровням запуска. Как правило, /etc/inittab будет содержать строки типа:

    l0:0:wait:/etc/rc.d/rc 0
    # ...
    l5:5:wait:/etc/rc.d/rc 5
    l6:6:wait:/etc/rc.d/rc 6

    В свою очередь, скрипт /etc/rc.d/rc будет управлять всеми файлами, названными /etc/rc$1.d/??*. В следующем примере можно увидеть, что в данной системе, стартующей с уровнем запуска 5, будут выполняться (по порядку):

    /etc/rc5.d/K15postgresql
    /etc/rc5.d/S01switchprofile
    /etc/rc5.d/S05harddrake
    ...
    /etc/rc5.d/S55sshd
    ...
    /etc/rc5.d/S99linuxconf
    /etc/rc5.d/S99local

    Файлы, начинающиеся с "K" или "k" являются убивающими (kill) скриптами , они завершают процессы или упорядочивают их действия (последствия). Файлы, которые начинаются с "S" или "s" -- это запускающие (startup) скрипты , они начинают новые процессы или подготавливают систему к работе с этим уровнем запуска. Большинство из них являются скриптами shell, и большая часть их будет ссылками (часто на /etc/init.d/).

    В то время когда система Linux стартует с определенным уровнем запуска, вы хотите зарегистрироваться в системе как пользователь. Чтобы авторизация прошла успешно, используется программа getty. Множество разновидностей программ на основе getty используется создателями дистрибутивов, типа agetty, mgetty, и mingetty. Но все они делают примерно и то же.

  8. Войдите в систему в приглашении. Уже знакомый нам /etc/inittab обычно запускает getty на одном или нескольких виртуальных экранах и делает это для нескольких уровней запуска. Уровни определены в строках типа:

    # Run gettys in standard runlevels
    1:2345:respawn:/sbin/mingetty tty1
    2:2345:respawn:/sbin/mingetty tty2
    3:2345:respawn:/sbin/mingetty tty3
    4:2345:respawn:/sbin/mingetty tty4
    5:2345:respawn:/sbin/mingetty tty5
    6:2345:respawn:/sbin/mingetty tty6

    Цифра в начале показывает, в каком виртуальном терминале будет работать программа getty; следующие несколько цифр -- это те уровни запуска, при которых это случится (например, запуск mingetty при каждом из уровней 2, 3, 4 и 5).

Следующие шаги инициируют запуск дополнительных служб, вход в графическое окружение, восстановление настроек пользовательского интерфейса или других более персонифицированных деталей, которые находятся вне рамок этого учебного пособия.

Понятие уровня запуска несколько произвольно, по крайней мере, оно не прописано в ядро Linux. Действительные уровни запуска сопоставлены набору номеров, чтобы можно было установить (или изменить имеющийся) по умолчанию уровень запуска выбором номера от 0 до 6. В соответствии с соглашением, следующий смысл присваивается каждому номеру уровня запуска:


Листинг 1. Уровни запуска
# Default runlevel. The runlevels used by Mandrake Linux are: # 0 - Halt (Do NOT set initdefault to this) # 1 - Single user mode # 2 - Multiuser, without NFS (The same as 3, if you don"t have networking) # 3 - Full multiuser mode # 4 - Unused # 5 - X11 # 6 - Reboot (Do NOT set initdefault to this)

Это соглашение, как можно видеть, используется в дистрибутиве Mandrake Linux, но большинство дистрибутивов используют то же самое соглашение. Может так оказаться, что текстовые или встроенные дистрибутивы не используют некоторые из уровней запуска, но все равно ими будут зарезервированы эти же номера.

Вы видели множество строчек из файла /etc/inittab в примерах, но что же конкретно они означают? Каждая строка имеет формат:

id:runlevels:action:process

Поле id это короткое сокращение, обозначающее конфигурационную строчку. (1 - 4 буквы в свежих версиях init ; 1 - 2 в более старых). Поле runlevels уже обсуждалось. Следующее поле action обозначает действие, предпринимаемое строкой. Некоторые действия могут быть "специальными," такие как:

ca::ctrlaltdel:/sbin/shutdown -t3 -r now

Эта строка устанавливает действие для последовательности клавиш Ctrl-Alt-Delete (независимо от уровня запуска). Но большинство действий просто запускает соответствующие процессы. Частичный список действий включает:

  • respawn: Процесс будет перезапущен всякий раз, когда завершится (как в случае с getty).
  • wait:Процесс будет начат однажды, когда будет введен указанный уровень запуска, и init будет ждать его завершения.
  • once: Процесс будет выполнен однажды, когда будет введен указанный уровень запуска.
  • boot: Процесс будет выполнен во время загрузки системы (но после sysinit). Уровень запуска не имеет значения.

Настройка запуска системы и процесса загрузки

Несколько лет назад для загрузки Linux на x86 системах в основном использовалась программа, названная LILO. Название LILO -- сокращение от "LInux LOader." Сейчас более популярна программа, названная GRUB (GRand Unified Bootloader). На системах, отличных от x86, используются другие загрузчики, но все они сконфигурированы аналогичным для LILO и GRUB способом.

Хотя существуют различия в их конфигурационном синтаксисе, и LILO и GRUB выполняют в значительной степени одну и ту же задачу. По существу, каждый из них предоставляет выбор операционной системы (включая, возможно, несколько ядер Linux) и загружает ядро выбранной ОС в память компьютера. Обе программы позволяют вам передавать аргументы ядру Linux по ходу, и обе могут быть сконфигурированы с возможностью загрузки на том же компьютере ОС, отличных от Linux.

Либо LILO, либо GRUB (или какой-то другой загрузчик) находится на MBR (Master Boot Record) первичного жесткого диска, который автоматически загружается системным BIOS. LILO имеет ограничения на загрузку специального raw сектора жесткого диска. Загрузчик GRUB более изощрен и распознает разные файловые системы, например, такие как ext2/3, ReiserFS, VFAT или UFS. Это означает, что GRUB не нужно перезаписывать MBR каждый раз, как только изменился конфигурационный файл (как это делает LILO).

Настройка загрузчика LILO производится при помощи содержимого файла /etc/lilo.conf. Для более детального изучения параметров настройки LILO, прочитайте страницы помощи man для lilo.conf. Общий характер поведения определяют несколько начальных параметров. Например, вы наверняка увидите boot=/dev/hda или нечто подобное. Эта команда устанавливает загрузчик на MBR первичного жесткого диска IDE. Вы можете также установить LILO внутрь конкретного раздела, обычно это нужно, когда вы используете другой основной загрузчик. Например, boot=/dev/sda3 устанавливает LILO на третий раздел первого SCSI диска. Другие параметры определяют внешний вид и время ожидания LILO.

Запомните, что после того, как вы внесете исправления в файл /etc/lilo.conf, вам необходимо запустить LILO для фактической установки нового загрузочного сектора, который используется во время загрузки. Можно легко забыть установить новые параметры, но загрузчик сам по себе не сможет прочесть новую конфигурацию, за исключением того случая, когда записаны фактические адреса секторов (которые LILO распознает в процессе работы).

Если используется LILO, особенное значение имеют строки типа image= и, может быть, other= , если имеется выбор между ОС Linux и другими операционными системами. Пример /etc/lilo.conf может содержать:


Листинг 2. Пример конфигурации LILO
image=/boot/bzImage-2.7.4 label="experimental" image=/boot/vmlinuz label="linux" initrd=/boot/initrd.img append="devfs=mount acpi=off quiet" vga=788 read-only other=/dev/hda3 label=dos

Такая конфигурация позволяет вам выбирать либо ядро версии 2.7.4, которое находится в стадии разработки, либо стабильное ядро (далее объявлено, что использовать как стартовый RAM-диск (initrd) в процессе загрузки). Вы можете также выбрать DOS, которая находится на третьем разделе первичного IDE диска.

Бесспорным преимуществом GRUB является то, что его не надо переустанавливать всякий раз, после того как вы изменили параметры загрузки. Конечно, в первый раз GRUB все же нужно установить, обычно это делается командой типа grub-install /dev/hda . Как правило, в процессе инсталляции дистрибутив делает это для вас сам, так что вы, может статься, так ни разу сами этого и не сделаете.


Листинг 3. Пример конфигурации GRUB
timeout 5 color black/yellow yellow/black default 0 password secretword title linux kernel (hd0,1)/boot/vmlinuz root=/dev/hda2 quiet vga=788 acpi=off initrd (hd0,1)/boot/initrd.img title experimental kernel (hd0,1)/boot/bzImage-2.7.4 root=/dev/hda2 quiet title dos root (hd0,4) makeactive chainloader +1

И LILO и GRUB позволяют передать специальные параметры выбранному вами ядру. Если вы используете LILO, вы можете передать параметры приглашению boot добавлением их к выбранному вами ядру. Например, для обычных параметров загрузки вы можете ввести:

LILO: linux ether=9,0x300,0xd0000 root=/dev/ha2 vga=791 acpi=on

Эта строчка передает специальные параметры модулю Ethernet, указывает корневой раздел, выбирает режим видео, и т.д. Конечно, не все это удобно, так как вы должны знать точно подходящие значения этих параметров и уметь правильно ввести их.

Особенное значение имеет параметр, который изменяет уровень запуска системы загрузчиком. Например, в целях восстановления системы, вы хотите загрузить систему в однопользовательском режиме. Осуществляется это следующим образом:

LILO: experimental single

Другой специальный параметр -- аргумент init= , который позволяет вам использовать программы, отличные от init в качестве первичного процесса. Параметры для режима аварийной ситуации могут быть следующими: init=/bin/sh , что, по крайней мере, позволит вам иметь в своем распоряжении командную строку (Linux shell), если init совсем вышел из строя.

С загрузчиком GRUB вы имеете еще большую гибкость. Фактически, GRUB представляет из себя оболочку командной строки и предоставляет пользователю базовую функциональность shell. GRUB дает возможность не только изменить базовую конфигурацию загрузчика, но даже читать файловые системы. Для настройки параметров загрузки, нажмите "e" в командной строке GRUB, после этого добавьте параметры (например, номер уровня запуска или ключевое слово "single" как в LILO). Все другие аргументы в приглашении загрузки, которые вы могли бы ввести, используя LILO, могут быть использованы в командной строке GRUB.

Для понимания своих возможностей вы можете открыть командную строку GRUB. Например, предположите, что вам кажется, что ваш файл /etc/inittab плохо сконфигурирован, и вы хотите исследовать это перед загрузкой. Вы могли бы ввести:

grub> cat (hd0,2)/etc/inittab

Это позволило бы заранее просмотреть ваш инициализацонный файл, без запуска операционной системы. Если бы там обнаружилась ошибка, то можно было бы загрузиться в однопользовательский режим и исправить ее.

Как только вы осознаете шаги в загрузке Linux после загрузки ядра (другими словами, процесс init и все, что он вызывает), вы также осознаете, как их отредактировать. В основном, вся настройка осуществляется редактированием файла /etc/inittab и различных скриптов в каталоге /etc/rc?.d/.

Например, недавно мне понадобилось настроить видео BIOS на ноутбуке с Linux, базирующемся на Debian, использующем разработки третьих фирм. Если он не был запущен до того, как запустятся X11, мой драйвер XOrg не установил бы правильные режимы видео. Как только я выяснил, в чем была проблема, решение было столь же просто, как создание скрипта /etc/rcS.d/S56-resolution.sh. Другими словами, я запускал дополнительный скрипт при каждой загрузке системы.

Замечу, что я удостоверился, что этот скрипт исполняется раньше, чем /etc/rcS.d/S70xorg-common вследствии простого соглашения, что скрипты запускаются в алфавитном порядке (если бы я хотел, чтобы мой скрипт выполнялся позже, я, возможно, назвал бы его S98-resolution.sh вместо /etc/rcS.d/S56-resolution.sh). Может быть, я поместил бы этот скрипт только в каталог /etc/rc5.d/, чтобы он запускался, когда выполняются X11, но я могу вручную запустить startx из-под другого уровня запуска.

Все настройки в процессе инициализации открыты для редактирования, прямо в файловой системе; почти все можно исправить с помощью текстовых скриптов.

Восстановление файловой системы

Самое замечательное свойство Linux, которое рассматривается в перспективе обслуживания системы, это то, что все является файлом. Конечно, время от времени возникает вопрос , в каком файле что живет. Но зато, как правило, восстановление Linux означает применение основных утилит файловой системы, таких как cp , mv , rm и текстовый редактор типа vi. Для автоматизации этих действий полезны такие инструменты как grep, awk и bash; или на более высоком уровне, perl или python. Но в данном учебном пособии мы не ставим целью изучать обращение с файлами.

Предположим, что вы знаете, как редактировать файлы и управлять ими, вот только в порушенной системе файлы, которых коснулось повреждение, возможно останутся вообще непригодными для использования.

Ваш лучший друг в восстановлении поврежденной файловой системы fsck .

Команда fsck является фактически только началом команды для большого количества других инструментов fsck.* -- fsck.ext2 , fsck.ext3 , или fsck.reiser . Вы можете определить тип явно, используя опцию -t , но fsck предпримет усилие понять самостоятельно. Прочитайте страницу помощи man для fsck или fsck.* для получения более подробной информации. Основное, что вам нужно знать, что при использовании аргумента -a программа будет пытаться исправить все найденные ошибки.

Вы можете проверить неподмонтированную файловую систему, упоминая местонахождение устройства, на котором она находится. Например, введите fsck /dev/hda8 , чтобы проверить неиспользующийся раздел. Вы можете также проверить корневую файловую систему, набрав fsck /home , но как правило, делают это, только если файловая система уже смонтирована как "только для чтения", а не для "чтения-записи".

Одно из основных преимуществ систем Linux состоит в гибкости пользовательского контроля, при монтировании и отмонтировании файловых системам. В отличие от Windows и некоторых других операционных систем, местоположения разделов не автоматически закреплены ядром Linux, а присоединены к иерархии корневой файловой системы командой mount . Кроме того, различные типы файловых систем (даже на различных устройствах) могут быть смонтированы в рамках той же самой иерархии. Вы можете отмонтировать конкретный раздел командой umount , назначать любую точку монтирования (например, /home) или адрес устройства (например, /dev/hda7).

Когда производится восстановление файловой системы, возможность управлять точками монтирования позволяет вам проводить анализ состояния разделов, используя fsck или другие инструменты, без риска дальнейшего повреждения уже поврежденной файловой системы. Вы можете также в обычном порядке монтировать файловую систему, используя различные параметры; самые важные из них монтируют файловую систему для использования только в режиме чтения с помощью одного из синонимов -r или -o ro .

В качестве примера, вы могли бы хотеть заменить местоположение каталога одного пользователя на каталог другого, или из-за повреждения раздела, или просто хотите расширить дисковое пространство, или переместиться на более быстрый диск. Такое изменение можно выполнить, используя:

# umount /home # old /dev/hda7 home dir
# mount -t xfs /dev/sda1 /home # new SCSI disk using XFS
# mount -t ext3 /dev/sda2 /tmp # also put the /tmp on SCSI

Для восстановления, модернизации системы, и специальных целей полезно иметь возможность монтировать и отмонтировать файловые системы по желанию. Но для повседневной работы, вам будет удобно, чтобы необходимый конкретный набор подмонтирований осуществлялся автоматически при каждой загрузке системы. Вы управляете точками монтирования, прописывая нужные строки конфигурации в файл /etc/fstab. Типичная конфигурация могла бы выглядеть так:


Листинг 4. Пример конфигурации в /etc/fstab
/dev/hda7 / ext3 defaults 1 1 none /dev/pts devpts mode=0620 0 0 /dev/hda9 /home ext3 defaults 1 2 none /mnt/cdrom supermount dev=/dev/hdc,fs=auto,ro,--,iocharset=iso8859-1,codepage=850,umask=0 0 0 none /mnt/floppy supermount dev=/dev/fd0,fs=auto,--,iocharset=iso8859-1,sync,codepage=850,umask=0 0 0 none /proc proc defaults 0 0 /dev/hda8 swap swap defaults 0 0