Невозможно отучить людей изучать самые ненужные предметы.
Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3
Надо знать обо всем понемножку, но все о немногом.
Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы
Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)
Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода
Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5
Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости
Справочник от А до Я
HTML, CSS, JavaScript
Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы
Помогли мы вам |
Итак, для установки Bodhi Linux требуется 768 Мбайт оперативной памяти, объем которой можно уменьшить до 384 Мбайт на работающей системе, и при этом ей все еще можно будет пользоваться. Такая экономичность позволяет создать приличный пул виртуальных машин, например для моделирования сетевых конфигураций.
Если на виртуальной машине подкорректировать объем памяти можно за несколько секунд, то для установки Bodhi Linux на устаревший компьютер с 512 Мбайт ОЗУ придется вместо этого где‑то искать и устанавливать дополнительную планку памяти. Да и в конце концов, почему Bodhi Linux (и многие другие современные дистрибутивы) так прожорливы на этапе установки, хотя могут потом работать в гораздо более скромном окружении?!
Для ответа на этот вопрос надо посмотреть, как происходит загрузка Bodhi Linux с дистрибутивного носителя (на схеме ниже). Первым делом загрузчик операционной системы помещает с носителя в оперативную память ядро Linux /
с упакованным содержимым минимальной файловой системы (МФС) /
, формирует окружение ядра с параметрами командной строки и передает ядру управление. Ядро получает параметры из окружения и принимает их к сведению, определяет и инициализирует основное оборудование компьютера, после чего распаковывает МФС и запускает процесс init, текст сценария которого содержится в файле /
распакованной файловой системы.
Основная задача процесса init на данном этапе — отыскать на носителе образ основной файловой системы /
, переключиться на него с МФС и запустить свое продолжение. Для этого могут потребоваться модули ядра с драйверами устройства, которые обслуживают носитель с дистрибутивом и обеспечивают понимание его файловой системы. Эти драйверы, если они не встроены в ядро, должны быть доступны из МФС.
После переключения на основную файловую систему МФС больше не требуется, и занимаемая ей оперативная память освобождается. Файловая система squashfs позволяет работать с ней в режиме «только чтение» непосредственно из файла с образом. С этого момента оперативная память используется в основном для следующих целей:
На каком же этапе возникает проблема в последовательности этих шагов? Чтобы узнать это, загрузим Bodhi Linux в виртуальной машине с 512 Мбайт ОЗУ. И почти сразу после того, как мы в меню загрузки выберем Try Bodhi или Install Now, получим черный экран смерти со множеством диагностических сообщений. Несмотря на то что заключительный вердикт звучит как «Kernel panic - not syncing: No working init found» («Ядро остановлено — не синхронизировано: не найден рабочий init»), суть проблемы отражает самая первая строка: «Initramfs unpacking failed: write error» («Сбой при распаковке initramfs: ошибка записи»). Это значит, что ядро не смогло распаковать МФС из initrd.
из‑за нехватки оперативной памяти.
Почему же памяти не хватило? По большому счету на этом этапе в ОЗУ находятся ядро и заархивированная МФС. Во время загрузки ядро Linux активно выделяет, перемещает и освобождает области памяти. Если ты не разработчик ядра, уследить за всеми выполняемыми действиями довольно сложно. К счастью, когда ситуация стабилизируется, ядро формирует информационное сообщение и узнать «окончательный счет» можно с помощью команды
Ниже приведены результаты ее выполнения для диапазона оперативной памяти от 384 до 1024 Мбайт с шагом 128 Мбайт:
384 Мб: [ ]Memory:263248K/392760K available (14339K kernel code,2400K rwdata,5008K rodata,2732K init,4972K bss,129512K reserved,0K cma-reserved)
512 Мб: [ ]Memory:392272K/523832K available (14339K kernel code,2400K rwdata,5008K rodata,2732K init,4972K bss,131560K reserved,0K cma-reserved)
640 Мб: [ ]Memory:520528K/654904K available (14339K kernel code,2400K rwdata,5008K rodata,2732K init,4972K bss,134376K reserved,0K cma-reserved)
768 Мб: [ ]Memory:649552K/785976K available (14339K kernel code,2400K rwdata,5008K rodata,2732K init,4972K bss,136424K reserved,0K cma-reserved)
896 Мб: [ ]Memory:778576K/917048K available (14339K kernel code,2400K rwdata,5008K rodata,2732K init,4972K bss,138472K reserved,0K cma-reserved)
1024 Мб: [ ]Memory:907600K/1048120K available (14339K kernel code,2400K rwdata,5008K rodata,2732K init,4972K bss,140520K reserved,0K cma-reserved)
На основании этих сведений можно сделать вывод, что объем памяти, занимаемой процессом ядра с сегментами кода (kernel code), констант (rodata), изменяемых неинициализированных (rwdata) и инициализированных (bss) данных постоянно и составляет 29,451 Кбайт или примерно 29 Мбайт. Объем дополнительно резервируемой ядром памяти в некоторой степени зависит от общего объема оперативной памяти компьютера, но в основном определяется размером файла initrd.
. Можно сказать, что значение reserved равно сумме размера процесса ядра (29 Мбайт), файла initrd.
(87 Мбайт) и системных структур (10–20 Мбайт).
Чтобы получить журнал сообщений ядра при 384 Мбайт и 512 Мбайт ОЗУ, когда ядро не может распаковать МФС, перенаправь консоль в последовательный порт ttyS0, добавив параметры ядра в командной строке загрузчика:
console=ttyS0 console=tty0 ignore_loglevel
А сам порт перенаправляется в файл настройкой виртуальной машины VirtualBox, как показано на рисунке.
В остальных случаях, когда оперативной памяти достаточно для распаковки МФС, можно назначить прерывание процесса init после загрузки драйверов, достаточных для монтирования накопителей. Для этого к параметрам ядра надо добавить break=mount
. Когда появится командная строка BusyBox, можно вручную примонтировать к МФС основной накопитель и сохранить на него необходимые сведения.
Теперь мы можем посчитать, что объем свободной оперативной памяти на данном этапе составляет 512 – 128 = 384 Мбайт. Это довольно много, если учесть, что перед ядром стоит единственная задача распаковки МФС из сжатого алгоритмом LZ4 архива. Сейчас самое время вспомнить, что в распакованном виде эта файловая система занимает 242 Мбайт, и для ее хранения этот объем надо вычесть из имеющегося свободного пространства: 384 – 242 = 142 Мбайт. Но это все еще приличный запас.
Распаковкой и одновременно формированием МФС занимается конечный автомат, реализованный в модуле init/initramfs.c. Он по мере необходимости резервирует буферную память, которая освобождается полностью только после завершения его работы. Поэтому в описываемых условиях свободная оперативная память исчерпывается в момент формирования 384/2 = 192 Мбайт МФС из 242 Мбайт необходимых.
Что, если не архивировать cpio-блок с МФС? Идея парадоксальная, но тогда ядру не придется выделять память для распаковки и дистрибутив запустится на системах с 512 Мбайт ОЗУ. Естественно, у такого способа будут недостатки. Во‑первых, размер образа увеличится на 242 – 83 = 159 Мбайт. Из‑за этого может возрасти время загрузки, если носитель с образом не очень производительный, например DVD-ROM или флешка USB 2.0.
Но хуже всего то, что этот способ совершенно неработоспособен, потому что из‑за увеличения файла initrd.
объем свободной памяти сократится на 159 Мбайт, после чего вместо 384 Мбайт останется 225 Мбайт, в которые никак не сможет поместиться 242-мегабайтная МФС. А на самом деле оказывается, что перенос содержимого из cpio-блока в МФС тоже производится через буферную память, что вызывает аварийное прерывание процесса после обработки примерно 112 Мбайт. Поэтому надо искать другие пути.
Единственный объект, модификация которого может помочь сэкономить память на начальном этапе загрузки, — это МФС. Определить, какой объем занимают ее части, нетрудно — достаточно выполнить внутри интересующих каталогов команду
Она подсчитывает и наглядно показывает размеры подкаталогов в текущем каталоге. В результате получилась карта самых крупных объектов МФС.
Подавляющую долю МФС составляют бинарные файлы, предоставленные производителями устройств, и модули ядра с драйверами устройств. Хорошо бы узнать, из каких пакетов они появились:
$ dpkg-query -S /lib/firmware
wireless-regdb, linux-firmware, intel-microcode, amd64-microcode: /lib/firmware
$ dpkg-query -S /lib/modules
linux-modules-extra-5.4.0-72-generic, linux-modules-5.4.0-72-generic, linux-headers-5.4.0-72-generic: /lib/modules
Оказывается, источниками той массы файлов, из‑за которых «распухает» initrd.
, — это всего несколько пакетов. То есть сгруппировать их по выполняемым функциям и удалить лишние не выйдет. Оставим пока эту проблему и попробуем выяснить, все ли эти пакеты необходимы для начальной загрузки ОС. Для ответа на этот вопрос надо обратиться к сценарию /
, который находится в корне МФС и координирует все выполняемые на этом этапе действия.
Сначала этот сценарий инициализирует переменную окружения PATH
, чтобы обеспечить себе доступ к системным утилитам:
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
После этого он дополняет файловую систему каталогами, чтобы приблизить ее к Filesystem Hierarchy Standard. Некоторые каталоги монтируются специальным образом для отображения в них виртуальных файловых систем:
/dev
/root
/sys <--- mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
/proc <--- mount -t proc -o nodev,noexec,nosuid proc /proc
/tmp
/var/lock
/dev <--- mount -t devtmpfs -o noexec,nosuid,mode=0755 udev /dev
/dev/pts <--- mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts
Затем формируется среда окружения, в которой отметим переменную RUNSIZE
. Она определяет размер оперативной памяти, который будет зарезервирован для виртуальной файловой системы /
. Значение этой переменной извлекается из конфигурационного файла /
и по умолчанию составляет 10%.
После подключения подпрограмм из библиотеки /
запускается цикл разбора параметров, переданных ядру Linux из командной строки загрузчика:
case $x in
...
ИмяПараметра=*)ИМЯПАРАМЕТРА="${x#ИмяПараметра=}";;
...
initramfs.runsize=*)RUNSIZE="${x#initramfs.runsize=}";;
boot=*)BOOT=${x#boot=};;
break=*)break=${x#break=};;
break)break=premount
;;
...
esacdone
В основном он дополняет или изменяет переменные среды. Например, на значение переменной RUNSIZE
можно повлиять, указав параметр ядра initramfs.
. Переменная BOOT — индикатор способа загрузки ОС: local, nfs или casper. В дальнейшем она используется в команде вида . /scripts/${BOOT}
для подключения сценариев монтирования основной файловой системы.
|
|