Содержание статьи
В предыдущих статьях «диетологии» — «Linux на диете» и «Новая диета для Linux» — мы поработали над снижением требований к оперативной памяти Bodhi Linux и достигли в этом определенных успехов. Но круг поклонников Bodhi не так велик. Поэтому давай посмотрим, каков аппетит у гораздо более близкого сердцу хакера Arch Linux.
Как ты знаешь, Arch Linux загружается в текстовую консоль, после чего дает пользователю полнейшую свободу действий. Наверное, 512 Мбайт ОЗУ для такой среды будет более чем достаточно? Давай проверим.
Итак, выставляем в свойствах виртуальной машины объем оперативной памяти 512 Мбайт, загружаем образ archlinux-2024.06.01-x86_64.iso, подключаем, запускаем, получаем...
Loading /arch/boot/x86_64/vmlinuz-linux... ok
Loading /arch/boot/x86_64/initramfs-linux.img...ok
[ ] Initramfs unpacking failed: write errormount: error while loading shared libraries: libmount.so.1: cannot open shared object file: No such file or directory
...
ERROR: Failed to mount '' on real root
You are now being dropped into an emergency shell.
sh: can't access tty; job control turned off
[rootfs ~]# _«Ага‑а-а!» — сказали бы тут угрюмые русские мужики, валившие в далеком сибирском лесу вековые кедры двуручными пилами. И здесь нас встретила старая добрая ошибка: Initramfs
. Правда, вместо kernel panic мы получили аварийную командную строку, но она не работает. Как понятно из последнего сообщения, оболочка sh
не смогла связаться с терминалом tty
.
Похоже, нам есть чем заняться! Приступим. В качестве рабочей операционной системы я по привычке воспользовался Bodhi Linux 6.0, что в итоге привело к... Но обо всем по порядку.
Измеряем и разбираем
Для начала еще раз попытаемся запустить Arch Linux, указав в параметрах ядра опцию debug
, чтобы отладочные события шли в последовательный порт, который у виртуальной машины можно привязать к файлу. Больше всего нас сейчас интересует распределение оперативной памяти.
...
[ ] Initramfs unpacking failed: write error [ ] Freeing initrd memory: 143796KИз сообщения видно, что после загрузки ядра с упакованным образом минимальной файловой системы (МФС) и резервирования служебных областей для работы осталось 320 340 Кбайт оперативной памяти. Не то чтобы совсем уж мало, но с учетом упакованного размера образа МФС в 143 796 Кбайт исчерпание памяти не выглядит чем‑то удивительным.
Для дальнейшей работы с содержимым дистрибутивного образа удобно извлечь его в отдельный каталог isofs
. Если он примонтирован в точке /
, это можно сделать командой
cp -R /media/ARCH_202406/. ./isofs
Теперь посмотрим, что собой представляет упакованный образ МФС, который находится в файле isofs/
.
$ initrd=isofs/arch/boot/x86_64/initramfs-linux.img
$ dd if=$initrd bs=512 | file -z -
/dev/stdin: ASCII cpio archive (SVR4 with no CRC)
Понятно, сначала идет неупакованный архив CPIO. Распакуем‑ка его в каталог initrd_1
и посмотрим, что в нем.
$ mkdir initramfs_1
$ dd if=$initrd bs=512 | cpio -iD initramfs_1
260261 blocks
Оказывается, он содержит микрокод процессоров AMD и Intel в каталоге kernel
, а также модули ядра и двоичные файлы устройств в каталогах usr/
и usr/
соответственно. Причем, судя по суффиксам .
, большинство файлов уже сжаты алгоритмом ZSTD, что существенно снижает наши возможности оптимизации. Давай посмотрим, какой объем занимают файлы этого блока МФС.
$ du -sh initramfs_1/{kernel,usr/lib/*}
13M initramfs_1/kernel
69M initramfs_1/usr/lib/firmware
53M initramfs_1/usr/lib/modules
Хорошо, теперь глянем, что еще есть в образе МФС.
$ dd if=$initrd bs=512 skip=260261 | file -z -
/dev/stdin: data
А это что за новость?! Какая еще data
? Надо разобраться:
$ dd if=$initrd bs=512 skip=260261 count=1 | hexdump -C
1+0 records in
1+0 records out
512 bytes copied
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
Нули?! Видимо, сборщики образа МФС решили выровнять начала блоков. Это, конечно, хорошо, но где же начинается следующий блок?
$ cmp $initrd /dev/zero $((512*260261))
isofs/arch/boot/x86_64/initramfs-linux.img /dev/zero differ: byte 9729, line 1
Понятно, теперь мы можем снова попытаться определить тип следующего блока:
$ dd iflag=skip_bytes if=$initrd bs=512 skip=$((512*260261+9728)) | file -z -
/dev/stdin: ASCII cpio archive (SVR4 with no CRC) (XZ compressed data)
Ага, второй блок представляет собой архив CPIO, сжатый алгоритмом XZ. Распакуем и посмотрим, что в нем:
$ mkdir initramfs_2
$ dd iflag=skip_bytes if=$initrd bs=512 skip=$((512*260261+9728)) | unxz | cpio -iD initramfs_2
27309+1 records in
27309+1 records out
13982236 bytes (14 MB, 13 MiB) copied
86167 blocks
А в нем, как нетрудно догадаться, оставшаяся часть МФС: утилиты и библиотечные модули, файлы с настройками и сценарий init
, запускаемый ядром после инициализации. Занимает все это в распакованном виде 43 Мбайт.
$ du -sh initramfs_2
43M initramfs_2
И что теперь с этим делать?
Итак, образ МФС мы распаковали. Теперь надо решить, что с ним делать дальше. Фокус с применением алгоритмов сжатия тут не пройдет, потому что всё уже сжали до нас. Можно было бы удалить некоторые ненужные драйверы, но не хотелось бы нарушать задумку создателей дистрибутива. Раз они поместили драйверы видеоадаптеров в МФС, значит, они тут нужны... Или нет?
Погоди‑ка, а что там у нас было во время самой первой попытки загрузить Arch Linux на 512 Мбайт? Неработающая консоль? А откуда взялась консоль, если при распаковке МФС произошла ошибка? Получается, что ошибку распаковки МФС ядро не считает критической, столкнувшись с такой ситуацией, оно не паникует, а пытается работать дальше как ни в чем не бывало. Вот как выглядит журнал загрузки с включенными отладочными сообщениями:
...
[ ] Initramfs unpacking failed: write error...
[ ] Run /init as init process...
mount: error while loading shared libraries: libmount.so.1: cannot open shared object file: No such file or directory
...
/init: line 16: can't open /proc/cmdline: no such file
:: mounting '' on real root
mount: error while loading shared libraries: libmount.so.1: cannot open shared object file: No such file or directory
ERROR: Failed to mount '' on real root
You are now being dropped into an emergency shell.
sh: can't access tty; job control turned off
[rootfs ~]# _Получается, из‑за того, что файл библиотеки libmount.
не попал в ту часть МФС, которая успела распаковаться, сценарий init
не смог примонтировать виртуальные файловые системы, включая /
, потом не смог обработать параметры ядра /
, и пошло‑поехало. Как в стихотворении Маршака: «Враг вступает в город, пленных не щадя, оттого, что в кузнице не было гвоздя».
Если бы все необходимое для работы сценария init
и переключения на полноценную корневую файловую систему распаковалось, а драйверы видеоадаптера — нет, то мы этой последней неприятности, возможно, даже и не заметили бы?
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»