- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF142:LT2
Материал из Linuxformat.
- Тренинги Linux Учебники
Тренинги Linux от Майка Сондерса |
---|
|
Содержание |
Майк Сондерс ведет Тренинги Linux
- Часть 2: После вылазки в мир «железа», теперь подробно рассмотрим процесс загрузки. Да выплюньте жевательную резинку!
Вы нажали кнопку включения компьютера. На экране мелькают сообщения или некая анимация (если у вас настольный дистрибутив), и наконец появляется приглашение для входа в систему. Что же происходит за это короткое время? Этому мы и посвятим второй урок из цикла «Тренинги Linux». Как и пре-дыдущий урок, он поможет вам подготовиться к сертификации в LPI и пригодится тем, кто ищет работу в мире Linux или просто хочет побольше узнать о своей операционной системе.
В качестве основы для сертификации используются не переменчивые и часто обновляемые дистрибутивы, а более стабильные платформы, используемые в промышленных решениях, такие как Red Hat Enterprise Linux (RHEL), CentOS и Debian. На прошлом уроке мы работали с CentOS; на сей раз настала очередь Debian (версия 5). Хотя определенные функции в разных дистрибутивах реализованы по-разному, большинство из сказанного применимо ко всем.
Раздел 1: От включения ПК до рабочего стола
Процесс загрузки Linux включает замысловатый набор процессов и скриптов, которые превращают компьютер, до этого бывший лишь мертвой грудой металла, в мощную рабочую станцию или сервер. Давайте пройдем по основным этапам загрузки.
BIOS
BIOS (Basic Input/Output System – базовая система ввода/вывода) – маленькая программа, проживающая в микросхеме на материнской плате. По нажатию кнопки включения питания компьютера процессор начинает выполнять код BIOS. Вы несомненно видели сообщения ‘Hit F2 for setup’ [Нажмите F2 для настройки], которые появляются при загрузке системы. Так можно войти в BIOS и изменить настройки, например, порядок загрузки дисков. Обычно BIOS выполняет быструю проверку устройств – например, микросхем оперативной памяти – и затем пытается найти загрузчик. Она пробует загрузить первые 512 байт с дискеты или жесткого диска в память, и если это удалось сделать, выполняет их.
Загрузчик
Итак, BIOS передал управление первой части ОС – загрузчику размером пол-килобайта. В восьмидесятых такого небольшого объема памяти было достаточно, чтобы загрузить ядро ОС [На самом деле никогда не было достаточно, просто раньше выбора не было и загружалось только одно ядро которому нельзя было передать параметры до загрузки, поэтому загрузчик содержал только адрес на диске где ему брать это ядро.]. Однако современные загрузчики должны поддерживать множество различных файловых систем, операционных систем и графических режимов, поэтому 512 байт для них недостаточно. В случае с Grub, который используется в большинстве дистрибутивов Linux, загрузчик размером пол-килобайта загружает другую программу Stage 1.5.
Это загрузчик чуть побольше, расположенный в начале диска, чтобы его можно было легко найти. Затем он загружает Grub Stage 2, полноценный загрузчик, который предоставляет все привычные вам возможности. Grub считывает файл настройки, загружает ядро Linux в оперативную память и начинает его выполнять.
Ядро Linux и Init
Начав исполняться с самых первых байтов, ядро Linux похоже на новорожденного, который ничего не знает о внешнем мире вашей системы. Сначала оно пытается понять, что за процессор установлен и каковы его возможности, каков объем оперативной памяти, и получает полную картину системы. Затем размещает себя в безопасной области памяти, чтобы другие программы не могли переписать его и эффектно обрушить систему, и начинает активизировать драйверы устройств, сетевые протоколы и т. д.
Сделав все необходимое, ядро передает управление пользовательскому пространству – месту, где выполняются программы. Ядру неинтересно запускать Bash, Gdm и т. д. напрямую, поэтому оно запускает только одну главную программу – /sbin/init. Это первый настоящий процесс в системе. Init отвечает за вызов загрузочных скриптов, запускающих систему, но ему нужно знать, что запускать. Его основной файл настройки – /etc/inittab, обычный текстовый файл, который можно изменять.
В основе этого файла лежит концепция уровней выполнения [runlevels] – различных состояний, в которых может находиться работающая система, таких как одно- и многопользовательский режим и выключение. О них мы поговорим позже, а пока вам нужно знать, что /etc/inittab велит init запустить скрипт /etc/init.d/rc с уровнем выполнения в качестве параметра.
Этот скрипт вызывает другие, для настройки различных частей системы – установки сетевого соединения, запуска системных журналов и – на настольном компьютере – запуска X Window System и менеджера входа в систему. После ввода логина и пароля менеджер входа в систему запускает выбранный рабочий стол или оконный менеджер, и все готово к работе. Весь этот процесс – от включения питания до выбора иконок на рабочем столе – включает массу работы, но в целом хорошо упрятан от пользователя.
Раздел 2: Изменение настроек Grub
LXF142_77_1.jpg
Теперь поподробнее рассмотрим загрузчик. Чаще всего это мощный Grub, способный загружать множество ОС и менять конфигурацию во время загрузки. Мы поговорим о его файлах настройки и связанных с ним утилитах в других статьях, а пока изучим изменение конфигурации во время загрузки в нашем Debian.
После загрузки Grub сразу после BIOS вы видите список возможных вариантов загрузки. Для выбора одного из них можно нажать Enter, но можно и изменить их прямо во время загрузки: выберите вариант, который хотите изменить, и нажмите E. После этого на экране появятся следующие три строки:
root (hd0,0) kernel /boot/vmlinuz-2.6.26-2-686 root=/dev/hda1 ro quiet initrd /boot/initrd.img-2.6.26-2-686
Посмотрите на вторую строку. Она сообщает Grub, где найти ядро Linux и какие параметры загрузки ему передать. В этом случае мы говорим ядру, где находится корневой раздел (/); ro означает, что раздел нужно смонтировать в режиме только для чтения. Это нужно затем, чтобы при необходимости проверить файловую систему – чуть позже она будет перемонтирована в режиме чтения и записи. А quiet говорит ядру, что оно не должно выдавать нам слишком много сообщений, чтобы загрузка была яснее и за ней было проще следить.
Мы можем изменить эти параметры, нажав стрелку вниз, чтобы выбрать вторую строку, и снова нажав E. Окно перейдет в режим чистого редактирования, в котором вы сможете добавить и удалить опции. С помощью клавиш управления курсором его можно перемещать по строке. Давайте кое-что попробуем: после quiet добавьте букву s (их должен разделять пробел). Так мы задаем уровень загрузки, на который должно загрузиться ядро – s означает однопользовательский режим [single user].
Нажмите Enter, чтобы вернуться в окно Grub, затем B, чтобы начать процесс загрузки. Так как мы загружаемся в однопользовательский режим, после инициализации ядра и монтирования корневого раздела процесс завершится, и у вас запросят пароль пользователя root. Введите его, и вы попадете в командную строку. Это ограниченный режим работы, но он удобен для решения проблем с загрузкой – в нем можно беспрепятственно изменять скрипты и исправлять ошибки.
Загрузка в будущем
Замечание, касающееся безопасности: любой, у кого есть доступ к вашему компьютеру, может перезагрузить его и порезвиться с настройками Grub, как бы хорошо ни была защищена система. На следующих уроках, когда дойдет до файла настройки Grub, мы посмотрим, как защитить загрузчик паролем, чтобы предотвратить эти действия.
Загрузочные скрипты в Linux (и Unix) традиционно запускаются последовательно, т. е. один за другим. Это просто и гарантирует правильную очередность активизации определенных устройств на определенных этапах процесса загрузки. Однако это неэффективно и приводит к увеличению времени загрузки, особенно на старом «железе». Значительную часть времени скрипты ждут, пока что-то произойдет – например, пока активируется устройство или пока DHCP-сервер сети выдаст разрешение.
Но ведь было бы здорово чем-то заняться во время этих задержек? Такова цель распараллеленных скриптов init. Пока сетевой скрипт ждет сигнал от DHCP-сервера, другой скрипт может очистить каталог /tmp или запустить X Window System. Впрочем, чтобы запустить несколько скриптов параллельно, недостаточно написать их в строчку через амперсанды – некоторые скрипты зависят от определенных ресурсов. Например, скрипт загрузки, который получает IP-адрес через DHCP, предполагает, что сеть уже активирована другим скриптом.
InitNG – параллельная система загрузки, в которой зависимости скриптов устроены так, чтобы порядок их загрузки не играл роли. Upstart, используемый в Ubuntu, запускает скрипты на основе системных событий, таких как обнаружение устройства. Затем есть System D (ожидается в Fedora 15) и другие подходы. Ради блага авторов документов и администраторов будем надеяться, что мир Linux в итоге остановится на чем-то одном, но шаги в этом направлении в любом случае значительно ускоряют процесс загрузки Linux.
Раздел 3: Просмотр файлов журналов
При упомянутой ранее опции quiet и общем быстродействии современных компьютеров вполне возможно, что фотоны от сообщений загрузки едва успеют достигнуть вашей сетчатки, как процесс загрузки завершится. К счастью, сообщения можно спокойно прочесть, когда система полностью загрузится. Загляните в файл /var/log/messages (для этого у вас должны быть права root), и увидите там все сообщения, сгенерированные ядром с момента его запуска. Однако при попытках ядра определить, какие устройства установлены, результаты иногда его удивляют, так что не паникуйте, если увидите занимательные предупреждения вроде ‘Warning: strange, CPU MTRRs all blank?’ [Предупреждение: странно, все диапазонные регистры памяти процессора чисты?]
Сондерс рассказывает о ядре
Порядок работы ядра примерно таков (хотя некоторые этапы перекрывают друг друга):
- Получение информации об устройствах из BIOS (учтите, что ей не всегда можно доверять).
- Определение количества процессоров/ядер и изучение всех возможностей процессора.
- Получение информации ACPI и запрос информации об устройствах на шине PCI.
- Инициализация сетевого стека TCP/IP.
- Поиск жестких дисков, дисководов и приводов CD-ROM.
- Определение USB-контроллеров и подключенных к ним устройств.
Удовлетворившись состоянием системы, ядро монтирует корневую файловую систему и запускает /sbin/init как описано выше. Хотя /var/log/messages — ценный ресурс для определения действий ядра после загрузки, он может быть загроможден сообщениями и от других программ. Например, в нашем дистрибутиве во многих строках встречается debian:, но есть и другие – с dhcbd и т. д.
Если вы хотите просмотреть только сообщения ядра, запустите команду dmesg. (Для удобства можно перенаправить ее результаты в текстовый файл командой dmesg > listing.txt.) Хотя большинство сообщений, которые вы там найдете, будут относиться к ранним этапам загрузки, эта информация будет обновлена, если вы подключите новое устройство. Например, вставьте USB-флэшку и снова выполните команду, и вы увидите новые сообщения, из которых будет ясно, как ядро опознало устройство.
Раздел 4: Уровни выполнения и магия /etc/init.d/
Ранее мы говорили об уровнях выполнения, которые играют невероятно важную роль в вашем дистрибутиве, даже если вы никогда о них не слышали. Уровень выполнения определяет состояние системы – в частности, какие процессы запущены и какие ресурсы доступны. Это не какой-то секрет или черная магия ядра, а исключительно система, в соответствии с которой /sbin/init запускает скрипты для активации или деактивации определенных функций. Существует восемь уровней выполнения – у семи из них есть номера:
- 0 Останов системы Уровень выполнения, на который система переходит при выключении компьютера. При переключении на этот уровень запускаются скрипты, которые завершают процессы и корректно останавливают систему.
- 1 Однопользовательский режим Обычные пользователи не могут войти в систему.
- 2 – 5 Многопользовательский режим В Debian эти уровни идентичны, и вы можете изменить один из них, если хотите. Это обычный режим работы, при котором в систему может войти несколько пользователей и все возможности системы активированы.
- 6 Перезагрузка Очень похож на уровень выполнения 0.
В других системах, например Red Hat/Fedora распределение уровней загрузки следующее:
- 0 и 6 аналогично уже описанному
- 1 - Однопельзовательский режим без поддержки сети
- 2 - Однопользователский режим с поддержкой сети
- 3 - Многопользовательский режим с поддержкой сети
- 4 - Свободно, может быть использовано в личных целях
- 5 - Многопользователский режим с поддержкой сети и автоматическим запуском X
Также есть уровень выполнения S, соответствующий однопользовательскому режиму, который мы активировали перед изменением параметров загрузки Grub. Он очень похож на уровень выполнения 1, но есть и небольшие различия: S – уровень выполнения, который используется при загрузке системы, когда вам нужно перейти в безопасный режим восстановления. В противоположность ему, уровень выполнения 1 используется, когда система уже запущена и вам нужно перейти в однопользовательский режим, чтобы провести какие-то действия по обслуживанию системы. И не волнуйтесь за пользователей, которые уже вошли в систему: ничто их оттуда не выбросит.
Хотя уровни выполнения со 2 по 5 идентичны в Debian, в некоторых других дистрибутивах в этом диапазоне есть особые уровни выполнения. Например, во многих дистрибутивах уровень выполнения 3 – для многопользовательского текстового режима, а уровень выполнения 5 – для входа в систему в графическом ре жиме (такого как Xdm/Gdm/Kdm). Чтобы определить, на каком уровне вы сейчас находитесь, выполните команду /sbin/runlevel. Для переключения на другой уровень выполнения воспользуйтесь командой /sbin/telinit таким образом (от имени root):
/sbin/telinit 2
А как узнать, на каком уровне выполнения ваша система работает по умолчанию? Волшебство здесь сосредоточено в файле /etc/inittab. В начале файла вы увидите такие строки:
# The default runlevel. id:2:initdefault:
Строки, начинающиеся с символа решетки – комментарии, а нижняя строка сообщает init, что по умолчанию используется уровень выполнения 2. Если вы создаете собственный уровень выполнения с помощью скриптов для уровня выполнения 3' и хотите загружаться на него по умолчанию, можно просто открыть этот файл от имени root, изменить номер уровня и перезагрузить компьютер.
Чуть ниже в файле /etc/inittab вы найдете несколько строк примерно такого вида:
l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 …
Они будут продолжаться до уровня 6. Эти строки сообщают init, что делать на каждом уровне выполнения: запустить скрипт /etc/init.d/rc с номером уровня выполнения в качестве параметра. Затем /etc/init.d/rc определяет, какие скрипты ему нужно запустить для текущего уровня выполнения. Они аккуратно разложены по каталогам с соответствующими номерами в /etc. Там вы найдете каталоги /etc/rc0.d, /etc/rc1.d и т. д.
Предупреждения об изменении уровней выполнения
Изменение уровней выполнения на компьютере с одним пользователем – не проблема: вы уже готовы к этому. Но как насчет многопользовательской системы? Что делать, если по SSH к вам подключены другие пользователи и они запустили какие-то программы? Они не обрадуются, если выбить почву у них из-под ног. К счастью, есть несколько способов оповестить их о грядущих изменениях. Во-первых, если вы зашли в систему под пользователем root, можете набрать wall, текст сообщения и нажать Ctrl+D. Это сообщение появится на терминалах всех находящихся в системе пользователей. Так можно, например, отправить сообщение «Выключение через 10 минут». Обычные пользователи тоже могут запускать команду wall, но они могут и отключать сообщения от других обычных пользователей командой mesg.
Альтернативный способ предупредить пользователей – написать им письмо. Это можно сделать командой
echo “Перезагрузка через 10 минут” | mail -s “Reboot notice” user@localhost
Если у пользователей есть утилита оповещения о новых письмах, они сразу увидят сообщение. Но на большой установке с несколькими сотнями пользователей в системе лучше дать им несколько часов, а не минут.
На уровне выполнения
Заглянем в каталог /etc/rc2.d уровня выполнения по умолчанию в Debian. Внутри вы найдете несколько скриптов с именами вроде S05loadcpufreq и S89cron. Каждый из них активизирует определенную возможность в вашей системе – загляните в какой-нибудь из них, и там вы увидите комментарий, описывающий действие скрипта.
Итак, у нас есть S30gdm, который запускает Gnome Display Manager. Но что означают первые три символа? S означает, что этот скрипт что-то запускает, а 30 задает его положение в порядке загрузки. Вы видите, что у каждого скрипта есть номер, и они выполняются в порядке возрастания номеров. Таким образом, важные скрипты, такие как S10rsyslog, выполняются раньше (для включения журналирования), а более тривиальные возможности, такие как Cron (S89cron), активируются ближе к концу уровня выполнения.
Вглядевшись в них с помощью команды ls -l, вы увидите, что это не файлы, а символические ссылки на скрипты в /etc/init.d – там находятся настоящие скрипты. Так происходит потому, что скрипты могут разделяться между уровнями выполнения. Например, вы можете захотеть изменить способ запуска Cron, и ваши изменения в файле /etc/init.d/cron распространятся на все уровни выполнения, на которых он используется. Можете заглянуть в /etc/init.d и посмотреть, что там есть.
Эти скрипты – аккуратно написанные обертки программ, по именам которых они названы. Например, в файле /etc/init.d/gdm содержится не только команда gdm; там устанавливаются необходимые переменные окружения, выводятся сообщения в лог-файлы и т. д. В Debian большинство из этих скриптов можно вызывать с параметрами. Скажем, запустив /etc/init.d/gdm, вы увидите
Usage: /etc/init.d/gdm {start|stop|restart|reload|forcereload|status}
Таким образом, командой /etc/init.d/gdm start можно запустить Gdm, а командой /etc/init.d/gdm stop — остановить его. Обратите внимание, что restart выполняет остановку и запуск, а reload просит программу перечитать ее файл настройки без перезапуска, если это возможно. Этими скриптами можно свободно пользоваться и вне системы уровней выполнения – например, для перезапуска Exim или Apache после внесения изменений в их файлы настройки.
Наконец, отметим еще кое-что из /etc/inittab, не имеющее отношения к уровням выполнения, но тем не менее полезное. Вы когда-нибудь задавались вопросом, откуда во время загрузки появляются текстовые терминалы? Те, на которые можно переключиться из X-сервера, нажав Ctrl+Alt+Fx? Они задаются в нижней части файла /etc/inittab в таких строках, как эта:
2:23:respawn:/sbin/getty 38400 tty2
Часть /sbin/getty 38400 tty2 — просто команда, которая запускает приглашение для ввода логина и пароля на втором виртуальном терминале. Ее можно заменить чем угодно – хоть выделить отдельный терминал под Tetris! А respawn означает, что он будет перезапускаться каждый раз при завершении работы. С ней забавно поиграть, но будьте осторожны – если ненароком запустить программу, которая перехватит весь ввод с клавиатуры, вы не сможете переключиться на другой терминал, чтобы завершить ее. Но накладывать в штаны еще рано – просто перезагрузитесь в однопользовательский режим и отмените свои изменения.
Выключаем систему безопасно
В настольных операционных системах восьмидесятых специального процесса для выключения системы не было – после окончания работы вы просто нажимали кнопку выключения питания. Тогда это было нормально, но на современных компьютерах может быть весьма рискованным по двум причинам. Во-первых, в некоторых операционных системах, включая Linux, при сохранении файла данные не записываются на диск сразу. Они ждут, пока другие процессы не захотят сохранить данные, потом эти данные связываются вместе в одну большую операцию записи, что помогает повысить производительность. Впрочем, Linux можно заставить записать на диск все данные, хранящиеся в буферах оперативной памяти, командой sync.
Во-вторых, в Linux у скриптов запуска есть эквивалентные скрипты останова, которые гарантируют, что процессы завершаются безопасно, временные файлы удаляются и т. д. Не бойтесь, ничего страшного не случится, если они не будут запущены, но они помогают сохранить систему в чистоте. Большинство из нас останавливает систему с помощью виджетов на рабочем столе, но если вам удобнее делать это с командной строки, взгляните на man-страницы команд shutdown, halt и reboot. С командой shutdown, например, можно задать задержку, но самая распространенная команда для немедленного выключения компьютера – shutdown -h now.