В этой статье мы испра­вим дис­три­бутив Arch Linux 2024.06 так, что­бы его мож­но было исполь­зовать на компь­юте­рах с малым объ­емом опе­ратив­ной памяти. А в ходе работы поз­накомим­ся с эле­мен­тами струк­туры фай­ловой сис­темы ISO 9660 и научим­ся исполь­зовать штат­ные инс­тру­мен­ты для решения око­лоха­кер­ских задач.

В пре­дыду­щих стать­ях «дието­логии» — «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 error

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 ~]# _

«Ага‑а-а!» — ска­зали бы тут угрю­мые рус­ские мужики, валив­шие в далеком сибир­ском лесу вековые кед­ры дву­руч­ными пилами. И здесь нас встре­тила ста­рая доб­рая ошиб­ка: Initramfs unpacking failed: write error. Прав­да, вмес­то kernel panic мы получи­ли ава­рий­ную коман­дную стро­ку, но она не работа­ет. Как понят­но из пос­ледне­го сооб­щения, обо­лоч­ка sh не смог­ла свя­зать­ся с тер­миналом tty.

По­хоже, нам есть чем занять­ся! Прис­тупим. В качес­тве рабочей опе­раци­онной сис­темы я по при­выч­ке вос­поль­зовал­ся Bodhi Linux 6.0, что в ито­ге при­вело к... Но обо всем по поряд­ку.

 

Измеряем и разбираем

Для начала еще раз попыта­емся запус­тить Arch Linux, ука­зав в парамет­рах ядра опцию debug console=ttyS0, что­бы отла­доч­ные события шли в пос­ледова­тель­ный порт, который у вир­туаль­ной машины мож­но при­вязать к фай­лу. Боль­ше все­го нас сей­час инте­ресу­ет рас­пре­деле­ние опе­ратив­ной памяти.

[ ] Memory: 320340K/523832K available (18432K kernel code, 2164K rwdata, 13224K rodata, 3412K init, 3624K bss, 203232K reserved, 0K cma-reserved)

...

[ ] Initramfs unpacking failed: write error [ ] Freeing initrd memory: 143796K

Из сооб­щения вид­но, что пос­ле заг­рузки ядра с упа­кован­ным обра­зом минималь­ной фай­ловой сис­темы (МФС) и резер­вирова­ния слу­жеб­ных областей для работы оста­лось 320 340 Кбайт опе­ратив­ной памяти. Не то что­бы сов­сем уж мало, но с уче­том упа­кован­ного раз­мера обра­за МФС в 143 796 Кбайт исчерпа­ние памяти не выг­лядит чем‑то уди­витель­ным.

Для даль­нейшей работы с содер­жимым дис­три­бутив­ного обра­за удоб­но извлечь его в отдель­ный каталог isofs. Если он при­мон­тирован в точ­ке /media/ARCH_202406, это мож­но сде­лать коман­дой

cp -R /media/ARCH_202406/. ./isofs
Творческий порядок в рабочем каталоге
Твор­ческий порядок в рабочем катало­ге

Те­перь пос­мотрим, что собой пред­став­ляет упа­кован­ный образ МФС, который находит­ся в фай­ле isofs/arch/boot/x86_64/initramfs-linux.img.

$ 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/lib/modules и usr/lib/firmware соот­ветс­твен­но. При­чем, судя по суф­фиксам .zst, боль­шинс­тво фай­лов уже сжа­ты алго­рит­мом 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.so.1 не попал в ту часть МФС, которая успе­ла рас­паковать­ся, сце­нарий init не смог при­мон­тировать вир­туаль­ные фай­ловые сис­темы, вклю­чая /proc, потом не смог обра­ботать парамет­ры ядра /proc/cmdline, и пош­ло‑поеха­ло. Как в сти­хот­ворении Мар­шака: «Враг всту­пает в город, плен­ных не щадя, отто­го, что в куз­нице не было гвоз­дя».

Ес­ли бы все необ­ходимое для работы сце­нария init и перек­лючения на пол­ноцен­ную кор­невую фай­ловую сис­тему рас­пакова­лось, а драй­веры виде­оадап­тера — нет, то мы этой пос­ледней неп­рият­ности, воз­можно, даже и не замети­ли бы?

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии