Конспект лекции, прочтённой (в результате оплошности лектора) без слайдов
Что происходит после включения компьютера? Как туда попадает ОС? Ведь компьютер-=- это железка, выполняющая программы.И сразу так вот хоп — загрузить операционку на него нельзя. Более того, а как вообще в компьютер попадает самая первая программа?
BIOS, Basic Input-Output System, подсистема, распознающая устройства и немножко умеющая с ними работать.
Del
” нажимаешь, попадаешь в настройку, и там всё это есть в разделе «Boot».
Обычно размером один сектор, а то и меньше: на жёстком диске 512 байтов минус таблица разбиения.
Теперь мы не зависим (в пределах разумного от размера). Обычно хранится в специальном месте в начале раздела (предусмотрено ФС).
Если вторичный загрузчик не умеет загружать ядро этой ОС, он загрузит другой загрузчик, который умеет. Например, Windows и Linux, Linux-загрузчик умеет загружать ядро Linux, но не умеет систем неые файлы Windows, ну и ладно, зато у Windows есть собственный загрузчик, который умеет, и известно, где он лежит. Ну, и загрузим его, пускай разбирается.
В этом месте заканчивается досистемная загрузка. По-хорошему она вообще не зависит от ОС. Сражу скажу — в Linux не используется теоретически правильная трёхступенчатая последовательность загрузи по причине legacy, тяжёлого наследства длинного исторического процесса разработки IBM PC.
Разбиение жёсткого диска на разделы устроено нелогично по причине всё того же legacy.
Почему бы не взять диск, завести на нём одну ФС и хранить там файлы?
mount
всё это объединяется в одно дерево, а тип ФС можно подбирать разныйОтступление о swap. Зачем он? Когда все процессы вместе используют столько памяти, сколько в системе нет. Но ведь они её и не используют одновременно, большая часть памяти заказана, но не используется. Или уже один раз использовалась, а теперь — нет. Но выбросить её нельзя, в ней лежат нужные процессу данные. Поэтому эти неиспользованные куски памяти можно записатьо на диск, а когда в них возникнет нужда (процесс к нм обратится) — прочитать оттуда. Надо отличать swapping, когда процесс выгружается из памяти целиком, чтобы дать место другому процессу, и paging, когда выгружаются только неиспользуемые страницы памяти. Если система начала использовать swapping, надо срочно покупать память. Хранить swap в файле — значит, попусту использовать механизмы файловой системы и увеличивать паразитную нагрузку.
fdisk
они называются «logical»).Каждый раздел — это устройство в /dev/
, IDE-диски — “hd
”, SCSI — “sd
”, первый — “a
”, второй — “b
” и т. д. Если в компьютере один IDE-диск, он называется обычно /dev/hda
, а его разделы /dev/hda1
, /dev/hfa2
и т. п.
hda1
)hda2
)hda3
)hda5
)hda6
)Среди первичных разделов один может быть загрузочный.
Это разбиение характерно для IBM PC.
Две системы загрузки — LILO и GRUB. LILO — это LInux LOader. Первичный загрузчик — LI, вторичный — LO. Приметы: есть при загрузке вывелось только L — аппаратные проблемы, Li недозагрузилось, если LI — программные, LO не найден, если LIL — аппаратные или LO побился, если LILO — программные: не найдено или побилось ядро.
Загрузчики LI и LO — простые, они только умеют загружать некоторые последовательности секторов с диска. Каких секторов? Это определяется картой размещения.
LI (обычно записывается в MBR) умеет грузить просто несколько секторов с определённого места (обычно — в начале соотв раздела). Сколько и откуда? А прямо внутри LI это и впишем. Так что получается, что если мы меняем вторичный загрузчик, надо переписать и первичный, вдруг место или размер вторичного изменились.
LO должен загрузить ядро и стартовый виртуальный диск (a.k.a. initrd), передать ядру параметры. Или загрузить вторичный загрузчик. Где лежат ядро и initrd? А где-то в файловой системе, причём необязательно в секторах подряд. Значит, надо составить карту: список секторов, в которых они лежат. Вот эту карту и надо присобачить к LO, и делать это всякий раз, когда то, что надо грузить LILO, как-то меняется.
Обратная зависимость: чтобы установить Linux, надо загрузить весь Linux и запустить утилиту lilo
. Если вы изменили /etc/lilo.conf
, надо переписывать всё: карты размещения вторичного загрузчика, сам вторичный загрузчик, первичный загрузчик и его карты. Если вы этого не сделали, но обновили ядро, что может быть? Система продолжает загружаться по старой карте (сектора, где раньше лежало старое ядро), до тех пор, пока на это свободное место кто-нибудь что-нибудь не запишет. Потом начнёт грузиться это, и всё сломается.
Карта размещения, ядро и стартовый виртуальный диск лежать в /boot
.
Если несколько пунктов меню (несколько ядер, загрузка других ОС) — это всё надо подготовить заранее.
LILO (точнее, LO) — не настоящий вторичный загрузчик, скорее, полуторный: он не может подгружать модули ядра и не разбирается в файловых системах. Только сектора грузит в память. Например, для того, чтобы смонтировать файловую систему с жёсткого диска, необходим драйвер жёсткого диска, то есть модуль ядра. Но взять его с этого диска нельзя, потому что он и нужен для доступа к диску. И кто будет компоновать модуль с ядром? LO этого не умеет.
Можно собрать такое ядро, в котором есть все базовые драйверы, как в 90-х. Всякий раз надо пересобирать ядро? Это тяжело, не имея опыта.
Если LO умеет загрузить один файл в память, то несложно загрузить два. Первый — это ядро, а второй — это образ файловой системы в памяти (стартовый виртуальный диск), ядро его смонтирует, а там — модули, пара-тройка утилит (mount
и sh
, например), какие-то мелкие настройки и командный сценарий, который, все нужные действия делает.
Такой вот настоящий, большой вторичный загрузчик, возможности которого не ограничены, потом у что он Linux.
В конце концов initrd смонтирует корневую файловую систему, размонтирует себя (чтобы память не занимать) и запустит оттуда настоящий init
— папу всех процессов. Linux начинает работать.
Далеко не все модули лежат в initrd, например, звуковая карта, видео, всякие не нужные для загрузки автоматически определяемые устройства. Хотя можно всё напихать и в initrd, есть даже такой дистрибутив на базе Sisyphus: RAD Linux, он предназначен для маршрутизаторов и всяких сетевых устройств, загружается по сети или как-то ещё, и представляет собою один сплошной initrd, загружаемый в память, и работающий как есть.
Распознаванием устройства занимается служба udev
. Например, если ядро распознало устройство с некоторым идентификатором, но не знает, что это такое, оно посылает udevd
сообщение «вот, появилось какое-то устройство». Демон udevd
говорит «о, так это ж BlueTooth», и смотрит в специальную таблицу, где написано «модуль ядра подгрузить такой-то, создать такую-то файл-дырку в /dev
с такими-то правами» и ещё что-то, например, запуск каких-то программ. И то же самое при удалении устройства.
В старых книжках сказано, что распознаванием устр-в занимается ядро. Сейчас ядро только определяет идентификаторы, а логика работы передана программе.
Папа всех процессов управляется файлом /etc/inittab
— один из самых старых файлов в UNIX, поэтому его синтаксис хитрый. Файл небольшой, потому что он запускает командный сценарий rc
, а уже rc
запускает все службы.
Когда-то всё, что надо запускать в системе складывалось в один сценарий /etc/rc
. Но это неудобно, все службы в одном сценарии, поэтому при удалении и обновлении служб приходится редактировать этот очень длинный файл.
.d
”Это способ перейти от монолитного файла “имя
” ->
“имя.d/часть1
”, “имя.d/часть2
”,...
Например, настроечный файл web-сервера и модули, при добавлении модуля него настройки не вписываются с один файл, а кладутся рядом. Потом администратор эти настройки редактирует. И при удалении модуля вместо того, чтобы как-то искать, а где же эти настройки неузнаваемые, просто удаляется файл с дополнит. настройками.
Или правила для udevd
, если поддержка BlueTooth вообще установлена, появляются соотв. правила в /etc/udev/rules.d/80-bluetooth.rules
, которые она носит с собой. Нет поддержки BlueTooth в системе — нет файла.
Получается, что “имя.d/
” — это настроечный файл (или сценарий на sehll), распределённый по файлам каталога по принципу «одна сущность — один файл».
Схема “.d
” для старта и останова служб имеет дополнительный плюс — самостоятельный запуск файлов. Если сценарий старта был монолитный, то отдельную службу остановить или перезапустить модно было бы только руками. А если попилить по принципу «одна служба — один сценарий», можно сделать такой сценарий старт-стопным. То есть оформить как программу на shell, принимающую стандартные параметры start
и stop
, что означает «запустить службу» и «остановить службу» (при этом параметры самих демонов могут быть какими угодно).
Так что при старте системы запускается последовательность файлов из /etc/init.d
с параметром start
, а при останове — stop
.
Есть несколько т. н. уровней выполнения, то есть профилей запуска системы, изменение состояния системы трактуется как переход с уровня на уровень. Переход на уровень 0 — это выключение системы, на уровень 6 — перезагрузка, а остальные — это профили запуска. 1 — однопользовательский вариант, запускается только shell, 2 — многопользовательский без сети (shell плюс несетевые службы), 3 — многопользовательский с сетью (то же плюс сетевые службы) и 5 — то же плюс графическая оболочка (4 и 7 можно использовать по своему усмотрению).
Фактически, переход с уровня на уровень просто меняет список служб, которые запущены и остановлены, и просто надо некоторые старт-стопные сценарии запустить с параметром start
, а некоторые — с параметром stop
.
Какие и в каком порядке сценарии запускаются при переходе на уровень, скажем, 5? Все эти сценарии лежат в каталоге /etc/rc/rc5.d/
, и называются так: сначала “D
” или “K
”, потом — двузначный номер, потом имя; причём все они — символьный ссылки на настоящие сценарии в init.d
. Старая добрая “.d
” схема.
На букву “K
” (Kill) начинаются файлы, которые надо запустить с параметром stop
, а на букву “S
” (Start) — которые надо запустить с параметром start
. А цифры нужны для упорядочивания, т. к. сценарии запускаются в лексикографическом порядке, сначала с меньшими числами, затем — с большими.
Итого, при старте системы выполняются старт-стопные сценарии с параметром start
просто подряд.
В конце концов init
запускает утилиту mingetty
для всех консолей. Mingetty проверяет, есть ли человек за клавиатурой или нет. Если человек есть (то есть он начал нажимать какие-то кнопки), то mingetty
запускает login
, пользователь вводит идентификационную информацию, пароль — система готова к работе.
Многосистемный компьютер:
/etc/lilo.conf
надо просто указывать other=/dev/раздел_с_windows
)./etc/lilo.conf
и заново запустить lilo
. (Наверное, стоит нарисовать такой сценарий, который это сам делает в LiveCD).Запись на NTFS: ntfs3g
и captive