Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Исследуем процесс загрузки Linux

(C) В.А.Костромин, 2007
(версия файла от 5.10.2007 г.)


Назад Оглавление Вперед

Этап 3: Загрузчик 2 этапа операционной системы

3.2. Файл /boot/initrd и его назначение

Как было сказано в предыдущем разделе, в процессе начальной загрузки вначале монтируется временный виртуальный диск, содержащий корневую файловую систему (очевидно, тоже временную), с помощью которой осуществляется запуск на выполнение ядра операционной системы. Образ этой корневой системы хранится на загрузочном устройстве в каталоге /boot и обычно носит имя initrd-2.x.yy-zzzz (точное наименование файла смотрите в вашей системе, далее он будет именоваться просто initrd). Загрузчик переносит образ корневой файловой системы из файла initrd в оперативную пямять одновременно с образом ядра, ядро преобразует initrd в "нормальный" RAM диск, монтирует временную корневую файловую систему, извлекает из нее нужные драйверы и другие служебные файлы, с помощью которых инициализирует все необходимые устройства. После этого происходит перемонтирование корневой файловой системы, временная ФС заменяется на постоянную, размещающуюся уже на долговременном носителе и процесс загрузки системы продолжается.

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

3.2.1. Внутреннее устройство initrd

Как сказано в статье [10] в дистрибутиве Fedora Core 3 (и его предшественниках) файл initrd создавался с использованием виртуального loop-устройства. В этом случае сделать содержимое файла initrd доступным для просмотра можно с помощью следующих команд (напомню, что имя вашего образа initrd может отличаться):

Листинг 2. Просматриваем initrd в варианте loop-устройства (до FC3)
 # mkdir temp ; cd temp
 # cp /boot/initrd.img.gz .
 # gunzip initrd.img.gz
 # mount -t ext -o loop initrd.img /mnt/initrd
 # ls -la /mnt/initrd
После этого вы можете посмотреть содержимое initrd в директории /mnt/initrd.
Заметьте что даже если имя вашего образа initrd не заканчивается на ".gz", это все равно сжатый файл и добавив к концу имени суффикс ".gz", вы сможете воспользоваться командой gunzip, чтобы его распаковать.

В таких дистрибутивах, как Fedora Core 4, SUSE 10, .... файл initrd представляет собой cpio-архив, сжатый упаковщиком gzip. Чтобы просмотреть его содержимое, надо выполнить команды, приведенные в листинге 3

Листинг 3. Просматриваем initrd в варианте cpio-архива (FC3 и позже)
mkdir ~/tmp
cd ~/tmp
cp /boot/initrd-2.6.16.13-4-default initrd-2.6.16.13-4-default.gz
gzip -d .gz
mv initrd-2.6.16.13-4-default initrd-2.6.16.13-4-default.cpio
cpio -i < initrd-2.6.16.13-4-default
После этого в каталоге ~/tmp вы найдете каталоговую структуру, аналогичную структуре каталогов обычной Linux-системы. В ней вы обнаружите обычные для корневого каталога подкаталоги, а также файл linuxrc. Могут там оказаться и другие файлы, например, файл bootsplash (судя по названию он содержит картинку, которая отображается при запуске).

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

3.2.2. Загрузка системы в случае использования initrd (ядра версий 2.4.х)

Приводимое ниже описание последовательности операций на этапе загрузки я позаимствовал из [11,12].

1. Загрузчик загружает ядро и содержимое initrd в память (очевидно, по вполне определенным адресам ???), после чего передает управление ядру.

2. Ядро содержит в себе небольшую несжатую часть, которая вначале разархивирует само ядро. Видимо как раз на этом этапе на экране монитора отображается сообщение "Uncompressing Linux... Ok, booting the kernel."

3. Ядро инициализирует устройства, создает файловую систему устройств /dev, разархивирует initrd и копирует его содержимое на устройство /dev/ram0, а затем освобождает память, занятую initrd.

4. Ядро монтирует устройство /dev/ram0 для чтения и записи в качестве начальной корневой файловой системы.

5. Если в начальной корневой файловой системе находится исполняемый файл /linuxrc, он исполняется с uid 0. Этот файл должен иметь разрешения на исполнение, он может быть как обычным исполняемым файлом, так и просто скриптом оболочки, но в последнем случае должен быть и интерпретатор скриптов.

6. Cкрипт /linuxrc монтирует нормальную корневую файловую систему.

7. Корневая файловая система помещается в корневую директорию. Смена корневого устройства выполняется системным вызовом pivot_root, который также доступен через утилиту pivot_root (см. pivot_root(8); pivot_root распространяется в составе util-linux версии не ниже 2.10h ). Смена корневой директории не включает её демонтирование. Следовательно, при выполнении данной процедуры можно сохранить процессы, запущенные с файловой системы initrd.

8. Если нормальная корневая файловая система имеет каталог /initrd, то устройство /dev/ram0 перемещается из / в /initrd. Иначе, если каталог /initrd не существует, устройство /dev/ram0 размонтируется.

9. На нормальной корневой файловой системе следует обычная процедура загрузки (например, вызов /sbin/init).

10. Теперь можно демонтировать /dev/ram0 и освободить память, занятую RAM диском.

3.2.3. Initramfs - новая модель инициализации (ядра версий 2.6.х)

Все сказанное выше относительно процедур загрузки и использования файла initrd справедливо для ядер версии 2.4.xx и более ранних. В ядрах версии 2.6 (а точнее, начиная с экспериментального ядра версии 2.5.46) разработчики решили реализовать иной механизм. Причиной послужили несколько недостатков ранее использовавшегося варианта реализации временной корневой файловой системы.

Во-первых, виртуальный диск, как и все блочные устройства, требует драйвер файловой системы для интерпретации данных во время выполнения. Этот драйвер приходилось включать в ядро.

Во-вторых, неэфективно используется оперативная память, так как размер виртуального диска фиксирован и не может изменяться во время работы без его переформатирования (даже если диск не заполнен, невозможно отдать эту память под другие нужды).

В третьих, в Linux осуществляется кэширование всех файлов и записей каталогов, прочитанных или записанных на блочное устройство. Виртуальный диск тоже кешируется, как и обычные диски, то есть часть данных будет храниться не только на RAM диске, но и в страничном кэше "page cache" (для файловых данных) и в кэше для записей каталогов "dentry cache", что еще больше снижает эффективность использования памяти.

Для устраненеия этих недостатков Линус Торвальдс предложил монтировать кэш ядра Линукс как особую файловую систему, работающую полностью в кэше ядра. При этом нет лишнего дублирования информации между блочным устройством и кэшем, так как блочного устройства попросту нет. Файловая система, реализующая эти идеи, была разработана и получила название initramfs. Ее использование имеет следующие преимущества:

  • Система, использующая initramfs в качестве корневой файловой системы, более не нуждается в соответствующем драйвере файловой системы, встроенном в ядро, так как нет блочных устройств для интерпретации файловых систем.
  • Размер этой файловой системы автоматически изменяется в соответствии с обьёмом данных, которые она содержит. При добавлении новых файлов (как и при расширении существующих) автоматически выделяется память, при удалении или уменьшении файла происходит высвобождение памяти.
  • Достоинством initramfs является также то, что это не новый код, а новое применение уже существующего кода кэширования ядра Линукс, что практически не влечёт увеличение размера ядра, выполнение будет очень простым и основано на чрезвычайно хорошо протестированной инфраструктуре.
  • Исчезают некоторые проблемы загрузки с SATA-дисков.
  • Initramfs загружается немного быстрее, чем initrd.

Формат initramfs используется по умолчанию для всех ядер, начиная с версии 2.6.15.

В каталоге /boot такая файловая система хранится, по-прежнему, в файле в виде сжатого cpio-архива. Только имя включаемого в этот архив скрипта изменилось с linuxrc на init. Например, в системе ASP Linux 11 после разархивирования файла initrd-2.6.14-1.1653.1asp.img по приведенному в листинге 3 алгоритму я увидел скрипт init и следующую структуру каталогов:

        /bin
        /dev
        /etc
        /lib
        /loopfs
        /proc
        /sbin -> bin
        /sys
        /sysroot

В подкаталоге /bin обнаружилось всего 4 исполняемых файла и две ссылки, в подкаталоге /dev - 8 файлов устройств, в /etc - конфигурационный файл udev/udev.conf, в каталоге lib - два файла: ext3.ko и jbd.ko. Остальные подкаталоги - пустые. Файл init оказался скриптом оболочки следующего вида:

Листинг 4. Содержимое файла init в дистрибутиве ASP Linux версии 11.

#!/bin/nash

mount -t proc /proc /proc
setquiet
echo Mounted /proc filesystem
echo Mounting sysfs
mount -t sysfs /sys /sys
echo Creating /dev
mount -o mode=0755 -t tmpfs /dev /dev
mknod /dev/console c 5 1
mknod /dev/null c 1 3
mknod /dev/zero c 1 5
mkdir /dev/pts
mkdir /dev/shm
echo Starting udev
/sbin/udevstart
echo -n "/sbin/hotplug" > /proc/sys/kernel/hotplug
echo "Loading jbd.ko module"
insmod /lib/jbd.ko 
echo "Loading ext3.ko module"
insmod /lib/ext3.ko 
/sbin/udevstart
echo Creating root device
mkrootdev /dev/root
echo Mounting root filesystem
mount -o defaults,errors=remount-ro --ro -t ext3 /dev/root /sysroot
echo Switching to new root
switchroot --movedev /sysroot
Обратите внимание на первую строку этого файла: это скрипт для оболочки nash, которая является сильно урезанной версией командного процессора и тоже включена в состав initramfs. Другие, более мощные оболочки на этом этапе еще недоступны.

Как видно из листинга 4, скрипт init монтирует файловые системы /sys и /dev, инициализирует несколько устройств, загружает модули из подкаталога /lib и монтирует корневую файловую систему. Сколько я ни вглядывался в экран при перезагрузках системы, я не увидел сообщений, которые вроде бы должны выдаваться командами echo, включенными в этот скрипт.

Образ виртуальной файловой системы initramfs хранится на диске по-прежнему в файле /boot/initrd-version и создается такой файл как и ранее командой mkinitrd. Прочитать о том, как создать такой файл, можно в статье [10]. Перечень модулей (иначе говоря, драйверов), которые будут включены в эту файловую систему, приведен в переменой INITRD_MODULES в файле /etc/sysconfig/kernel. Если вам требуется включить в /boot/initrd-version какие-то дополнительные модули (например, в случае изменения состава оборудования), вы можете скорректировать соответствующим образом список модулей в файле /etc/sysconfig/kernel, после чего заново создать файл /boot/initrd-version.


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


Назад Оглавление Вперед